aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTravis Geiselbrecht <travisg@gmail.com>2023-06-21 15:42:35 -0700
committerGitHub <noreply@github.com>2023-06-21 15:42:35 -0700
commit30dc320054f70910e1c1ee40a6948ee99672acec (patch)
treefb47ab6337a71029dee71933e449cf7f6805fc0f
parent9325ca7f3b3025aafe61898d27f1c02b99426b82 (diff)
parent3b215c398e582765ea33331369250ace997dcf98 (diff)
downloadlk-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.yml70
-rw-r--r--arch/riscv/include/arch/riscv.h20
-rw-r--r--arch/x86/32/exceptions.S9
-rw-r--r--arch/x86/64/exceptions.S8
-rw-r--r--arch/x86/64/start.S4
-rw-r--r--engine.mk32
-rw-r--r--external/platform/pico/rp2_common/pico_platform/include/pico/platform.h1
-rw-r--r--platform/rp20xx/include/sys/cdefs.h6
-rw-r--r--top/include/lk/compiler.h3
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
diff --git a/engine.mk b/engine.mk
index 3a92d672..e56d1b23 100644
--- a/engine.mk
+++ b/engine.mk
@@ -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__