Open vext01 opened 10 months ago
If you turn off PIE, then the symbol comes back:
$ clang -fno-PIE -no-pie -Wno-override-module -fuse-ld=lld stackmaps.ll && nm a.out | grep main | grep -v start
0000000000201640 T main
ELF .llvm_stackmaps
is readonly. The format seems not designed for static links using -pie
/-shared
because dynamic relocations are needed.
It can switch to PC-relative relocations to avoid this problem.
% readelf -Wr stackmaps.o
Relocation section '.rela.llvm_stackmaps' at offset 0x150 contains 1 entry:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000010 0000000400000001 R_X86_64_64 0000000000000000 main + 0
Relocation section '.rela.eh_frame' at offset 0x168 contains 1 entry:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000020 0000000200000002 R_X86_64_PC32 0000000000000000 .text + 0
There will be a linker error if you specify -z text
or use binutils configured with --enable-textrel-check=yes
.
lld creates a canonical PLT entry, so we see an undefined symbol with a non-zero st_value
.
% readelf -Ws a.out | grep 'Num:\| main'
Num: Value Size Type Bind Vis Ndx Name
Num: Value Size Type Bind Vis Ndx Name
22: 0000000000001720 0 FUNC GLOBAL DEFAULT UND main
However, the symbol is not exported and we will get a R_X86_64_JUMP_SLOT
referencing the null symbol.
I have created https://github.com/llvm/llvm-project/pull/75095 to add the error to lld, but .llvm_stackmaps
also needs a change to work with -pie
.
Thanks for the info.
By the way, I notice some other "possibly useful at runtime" sections, aren't marked SHT_ALLOC
, which means that the loader won't load them, and all addresses inside talk about file offsets instead of virtual addresses. Look for example at the basic block labels section (.llvm_bb_addr_map
, created with -lto-basic-block-sections=labels
).
One possible fix (maybe not the best) is to do the same with the stackmap section (i.e. revoke SHT_ALLOC
) at the cost of:
I must admit, I don't know much about relocations, but I will give the link you posted a read.
Take the following input programs:
Using LLVM as of the time of writing:
If you use
lld
to link and emit a stackmap section, themain
symbol becomes undefined.gnu ld, no stackmaps
gnu ld, with stackmaps
lld, no stackmaps
lld, with stackmaps
Why is this? Is this bug?
This breaks something I'm working on that uses
dladdr(3)
at runtime.CC @lhames