diff options
author | Travis Geiselbrecht <travisg@gmail.com> | 2023-06-21 15:42:35 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-21 15:42:35 -0700 |
commit | 30dc320054f70910e1c1ee40a6948ee99672acec (patch) | |
tree | fb47ab6337a71029dee71933e449cf7f6805fc0f | |
parent | 9325ca7f3b3025aafe61898d27f1c02b99426b82 (diff) | |
parent | 3b215c398e582765ea33331369250ace997dcf98 (diff) | |
download | lk-30dc320054f70910e1c1ee40a6948ee99672acec.tar.gz |
[github] Merge pull request #380 from arichardson/add-clang-ci
Allow building RISCV64 and x86_64 with clang and add a Clang CI job
-rw-r--r-- | .github/workflows/github-ci-clang.yml | 70 | ||||
-rw-r--r-- | arch/riscv/include/arch/riscv.h | 20 | ||||
-rw-r--r-- | arch/x86/32/exceptions.S | 9 | ||||
-rw-r--r-- | arch/x86/64/exceptions.S | 8 | ||||
-rw-r--r-- | arch/x86/64/start.S | 4 | ||||
-rw-r--r-- | engine.mk | 32 | ||||
-rw-r--r-- | external/platform/pico/rp2_common/pico_platform/include/pico/platform.h | 1 | ||||
-rw-r--r-- | platform/rp20xx/include/sys/cdefs.h | 6 | ||||
-rw-r--r-- | top/include/lk/compiler.h | 3 |
9 files changed, 126 insertions, 27 deletions
diff --git a/.github/workflows/github-ci-clang.yml b/.github/workflows/github-ci-clang.yml new file mode 100644 index 00000000..19dc5612 --- /dev/null +++ b/.github/workflows/github-ci-clang.yml @@ -0,0 +1,70 @@ +name: LK CI (Clang) + +# Brute force build a bunch of variants of LK in parallel jobs. + +on: [ push, pull_request ] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + toolchain-ver: [13, 14, 15] + debug: [2] + project: + # Note: Clang toolchains do not ship with a compiler-rt (libgcc) for + # all targets, so we have to restrict this build matrix to targets + # that build without requiring these functions (i.e. 64-bit targets, + # since 32-bit ones require functions such as __divdi3). + - pc-x86-64-test + - qemu-virt-arm64-test + - qemu-virt-riscv64-test + - qemu-virt-riscv64-supervisor-test + env: + PROJECT: ${{ matrix.project }} + TOOLCHAIN_VER: ${{ matrix.toolchain-ver }} + DEBUG: ${{ matrix.debug }} + UBSAN: 0 # UBSan runtimes for baremetal are not part of the toolchain + steps: + - name: banner + shell: bash + run: | + printf "Building with %d processors\n" "$(nproc)" + grep -oP '(?<=model name\t: ).*' /proc/cpuinfo|head -n1 + echo PROJECT = $PROJECT + echo TOOLCHAIN_VER = $TOOLCHAIN_VER + echo DEBUG = $DEBUG + echo UBSAN = $UBSAN + + - name: checkout + uses: actions/checkout@v3 + + # Install LLVM and set up the required environment variables + - name: compute toolchain + shell: bash + run: | + sudo apt install clang-${{ matrix.toolchain-ver }} lld-${{ matrix.toolchain-ver }} + GCC_TOOLCHAIN_PREFIX=$(make list-toolchain | grep TOOLCHAIN_PREFIX | tail -1 | cut -d ' ' -f 3) + # Map the GCC toolchain prefix to a clang --target argument: + CLANG_TRIPLE=$(echo "${GCC_TOOLCHAIN_PREFIX}" | sed 's/-elf-/-unknown-elf/g') + LLVM_BINDIR=/usr/lib/llvm-${{ matrix.toolchain-ver }}/bin + echo "CC=${LLVM_BINDIR}/clang --target=${CLANG_TRIPLE}" >> $GITHUB_ENV + echo "LD=${LLVM_BINDIR}/ld.lld" >> $GITHUB_ENV + echo "OBJDUMP=${LLVM_BINDIR}/llvm-objdump" >> $GITHUB_ENV + echo "OBJCOPY=${LLVM_BINDIR}/llvm-objcopy" >> $GITHUB_ENV + echo "CPPFILT=${LLVM_BINDIR}/llvm-cxxfilt" >> $GITHUB_ENV + echo "SIZE=${LLVM_BINDIR}/llvm-size" >> $GITHUB_ENV + echo "NM=${LLVM_BINDIR}/llvm-nm" >> $GITHUB_ENV + echo "STRIP=${LLVM_BINDIR}/llvm-strip" >> $GITHUB_ENV + echo "TOOLCHAIN_PREFIX=/invalid/prefix/should/not/be/used" >> $GITHUB_ENV + echo "LIBGCC=" >> $GITHUB_ENV + cat "$GITHUB_ENV" + + # build it + - name: build + shell: bash + run: | + make -j $(nproc) + +# vim: ts=2 sw=2 expandtab diff --git a/arch/riscv/include/arch/riscv.h b/arch/riscv/include/arch/riscv.h index 340284d4..ac265f0d 100644 --- a/arch/riscv/include/arch/riscv.h +++ b/arch/riscv/include/arch/riscv.h @@ -19,9 +19,11 @@ #if RISCV_M_MODE # define RISCV_XMODE_OFFSET (RISCV_MACH_OFFSET) # define RISCV_XRET mret +# define RISCV_MODE_PREFIX m #elif RISCV_S_MODE # define RISCV_XMODE_OFFSET (RISCV_SUPER_OFFSET) # define RISCV_XRET sret +# define RISCV_MODE_PREFIX s #else # error Unrecognized RISC-V privilege level selected #endif @@ -36,14 +38,14 @@ #define RISCV_CSR_TIMEH (0xc81) #define RISCV_CSR_INSRETH (0xc82) -#define RISCV_CSR_XSTATUS (0x000 | RISCV_CSR_XMODE_BITS) -#define RISCV_CSR_XIE (0x004 | RISCV_CSR_XMODE_BITS) -#define RISCV_CSR_XTVEC (0x005 | RISCV_CSR_XMODE_BITS) -#define RISCV_CSR_XSCRATCH (0x040 | RISCV_CSR_XMODE_BITS) -#define RISCV_CSR_XEPC (0x041 | RISCV_CSR_XMODE_BITS) -#define RISCV_CSR_XCAUSE (0x042 | RISCV_CSR_XMODE_BITS) -#define RISCV_CSR_XTVAL (0x043 | RISCV_CSR_XMODE_BITS) -#define RISCV_CSR_XIP (0x044 | RISCV_CSR_XMODE_BITS) +#define RISCV_CSR_XSTATUS __CONCAT(RISCV_MODE_PREFIX, status) +#define RISCV_CSR_XIE __CONCAT(RISCV_MODE_PREFIX, ie) +#define RISCV_CSR_XTVEC __CONCAT(RISCV_MODE_PREFIX, tvec) +#define RISCV_CSR_XSCRATCH __CONCAT(RISCV_MODE_PREFIX, scratch) +#define RISCV_CSR_XEPC __CONCAT(RISCV_MODE_PREFIX, epc) +#define RISCV_CSR_XCAUSE __CONCAT(RISCV_MODE_PREFIX, cause) +#define RISCV_CSR_XTVAL __CONCAT(RISCV_MODE_PREFIX, tval) +#define RISCV_CSR_XIP __CONCAT(RISCV_MODE_PREFIX, ip) #if RISCV_M_MODE // Machine-mode only CSRs #define RISCV_CSR_MCYCLE (0xb00) @@ -55,7 +57,7 @@ #endif // RISCV_M_MODE #if RISCV_S_MODE // Supervisor-mode only CSRs -#define RISCV_CSR_SATP (0x180) +#define RISCV_CSR_SATP satp #endif #define RISCV_CSR_XSTATUS_IE (1ul << (RISCV_XMODE_OFFSET + 0)) diff --git a/arch/x86/32/exceptions.S b/arch/x86/32/exceptions.S index 8ca8771b..98ac81f1 100644 --- a/arch/x86/32/exceptions.S +++ b/arch/x86/32/exceptions.S @@ -21,8 +21,7 @@ _isr: .set i, 0 .rept NUM_INT -.set isr_stub_start, . - +100: /* unnamed label for start of isr stub */ .if i == 8 || (i >= 10 && i <= 14) || i == 17 nop /* error code pushed by exception */ nop /* 2 nops are the same length as push byte */ @@ -34,12 +33,12 @@ _isr: jmp interrupt_common .endif -/* figure out the length of a single isr stub (usually 6 or 9 bytes) */ -.set isr_stub_len, . - isr_stub_start - .set i, i + 1 .endr +/* figure out the length of a single isr stub (usually 6 or 9 bytes) */ +.set isr_stub_len, . - 100b + /* annoying, but force AS to use the same (longer) encoding of jmp for all of the stubs */ .fill 256 diff --git a/arch/x86/64/exceptions.S b/arch/x86/64/exceptions.S index e66c53ce..86a54827 100644 --- a/arch/x86/64/exceptions.S +++ b/arch/x86/64/exceptions.S @@ -26,7 +26,7 @@ _isr: .set i, 0 .rept NUM_INT -.set isr_stub_start, . +100: /* unnamed label for start of isr stub */ .if i == 8 || (i >= 10 && i <= 14) || i == 17 .align 16 @@ -43,12 +43,12 @@ _isr: .align 16 .endif -/* figure out the length of a single isr stub (usually 6 or 9 bytes) */ -.set isr_stub_len, . - isr_stub_start - .set i, i + 1 .endr +/* figure out the length of a single isr stub (usually 6 or 9 bytes) */ +.set isr_stub_len, . - 100b + /* annoying, but force AS to use the same (longer) encoding of jmp for all of the stubs */ .fill 256 diff --git a/arch/x86/64/start.S b/arch/x86/64/start.S index b11e8bca..7637525a 100644 --- a/arch/x86/64/start.S +++ b/arch/x86/64/start.S @@ -74,7 +74,7 @@ real_start: /* far jump to load the CS from our GDT */ pushl $CODE_SELECTOR pushl $PHYS(.Lfarjump) - retf + lret .Lfarjump: @@ -185,7 +185,7 @@ paging_setup: /* Use a far jump to get into 64bit mode */ pushl $CODE_64_SELECTOR pushl $PHYS(farjump64) - retf + lret .align 8 .code64 @@ -66,6 +66,9 @@ GLOBAL_COMPILEFLAGS := -g -include $(CONFIGHEADER) GLOBAL_COMPILEFLAGS += -Wextra -Wall -Werror=return-type -Wshadow -Wdouble-promotion GLOBAL_COMPILEFLAGS += -Wno-multichar -Wno-unused-parameter -Wno-unused-function -Wno-unused-label GLOBAL_COMPILEFLAGS += -fno-common +# Build with -ffreestanding since we are building an OS kernel and cannot +# rely on all hosted environment functionality being present. +GLOBAL_COMPILEFLAGS += -ffreestanding GLOBAL_CFLAGS := --std=gnu11 -Werror-implicit-function-declaration -Wstrict-prototypes -Wwrite-strings GLOBAL_CPPFLAGS := --std=c++14 -fno-exceptions -fno-rtti -fno-threadsafe-statics GLOBAL_ASMFLAGS := -DASSEMBLY @@ -192,6 +195,15 @@ SIZE ?= $(TOOLCHAIN_PREFIX)size NM ?= $(TOOLCHAIN_PREFIX)nm STRIP ?= $(TOOLCHAIN_PREFIX)strip +# Detect whether we are using ld.lld. If we don't detect ld.lld, we assume +# it's ld.bfd. This check can be refined in the future if we need to handle +# more cases (e.g. ld.gold). +LINKER_TYPE := $(shell $(LD) -v 2>&1 | grep -q "LLD" && echo lld || echo bfd) +$(info LINKER_TYPE=$(LINKER_TYPE)) +# Detect whether we are compiling with GCC or Clang +COMPILER_TYPE := $(shell $(CC) -v 2>&1 | grep -q "clang version" && echo clang || echo gcc) +$(info COMPILER_TYPE=$(COMPILER_TYPE)) + # Now that CC is defined we can check if warning flags are supported and add # them to GLOBAL_COMPILEFLAGS if they are. ifeq ($(call is_warning_flag_supported,-Wnonnull-compare),yes) @@ -207,6 +219,26 @@ ARCH_COMPILEFLAGS += -Wno-asm-operand-widths endif endif +ifeq ($(ARCH),riscv) +# ld.lld does not support linker relaxations yet. +# TODO: This is no longer true as of LLVM 15, so should add a version check +ifeq ($(LINKER_TYPE),lld) +ARCH_COMPILEFLAGS += -mno-relax +# Work around out-of-range undef-weak relocations when building with clang and +# linking with ld.lld. This is not a problem with ld.bfd since ld.bfd rewrites +# the instructions to avoid the out-of-range PC-relative relocation +# See https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/126 for more +# details. For now, the simplest workaround is to build with -fpie when using +# a version of clang that does not include https://reviews.llvm.org/D107280. +# TODO: Add a clang 17 version check now that the review has been merged. +ifeq ($(COMPILER_TYPE),clang) +# We also add the -fdirect-access-external-data flag is added to avoid the +# majority of the performance overhead caused by -fPIE. +ARCH_COMPILEFLAGS += -fPIE -fdirect-access-external-data +endif +endif +endif + $(info PROJECT = $(PROJECT)) $(info PLATFORM = $(PLATFORM)) $(info TARGET = $(TARGET)) diff --git a/external/platform/pico/rp2_common/pico_platform/include/pico/platform.h b/external/platform/pico/rp2_common/pico_platform/include/pico/platform.h index 2ed5e212..d0771e1e 100644 --- a/external/platform/pico/rp2_common/pico_platform/include/pico/platform.h +++ b/external/platform/pico/rp2_common/pico_platform/include/pico/platform.h @@ -7,7 +7,6 @@ #ifndef _PICO_PLATFORM_H_ #define _PICO_PLATFORM_H_ -#include <sys/cdefs.h> #include "pico/types.h" #include "hardware/platform_defs.h" diff --git a/platform/rp20xx/include/sys/cdefs.h b/platform/rp20xx/include/sys/cdefs.h deleted file mode 100644 index 9fc7e4f4..00000000 --- a/platform/rp20xx/include/sys/cdefs.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#ifndef __CONCAT -#define __CONCAT1(x,y) x ## y -#define __CONCAT(x,y) __CONCAT1(x,y) -#endif diff --git a/top/include/lk/compiler.h b/top/include/lk/compiler.h index 45b1dc81..04236826 100644 --- a/top/include/lk/compiler.h +++ b/top/include/lk/compiler.h @@ -11,6 +11,9 @@ #pragma once +#define __CONCAT1(x, y) x ## y +#define __CONCAT(x, y) __CONCAT1(x, y) + #ifndef __ASSEMBLY__ #if __GNUC__ || __clang__ |