Skip to content
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

clang appears to emit calls to c++ memcpy from c code when processing __builtin_memcpy #31

Open
sleffler opened this issue Jun 21, 2024 · 4 comments

Comments

@sleffler
Copy link

Opentitan again, building the boot rom which is c & assembler (no c++). I get undefined symbols; e.g.

ld.lld: error: undefined symbol: __library_export_libcalls__Z6memcpyPvPKvj
>>> referenced by flash_ctrl_testutils.c
>>>               flash_ctrl_testutils.o:(__library_import_libcalls__Z6memcpyPvPKvj) in archive bazel-out/k8-fastbuild/bin/external/lowrisc_opentitan/sw/device/lib/testing/libflash_ctrl_testutils.a

Tracked this down to structure copies and similar operations. One example workaround is this (might be non-opentitan code as we incorporate opentitan in a more complex environment):

-  const char kTarMagic[] = "ustar";
+//  const char kTarMagic[] = "ustar";
+  const char* kTarMagic = "ustar";

but there are many others (e.g. struct's passed by value as params). I also saw an explicit __builtin_memcpy converted to a call to the c++ memcpy.

This is a sample cmd line:

toolchains/cheri_llvm/wrappers/clang -MD -MF bazel-out/k8-fastbuild/bin/sw/device/lib/_objs/spi_flash/spi_flash.d '-frandom-seed=bazel-out/k8-fastbuild/bin/sw/device/lib/_objs/spi_flash/spi_flash.o' '-DBAZEL_CURRENT_REPOSITORY=""' -iquote . -iquote bazel-out/k8-fastbuild/bin -iquote external/lowrisc_opentitan -iquote bazel-out/k8-fastbuild/bin/external/lowrisc_opentitan -Ibazel-out/k8-fastbuild/bin/external/lowrisc_opentitan/hw/ip/flash_ctrl/data -Ibazel-out/k8-fastbuild/bin/external/lowrisc_opentitan/hw/top_earlgrey/ip/flash_ctrl/data/autogen -Ibazel-out/k8-fastbuild/bin/external/lowrisc_opentitan/hw/ip/uart/data -Ibazel-out/k8-fastbuild/bin/external/lowrisc_opentitan/hw/ip/otp_ctrl/data -Ibazel-out/k8-fastbuild/bin/external/lowrisc_opentitan/hw/ip/spi_host/data -nostdinc -isystemexternal/cheriot-llvm/lib/clang/13.0.0/include -isystemexternal/cheriot-llvm/riscv32-unknown-elf/include '-march=rv32imcxcheri' '-mcpu=cheriot' '-mabi=cheriot' '-mcmodel=medany' -mlittle-endian '--target=riscv32-unknown-elf' -mxcheri-rvc -mrelax '-DCHERI=1' '-Werror=date-time' -ffunction-sections -fdata-sections -Os -g -ffreestanding -fno-common '' '-std=gnu11' -S sw/device/lib/spi_flash.c -o spi_flash.s

Tried adding -fno-built-memcpy but it seemed to have no effect. Maybe I'm missing a compiler flag?

@davidchisnall
Copy link

This is not a C++ memcpy, this is a memcpy with the CHERIoT libcall calling convention. We mangle all libcall calling convention functions to avoid problems where people accidentally miss type signature changes.

Freestanding C implementations are required to provide memcpy (and memcmp) and so LLVM does not have a mode to disable requiring them. For bare metal code, the best thing to do is have an early init phase set provide the sentry for the memcpy function in the compiler-generated export table entry.

@sleffler
Copy link
Author

sleffler commented Jun 24, 2024 via email

@davidchisnall
Copy link

Ok. Don't recall seeing this documented anywhere.

It's in §5.3 of the CHERIoT Architecture doc (Chapter 5 is the ABI description). It's not documented anywhere else because the only people who should care about it are folks implementing compilers or loaders.

TBH I expected this to be part of a toolchain

For a system where the ISA, programmer model, ABI, and RTOS are co-designed, it's not always clear where the best home for something is. We currently don't provide any headers with the compiler and expect them to come from the RTOS in all cases.

If you need to run code using the CHERIoT ABI from ROM, then you probably need to run a loader-style step early on that embeds the capabilities in the code for the ROM. We haven't done that because it breaks the strong provenance chain for all capabilities in the system are derived from the ones provided at boot (which lets us to layered boot things where each step in the chain may be arbitrarily restricted by a prior step).

@sleffler
Copy link
Author

sleffler commented Jun 24, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants