Разрешить относительные перемещения в частичной ссылке

Я заметил, что использование -r для частичной ссылки на самом деле не решает никаких перемещений, кажется, даже если они могут быть разрешены с помощью относительной адресации. Например, рассмотрим f.o и g.o, где f.o содержит f(), который вызывает g() в g.o. Перед линковкой разборка и перестановки ожидаются. Однако после частичного связывания с новым файлом h.o (через ld -r -o h.o f.o g.o) вызов g() все еще перемещается, хотя теоретически он мог быть разрешен с помощью относительного адреса.

Вот разборка h.o (objdump -d h.o), содержащая f() и g(). Вы можете видеть, что вызов g() все еще не разрешен:

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

Вот таблица перемещения 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

Итак, просто интересно, есть ли способ принудительно выполнить перемещение через относительный адрес во время частичной ссылки. Я попытался скомпилировать код с -fpic, но это все равно не привело к перемещению во время частичного связывания.

Обратите внимание, что у меня нет цели, приложения или причины для этого. Просто изучаю функциональность и возможности ld.


person kec    schedule 10.02.2016    source источник
comment
Я также узнал, что gcc также не разрешает перемещения вызовов однофайловых функций по умолчанию: stackoverflow.com/questions/29391965/   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 28.12.2018


Ответы (1)


Согласно этой ссылке, это выглядит например, причина того, что относительные символы не разрешены, заключается в том, чтобы придать связанной большей гибкости. Если бы мы вместо этого хотели преобразовать символ g в другой адрес, нам нужно было бы изменить эти переходы в коде.

Однако, если вы измените символ g на статический, компоновщик разрешит скачки. В этом случае символ больше не экспортируется и, следовательно, не может быть изменен будущими вызовами компоновщика.

person Strikeskids    schedule 04.12.2017