Description
Hello,
I'm trying to use LLVM profiling on a kernel, and would like to export the data to a buffer using the provided __llvm_profile_{get_size_for_buffer,write_buffer,reset_counters}()
helpers. I've declared external prototypes for them at the caller translation unit, and also defined __llvm_profile_runtime
on that same translation unit as a global symbol.
However, when attempting to link the resulting object files together, I get the following errors:
# ld -melf_x86_64_fbsd -T arch/x86/xen.lds -N prelink.o --build-id=sha1 ./common/symbols-dummy.o -o ./.xen-syms.0
ld: error: undefined hidden symbol: __llvm_profile_get_size_for_buffer
>>> referenced by lib/xxhash64.c
>>> prelink.o:(get_size)
>>> referenced by lib/xxhash64.c
>>> prelink.o:(dump)
ld: error: undefined hidden symbol: __llvm_profile_reset_counters
>>> referenced by lib/xxhash64.c
>>> prelink.o:(reset_counters)
ld: error: undefined hidden symbol: __llvm_profile_write_buffer
>>> referenced by lib/xxhash64.c
>>> prelink.o:(dump)
I can kind of workaround those by adding the compiler_rt profiling library to the linker phase:
# ld /usr/lib/clang/19/lib/freebsd/libclang_rt.profile-x86_64.a -melf_x86_64_fbsd -T arch/x86/xen.lds -N prelink.o --build-id=sha1 ./common/symbols-dummy.o -o ./.xen-syms.0
ld: error: /usr/lib/clang/19/lib/freebsd/libclang_rt.profile-x86_64.a(InstrProfilingPlatformLinux.o):(function __llvm_write_binary_ids: .text+0xf3): relocation R_X86_64_PC32 out of range: 137644034653121 is not in [-2147483648, 2147483647]; references '__ehdr_start'
>>> referenced by InstrProfilingPlatformLinux.c:179 (/usr/src/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c:179)
>>> defined in <internal>
ld: error: /usr/lib/clang/19/lib/freebsd/libclang_rt.profile-x86_64.a(InstrProfilingPlatformLinux.o):(function __llvm_write_binary_ids: .text+0x118): relocation R_X86_64_PC32 out of range: 137644034653028 is not in [-2147483648, 2147483647]; references '__ehdr_start'
>>> referenced by InstrProfilingPlatformLinux.c:0 (/usr/src/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c:0)
>>> defined in <internal>
ld: error: /usr/lib/clang/19/lib/freebsd/libclang_rt.profile-x86_64.a(InstrProfilingPlatformLinux.o):(function __llvm_write_binary_ids: .text+0x11f): relocation R_X86_64_PC32 out of range: 137644034653053 is not in [-2147483648, 2147483647]; references '__ehdr_start'
>>> referenced by InstrProfilingPlatformLinux.c:0 (/usr/src/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c:0)
>>> defined in <internal>
ld: error: /usr/lib/clang/19/lib/freebsd/libclang_rt.profile-x86_64.a(InstrProfilingPlatformLinux.o):(function __llvm_write_binary_ids: .text+0x19e): relocation R_X86_64_PC32 out of range: 137644034652894 is not in [-2147483648, 2147483647]; references '__ehdr_start'
>>> referenced by InstrProfilingPlatformLinux.c:0 (/usr/src/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c:0)
>>> defined in <internal>
But that's ugly, as I don't know a programatic way to get the name and path of the required compiler_rt profiling library, neither does it solve the issue, as now there are unsolved relocations against __ehdr_start
. Is there some guidance I'm missing about how to use profiling on freestanding environments?