I have an object file created by LLVM:
$ readelf -s test.o
Symbol table '.symtab' contains 8 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS test
2: 0000000000000010 22 FUNC LOCAL DEFAULT 2 start.callMain2
3: 0000000000000030 213 FUNC LOCAL DEFAULT 2 test.main
4: 0000000000000110 18 FUNC LOCAL DEFAULT 2 start.exit2
5: 0000000000000000 5 FUNC GLOBAL DEFAULT 2 _start
6: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND __extenddftf2
7: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND __eqtf2
You can see that it makes an external function call to __extenddftf2
as well as __eqtf2
which both need to be resolved by the linker.
Here I have a compiler-rt.o file:
$ readelf -s compiler-rt.o
Symbol table '.symtab' contains 40 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS compiler_rt
2: 0000000000000860 21 FUNC LOCAL DEFAULT 1 math.inf.inf__anon_38
3: 0000000000000000 0 NOTYPE LOCAL DEFAULT 3 .LCPI5_0
4: 0000000000000a40 21 FUNC LOCAL DEFAULT 1 math.inf.inf__anon_40
5: 0000000000000000 0 NOTYPE LOCAL DEFAULT 4 .LCPI7_0
6: 0000000000000cb0 18 FUNC LOCAL DEFAULT 1 math.inf.inf__anon_42
7: 0000000000000000 0 NOTYPE LOCAL DEFAULT 5 .LCPI9_0
8: 00000000000013f0 34 FUNC LOCAL DEFAULT 1 debug.assert
9: 0000000000000000 0 SECTION LOCAL DEFAULT 1
10: 0000000000000000 0 SECTION LOCAL DEFAULT 6
11: 0000000000000000 0 SECTION LOCAL DEFAULT 3
12: 0000000000000000 0 SECTION LOCAL DEFAULT 4
13: 0000000000000000 0 SECTION LOCAL DEFAULT 5
14: 0000000000000000 500 FUNC GLOBAL DEFAULT 1 __extenddftf2
15: 0000000000000200 427 FUNC GLOBAL DEFAULT 1 __extendsftf2
16: 00000000000003b0 329 FUNC GLOBAL DEFAULT 1 __extendhfsf2
17: 0000000000000500 450 FUNC GLOBAL DEFAULT 1 __extendhftf2
18: 00000000000006d0 393 FUNC GLOBAL DEFAULT 1 __lesf2
19: 0000000000000880 440 FUNC GLOBAL DEFAULT 1 __ledf2
20: 0000000000000a60 582 FUNC GLOBAL DEFAULT 1 __letf2
21: 0000000000000cd0 390 FUNC GLOBAL DEFAULT 1 __gesf2
22: 0000000000000e60 437 FUNC GLOBAL DEFAULT 1 __gedf2
23: 0000000000001020 579 FUNC GLOBAL DEFAULT 1 __getf2
24: 0000000000001270 46 FUNC GLOBAL DEFAULT 1 __eqsf2
25: 00000000000012a0 46 FUNC GLOBAL DEFAULT 1 __eqdf2
26: 00000000000012d0 46 FUNC GLOBAL DEFAULT 1 __ltsf2
27: 0000000000001300 46 FUNC GLOBAL DEFAULT 1 __ltdf2
28: 0000000000001330 46 FUNC GLOBAL DEFAULT 1 __nesf2
29: 0000000000001360 46 FUNC GLOBAL DEFAULT 1 __nedf2
30: 0000000000001390 46 FUNC GLOBAL DEFAULT 1 __gtsf2
31: 00000000000013c0 46 FUNC GLOBAL DEFAULT 1 __gtdf2
32: 00000000000003b0 329 FUNC GLOBAL DEFAULT 1 __gnu_h2f_ieee
33: 00000000000006d0 393 FUNC GLOBAL DEFAULT 1 __cmpsf2
34: 0000000000000880 440 FUNC GLOBAL DEFAULT 1 __cmpdf2
35: 0000000000000a60 582 FUNC GLOBAL DEFAULT 1 __cmptf2
36: 0000000000000a60 582 FUNC GLOBAL DEFAULT 1 __eqtf2
37: 0000000000000a60 582 FUNC GLOBAL DEFAULT 1 __lttf2
38: 0000000000000a60 582 FUNC GLOBAL DEFAULT 1 __netf2
39: 0000000000001020 579 FUNC GLOBAL DEFAULT 1 __gttf2
You can see it provides both functions. However, after linking:
ld.lld -error-limit=0 -z stack-size=16777216 --gc-sections -m elf_x86_64 -static -o test test.o /home/andy/.cache/zig/o/8fba243ef4ba3750d1cf9c276017e573/libc.a /home/andy/.cache/zig/o/a694ba35d496c525af985782dbb765f3/libcompiler_rt.a
The __cmptf2
function is
$ readelf -s test
Symbol table '.symtab' contains 13 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS test
2: 0000000000201130 22 FUNC LOCAL DEFAULT 1 start.callMain2
3: 0000000000201150 213 FUNC LOCAL DEFAULT 1 test.main
4: 0000000000201230 18 FUNC LOCAL DEFAULT 1 start.exit2
5: 0000000000000000 0 FILE LOCAL DEFAULT ABS compiler_rt
6: 0000000000201120 5 FUNC GLOBAL DEFAULT 1 _start
7: 0000000000201250 221 FUNC GLOBAL DEFAULT 1 __extenddftf2
8: 0000000000201330 0 FUNC GLOBAL DEFAULT 1 __eqtf2
9: 0000000000201330 0 FUNC GLOBAL DEFAULT 1 __letf2
10: 0000000000201330 0 FUNC GLOBAL DEFAULT 1 __cmptf2
11: 0000000000201330 0 FUNC GLOBAL DEFAULT 1 __lttf2
12: 0000000000201330 0 FUNC GLOBAL DEFAULT 1 __netf2
The binary crashes because the function call to __eqtf2
has been deleted (the Size is 0). However the call to __extenddftf2
has been preserved, as expected.
2011e2: e8 49 01 00 00 call 201330 <__cmptf2>
There is nothing at address 201330. What gives?
The problem went away when I deleted all the aliases of__eqtf2