Resolve relative relocations in partial link

2019-02-24 07:52发布

问题:

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.

回答1:

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.