i'm writing a no_std program for macos. and, long story short, i need to make sure my code doesn't call into libc (or any other shared library for that matter).
the issue is, the compiler generates calls to memcpy, memset, etc for large structs/arrays.
but i can work around that by defining those functions myself.
in optimized builds however, the compiler sometimes generates calls to bzero directly instead of memset. and the trick of defining bzero myself doesn't work (possibly because it's not a weak symbol or something like that).
i'm looking for something like -nostdlib. so i get linker errors whenever the compiler uses a new libc symbol and can define it myself.
For memcpy, memset and such you probably want to use the compiler-builtins crate with the mem feature enabled. Make sure to add use compiler_builtins as _; after you add the dependency to ensure that it is actually getting linked in. That said, avoiding libc on macOS is not something you should do. macOS doesn't have a stable syscall ABI and even has broken projects as big as Go when trying to avoid using libc. The lowest level stable ABI that macOS has is called libc.
i know, i'm working on a record/replay debugger, and i'll have kernel version specific code. this is only in the recording program. but i need to make sure that the pc doesn't leave my code section (because i trap the rest of memory).
okay thanks! i was going to look for an optimized impl at some point, that looks like it'll work.
but it still leaves me with the bzero issue.
maybe i'll just try to avoid code that does bulk zero initialization.
is there really no way to pass something like -nostdlib on to llvm?
(btw, i don't need use compiler_builtins as _;. and why would that result in the code being linked?)
Rustc will ignore dependencies you declared in Cargo.toml unless you reference them somewhere in your source. Even an unused use is enough for rustc to load the crate metadata for the dependency, which then results in the dependency getting linked even if unused.
since bzero only appears in optimized builds, i assume this is an llvm optimization that turns memset(ptr, 0, size) (-like code) into bzero(ptr, size).
with clang's -nostdlib, i'd get what i'd like:
% clang -nostdlib -O2 foo.c
Undefined symbols for architecture arm64:
"___stack_chk_fail", referenced from:
_main in foo-272caa.o
"___stack_chk_guard", referenced from:
_main in foo-272caa.o
_main in foo-272caa.o
"_bzero", referenced from:
_main in foo-272caa.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
i don't know, is there some flag that clang passes to llvm, that i could also pass through rustc in some unstable/nightly way?