-
Notifications
You must be signed in to change notification settings - Fork 14
Add support for the CHERI-LLVM toolchain for RV32 baremetal apps #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
714bd8b
a5ffa91
4bd96e2
98898e7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package(default_visibility = ["//visibility:public"]) | ||
ivanmgribeiro-google marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
load("//config:execution.bzl", "exec_config") | ||
|
||
platform( | ||
name = "riscv32-cheri", | ||
constraint_values = [ | ||
"@platforms//cpu:riscv32", | ||
"//platforms/riscv32-cheri/extension:cheri", | ||
], | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
load("//config:device.bzl", "device_config") | ||
|
||
DEVICES = [ | ||
device_config( | ||
name = "riscv32-cheri", | ||
architecture = "rv32imcxcheri", | ||
feature_set = "//platforms/riscv32-cheri/features:rv32imcxcheri", | ||
constraints = [ | ||
"@platforms//cpu:riscv32", | ||
"//platforms/riscv32-cheri/extension:cheri", | ||
], | ||
substitutions = { | ||
"ARCHITECTURE": "rv32imcxcheri", | ||
"ABI": "il32pc64", | ||
"CMODEL": "medany", | ||
"ENDIAN": "little", | ||
"[STACK_PROTECTOR]": "", | ||
}, | ||
), | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package(default_visibility = ["//visibility:public"]) | ||
ivanmgribeiro-google marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
constraint_setting(name = "extension") | ||
|
||
constraint_value( | ||
name = "cheri", | ||
constraint_setting = ":extension", | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
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=riscv32-unknown-elf", | ||
"-mno-relax", | ||
# tell the loader where the base libraries are | ||
"-Lexternal/cheri_llvm_files/sdk/baremetal/baremetal-riscv32-purecap/riscv32-unknown-elf/lib/", | ||
], | ||
), | ||
], | ||
), | ||
], | ||
) | ||
|
||
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_set( | ||
name = "rv32imcxcheri", | ||
base = [ | ||
"//features/common", | ||
"//features/embedded", | ||
], | ||
feature = [ | ||
":architecture", | ||
":fastbuild", | ||
], | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
load("//config:compiler.bzl", "setup") | ||
load("//platforms/riscv32-cheri: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] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package(default_visibility = ["//visibility:public"]) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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` | ||
Comment on lines
+21
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should discuss how to allow you to provide the compiler archive without requiring it to be in this repository or requiring the user to take a repository modifying action (e.g. copying the file into this subdir). Modifying the repository as a build step is "bad". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've been thinking about how to allow you to supply the compiler archive without needing to ask the user to modify the repository. There are two mechanisms I can think of:
I've been considering something like (2) for a while to enable end users to pass in alternate compilers, but I haven't yet had a need for it and I'd probably want to plumb things up a bit more to make the archive properties more configurable. |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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/**"], | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package(default_visibility = ["//visibility:public"]) | ||
|
||
exports_files(glob(["*"])) | ||
|
||
filegroup( | ||
name = "all", | ||
srcs = [ | ||
"ar", | ||
"clang", | ||
"cpp", | ||
"ld", | ||
"nm", | ||
"objcopy", | ||
"objdump", | ||
"strip", | ||
], | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
driver.sh |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
driver.sh |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
driver.sh |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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[@]}" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
driver.sh |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
driver.sh |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
driver.sh |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
driver.sh |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
driver.sh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be named something like
riscv32_cheri
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CHERI LLVM toolchain can also generate riscv64 binaries, and even mips64 binaries (although this is almost never used nowadays) so I would hesitate to tie the name to riscv32.
The steps described in the README for building the archive specifically build libraries etc. that target riscv32+cheri, but they could be extended to also build the requirements for riscv64+cheri baremetal, mips64+cheri baremetal or even vanilla riscv32/64 and the built archive could then be used for any of those targets, so I think a more generic toolchain name is more appropriate.
Let me know your thoughts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What we're adding in this PR is a particular toolchain configuration that informs bazel about how to select and run the compiler to emit
riscv32
code withcheri
features.When/if we get to the point of having
riscv64+cheri
ormips64+cheri
orx86_64+cheri
, we'll need to add those as separate configurations (note that these configurations could indeed be backed by a single compiler and appropriate constraints to select the proper feature set per configuration).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the risk of annoying your half-to-death with requests to change the directory structure, it sounds like it might be appropriate to change
platforms/riscv32/cheri/...
toplatforms/cheri/riscv32/...
. That would allow for the creation of ariscv64
,mips64
and whatever else under theplatforms/cheri
directory.I still think the appropriate name here (in
crt_register_toolchains
) is a combination ofcheri
and the architecture name. Even if you did eventually support a bunch of architectures with cheri options, downstream projects would probably only want to enable the configuration that was appropriate to their CPU architecture.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, this makes sense. I've committed changes to rename the argument
cheri_llvm
tocheri_riscv32
(the toolchain is still calledcheri_llvm
) and I've movedplatforms/riscv32/cheri
->platforms/cheri/riscv32
.