diff --git a/config/registration.bzl b/config/registration.bzl index 51f49c6..1c8c157 100644 --- a/config/registration.bzl +++ b/config/registration.bzl @@ -4,6 +4,7 @@ load("@crt//toolchains/gcc_arm_none_eabi:repository.bzl", "gcc_arm_none_eabi_repos") load("@crt//toolchains/lowrisc_rv32imcb:repository.bzl", "lowrisc_rv32imcb_repos") +load("@crt//toolchains/cheri_llvm:repository.bzl", "cheri_llvm_repos") load("@crt//toolchains/gcc_mxe_mingw64:repository.bzl", "gcc_mxe_mingw64_repos") load("@crt//toolchains/cc65:repository.bzl", "cc65_repos") @@ -11,6 +12,7 @@ def crt_register_toolchains( arm = False, m6502 = False, riscv32 = False, + cheri_riscv32 = False, win64 = False): native.register_execution_platforms("@local_config_platform//:host") if arm: @@ -28,6 +30,11 @@ def crt_register_toolchains( native.register_execution_platforms("@crt//platforms/riscv32:all") native.register_toolchains("@crt//toolchains/lowrisc_rv32imcb:all") + if cheri_riscv32: + cheri_llvm_repos() + native.register_execution_platforms("@crt//platforms/cheri/riscv32:all") + native.register_toolchains("@crt//toolchains/cheri_llvm:all") + if win64: gcc_mxe_mingw64_repos() native.register_execution_platforms("@crt//platforms/x86_64:all") diff --git a/constraints/BUILD.bazel b/constraints/BUILD.bazel new file mode 100644 index 0000000..f29bca3 --- /dev/null +++ b/constraints/BUILD.bazel @@ -0,0 +1,5 @@ +# Copyright lowRISC contributors. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +package(default_visibility = ["//visibility:public"]) diff --git a/constraints/extension/BUILD.bazel b/constraints/extension/BUILD.bazel new file mode 100644 index 0000000..f92a5c9 --- /dev/null +++ b/constraints/extension/BUILD.bazel @@ -0,0 +1,8 @@ +package(default_visibility = ["//visibility:public"]) + +constraint_setting(name = "extension") + +constraint_value( + name = "cheri", + constraint_setting = ":extension", +) diff --git a/platforms/cheri/BUILD.bazel b/platforms/cheri/BUILD.bazel new file mode 100644 index 0000000..ffd0fb0 --- /dev/null +++ b/platforms/cheri/BUILD.bazel @@ -0,0 +1 @@ +package(default_visibility = ["//visibility:public"]) diff --git a/platforms/cheri/riscv32/BUILD.bazel b/platforms/cheri/riscv32/BUILD.bazel new file mode 100644 index 0000000..6a92362 --- /dev/null +++ b/platforms/cheri/riscv32/BUILD.bazel @@ -0,0 +1,11 @@ +package(default_visibility = ["//visibility:public"]) + +load("//config:execution.bzl", "exec_config") + +platform( + name = "cheri-riscv32", + constraint_values = [ + "@platforms//cpu:riscv32", + "//constraints/extension:cheri", + ], +) diff --git a/platforms/cheri/riscv32/devices.bzl b/platforms/cheri/riscv32/devices.bzl new file mode 100644 index 0000000..eafa2ed --- /dev/null +++ b/platforms/cheri/riscv32/devices.bzl @@ -0,0 +1,28 @@ +load("//config:device.bzl", "device_config") +load("//config:compiler.bzl", "listify_flags") + +DEVICES = [ + device_config( + name = "cheri-riscv32", + architecture = "rv32imcxcheri", + feature_set = "//platforms/cheri/riscv32/features:rv32imcxcheri", + constraints = [ + "@platforms//cpu:riscv32", + "//constraints/extension:cheri", + ], + substitutions = { + "ARCHITECTURE": "rv32imcxcheri", + "ABI": "il32pc64", + "CMODEL": "medany", + "ENDIAN": "little", + "TARGET": "riscv32-unknown-elf", + "[STACK_PROTECTOR]": "", + "[SYSTEM_LIBRARY_PATHS]": listify_flags( + "-L{}", + [ + "external/cheri_llvm_files/sdk/baremetal/baremetal-riscv32-purecap/riscv32-unknown-elf/lib/", + ], + ), + }, + ), +] diff --git a/platforms/cheri/riscv32/features/BUILD.bazel b/platforms/cheri/riscv32/features/BUILD.bazel new file mode 100644 index 0000000..20069b8 --- /dev/null +++ b/platforms/cheri/riscv32/features/BUILD.bazel @@ -0,0 +1,86 @@ +load( + "//config:features.bzl", + "CPP_ALL_COMPILE_ACTIONS", + "C_ALL_COMPILE_ACTIONS", + "LD_ALL_ACTIONS", + "feature", + "feature_set", + "flag_group", + "flag_set", +) + +package(default_visibility = ["//visibility:public"]) + +feature( + name = "architecture", + enabled = True, + flag_sets = [ + flag_set( + actions = CPP_ALL_COMPILE_ACTIONS + C_ALL_COMPILE_ACTIONS + LD_ALL_ACTIONS, + flag_groups = [ + flag_group( + flags = [ + "-march=ARCHITECTURE", + "-mabi=ABI", + "-mcmodel=CMODEL", + "-mENDIAN-endian", + "--target=TARGET", + "-mno-relax", + ], + ), + ], + ), + ], +) + +feature( + name = "fastbuild", + enabled = False, + flag_sets = [ + flag_set( + actions = CPP_ALL_COMPILE_ACTIONS + C_ALL_COMPILE_ACTIONS, + flag_groups = [ + flag_group( + flags = [ + "-Os", + "-g", + ], + ), + ], + ), + ], + provides = ["compilation_mode"], +) + +feature( + name = "library_search_directories", + enabled = True, + flag_sets = [ + flag_set( + actions = LD_ALL_ACTIONS, + flag_groups = [ + flag_group( + flags = ["[SYSTEM_LIBRARY_PATHS]"], + ), + flag_group( + expand_if_available = "library_search_directories", + flags = ["-L%{library_search_directories}"], + iterate_over = "library_search_directories", + ), + ], + ), + ], +) + +feature_set( + name = "rv32imcxcheri", + base = [ + "//features/common", + "//features/embedded", + ], + feature = [ + ":architecture", + ":fastbuild", + ":library_search_directories", + ], +) diff --git a/toolchains/cheri_llvm/BUILD.bazel b/toolchains/cheri_llvm/BUILD.bazel new file mode 100644 index 0000000..19c1923 --- /dev/null +++ b/toolchains/cheri_llvm/BUILD.bazel @@ -0,0 +1,41 @@ +load("//config:compiler.bzl", "setup") +load("//platforms/cheri/riscv32:devices.bzl", "DEVICES") + +package(default_visibility = ["//visibility:public"]) + +SYSTEM_INCLUDE_PATHS = [ + "external/cheri_llvm_files/sdk/lib/clang/13.0.0/include", + "external/cheri_llvm_files/sdk/baremetal/baremetal-riscv32-purecap/riscv32-unknown-elf/include/", +] + +filegroup( + name = "compiler_components", + srcs = [ + "//toolchains/cheri_llvm/wrappers:all", + "@cheri_llvm_files//:all", + ], +) + +[setup( + name = device.name, + architecture = device.architecture, + artifact_naming = device.artifact_naming, + compiler_components = ":compiler_components", + constraints = device.constraints, + feature_set = device.feature_set, + include_directories = SYSTEM_INCLUDE_PATHS, + params = { + "compiler": "clang", + }, + substitutions = device.substitutions, + tools = { + "ar": "wrappers/ar", + "cpp": "wrappers/cpp", + "gcc": "wrappers/clang", + "ld": "wrappers/ld", + "nm": "wrappers/nm", + "objcopy": "wrappers/objcopy", + "objdump": "wrappers/objdump", + "strip": "wrappers/strip", + }, +) for device in DEVICES] diff --git a/toolchains/cheri_llvm/archive/BUILD.bazel b/toolchains/cheri_llvm/archive/BUILD.bazel new file mode 100644 index 0000000..ffd0fb0 --- /dev/null +++ b/toolchains/cheri_llvm/archive/BUILD.bazel @@ -0,0 +1 @@ +package(default_visibility = ["//visibility:public"]) diff --git a/toolchains/cheri_llvm/archive/README.md b/toolchains/cheri_llvm/archive/README.md new file mode 100644 index 0000000..0bc37df --- /dev/null +++ b/toolchains/cheri_llvm/archive/README.md @@ -0,0 +1,23 @@ +### Instructions for building the CHERI-LLVM toolchain archive for purecap riscv32 + +This will use [cheribuild](https://github.com/CTSRD-CHERI/cheribuild) to build +the CHERI-LLVM RISC-V 32bit "purecap" toolchain for embedded development. +By default, the sources and toolchain will be fetched and built in `~/cheri/`. +This can be changed using the `--source-root`, `--output-root`, `--build-root`, +and `--tools-root` arguments. `-d` ensures required steps are executed (i.e. +builds LLVM & Clang before compiling the libraries). `-j` controls the number +of threads to be used for compilation. + +Clone the cheribuild repository anywhere (its directory will not be used for building), then: + +`./cheribuild.py newlib-baremetal-riscv32-purecap -d` (for libc, libm, libg) +`./cheribuild.py compiler-rt-builtins-baremetal-riscv32-purecap -d` (for builtins) + +Then `cd` to wherever the sdk folder is (`~/cheri/output/` by default, +or within either of the directories pointed to when passing +`--tool-root` or `--output-root`) and tar the `sdk` folder: +`tar -cvzf cheri_llvm_sdk.tar.gz sdk/` + +Lastly, copy `cheri_llvm_sdk.tar.gz` to this folder. The name must match the +filename in the `archive` field in `../repository.bzl` + diff --git a/toolchains/cheri_llvm/repository.bzl b/toolchains/cheri_llvm/repository.bzl new file mode 100644 index 0000000..25d541b --- /dev/null +++ b/toolchains/cheri_llvm/repository.bzl @@ -0,0 +1,8 @@ +load("@crt//config:repo.bzl", "compiler_repository") + +def cheri_llvm_repos(): + compiler_repository( + name = "cheri_llvm_files", + archive = "@crt//toolchains/cheri_llvm/archive:cheri_llvm_sdk.tar.gz", + exports = ["sdk/bin/**"], + ) diff --git a/toolchains/cheri_llvm/wrappers/BUILD b/toolchains/cheri_llvm/wrappers/BUILD new file mode 100644 index 0000000..b44d8ec --- /dev/null +++ b/toolchains/cheri_llvm/wrappers/BUILD @@ -0,0 +1,17 @@ +package(default_visibility = ["//visibility:public"]) + +exports_files(glob(["*"])) + +filegroup( + name = "all", + srcs = [ + "ar", + "clang", + "cpp", + "ld", + "nm", + "objcopy", + "objdump", + "strip", + ], +) diff --git a/toolchains/cheri_llvm/wrappers/ar b/toolchains/cheri_llvm/wrappers/ar new file mode 120000 index 0000000..da2bdd9 --- /dev/null +++ b/toolchains/cheri_llvm/wrappers/ar @@ -0,0 +1 @@ +driver.sh \ No newline at end of file diff --git a/toolchains/cheri_llvm/wrappers/clang b/toolchains/cheri_llvm/wrappers/clang new file mode 120000 index 0000000..da2bdd9 --- /dev/null +++ b/toolchains/cheri_llvm/wrappers/clang @@ -0,0 +1 @@ +driver.sh \ No newline at end of file diff --git a/toolchains/cheri_llvm/wrappers/cpp b/toolchains/cheri_llvm/wrappers/cpp new file mode 120000 index 0000000..da2bdd9 --- /dev/null +++ b/toolchains/cheri_llvm/wrappers/cpp @@ -0,0 +1 @@ +driver.sh \ No newline at end of file diff --git a/toolchains/cheri_llvm/wrappers/driver.sh b/toolchains/cheri_llvm/wrappers/driver.sh new file mode 100755 index 0000000..2a47197 --- /dev/null +++ b/toolchains/cheri_llvm/wrappers/driver.sh @@ -0,0 +1,13 @@ +#!/bin/bash --norc + +PROG=${0##*/} +TOOLCHAIN="cheri_llvm_files" +VERSION="13.0.0" + +ARGS=() +POSTARGS=() + +exec "external/${TOOLCHAIN}/sdk/bin/${PROG}" \ + "${ARGS[@]}" \ + "$@"\ + "${POSTARGS[@]}" diff --git a/toolchains/cheri_llvm/wrappers/ld b/toolchains/cheri_llvm/wrappers/ld new file mode 120000 index 0000000..da2bdd9 --- /dev/null +++ b/toolchains/cheri_llvm/wrappers/ld @@ -0,0 +1 @@ +driver.sh \ No newline at end of file diff --git a/toolchains/cheri_llvm/wrappers/nm b/toolchains/cheri_llvm/wrappers/nm new file mode 120000 index 0000000..da2bdd9 --- /dev/null +++ b/toolchains/cheri_llvm/wrappers/nm @@ -0,0 +1 @@ +driver.sh \ No newline at end of file diff --git a/toolchains/cheri_llvm/wrappers/objcopy b/toolchains/cheri_llvm/wrappers/objcopy new file mode 120000 index 0000000..da2bdd9 --- /dev/null +++ b/toolchains/cheri_llvm/wrappers/objcopy @@ -0,0 +1 @@ +driver.sh \ No newline at end of file diff --git a/toolchains/cheri_llvm/wrappers/objdump b/toolchains/cheri_llvm/wrappers/objdump new file mode 120000 index 0000000..da2bdd9 --- /dev/null +++ b/toolchains/cheri_llvm/wrappers/objdump @@ -0,0 +1 @@ +driver.sh \ No newline at end of file diff --git a/toolchains/cheri_llvm/wrappers/strip b/toolchains/cheri_llvm/wrappers/strip new file mode 120000 index 0000000..da2bdd9 --- /dev/null +++ b/toolchains/cheri_llvm/wrappers/strip @@ -0,0 +1 @@ +driver.sh \ No newline at end of file