I've noticed that using -r
to do a partial link doesn't actually resolve any relocations, it seems, even if they could be resolved via relative addressing. For example, consider f.o
and g.o
, with f.o
containing f()
which calls g()
within g.o
. Before linking, the disassembly and relocations are as expected. After partial linking to a new file h.o
(via ld -r -o h.o f.o g.o
), however, there is still a relocation for the call to g()
, even though in theory it could have been resolved with a relative address.
Here is the disassembly of h.o
(objdump -d h.o
), containing f()
and g()
. You can see that the call to g()
is still unresolved:
h.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <f>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: e8 00 00 00 00 callq 9 <f+0x9>
9: 90 nop
a: 5d pop %rbp
b: c3 retq
000000000000000c <g>:
c: 55 push %rbp
d: 48 89 e5 mov %rsp,%rbp
10: 90 nop
11: 5d pop %rbp
12: c3 retq
Here is the relocation table of h.o
(objdump -r h.o
):
h.o: file format elf64-x86-64
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000000000000005 R_X86_64_PC32 g-0x0000000000000004
RELOCATION RECORDS FOR [.eh_frame]:
OFFSET TYPE VALUE
0000000000000020 R_X86_64_PC32 .text
0000000000000058 R_X86_64_PC32 .text+0x000000000000000c
So, just wondering whether or not there was any way to force the relocation to be performed via a relative address during a partial link. I tried compiling the code with -fpic
, but that still did not cause the relocation to be performed during the partial link.
Note that I have no goal, application, or reason for this. Just exploring the functionality and capabilities of ld
.
Per this reference it looks like the reason that the relative symbols are not resolved is to give the linked more flexibility. If we wanted to instead resolve the symbol
g
to a different address, we would need to change those jumps in the code.However, if you change your symbol
g
to be static, then the linker will resolve the jumps. In that case, the symbol is no longer exported and thus not manipulable by future linker calls.