Skip to content

Commit

Permalink
[github] Merge pull request #380 from arichardson/add-clang-ci
Browse files Browse the repository at this point in the history
Allow building RISCV64 and x86_64 with clang and add a Clang CI job
  • Loading branch information
travisg committed Jun 21, 2023
2 parents 9325ca7 + 3b215c3 commit 30dc320
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 27 deletions.
70 changes: 70 additions & 0 deletions .github/workflows/github-ci-clang.yml
Original file line number Diff line number Diff line change
@@ -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
20 changes: 11 additions & 9 deletions arch/riscv/include/arch/riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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))
Expand Down
9 changes: 4 additions & 5 deletions arch/x86/32/exceptions.S
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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

Expand Down
8 changes: 4 additions & 4 deletions arch/x86/64/exceptions.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down
4 changes: 2 additions & 2 deletions arch/x86/64/start.S
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ real_start:
/* far jump to load the CS from our GDT */
pushl $CODE_SELECTOR
pushl $PHYS(.Lfarjump)
retf
lret

.Lfarjump:

Expand Down Expand Up @@ -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
Expand Down
32 changes: 32 additions & 0 deletions engine.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
6 changes: 0 additions & 6 deletions platform/rp20xx/include/sys/cdefs.h

This file was deleted.

3 changes: 3 additions & 0 deletions top/include/lk/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@

#pragma once

#define __CONCAT1(x, y) x ## y
#define __CONCAT(x, y) __CONCAT1(x, y)

#ifndef __ASSEMBLY__

#if __GNUC__ || __clang__
Expand Down

0 comments on commit 30dc320

Please sign in to comment.