При динамической связывании двоичного кода с библиотеками информация о перемещении используется для связывания переменных/функций различных объектов ELF. Однако DWARF не зависит от перемещения: как отладчик должен разрешать глобальные переменные?Расположение глобальных переменных с DWARF (и перемещением)
Скажем, у меня есть liba.so (ас), определяющего глобальную переменную (с помощью GNU/Linux с помощью GCC или Clang):
#include <stdio.h>
int foo = 10;
int test(void) {
printf("&foo=%p\n", &foo);
}
и программы б связаны с liba.so (РМЖ):
#include <stdio.h>
extern int foo;
int main(int argc, char** argv) {
test();
printf("&foo=%p\n", &foo);
return 0;
}
Я ожидаю, что «Foo» будет инстанциирован в liba.so , но на самом деле это инстанциирован в обоих liba.so и б:
$ ./b
&foo=0x600c68 # <- b .bss
&foo=0x600c68 # <- b .bss
Переменная Foo, который используется (как по б и lib.so) находится в .bss Ь , а не в liba.so:
[...]
0x0000000000600c68 - 0x0000000000600c70 is .bss
[...]
0x00007ffff7dda9c8 - 0x00007ffff7dda9d4 is .data in /home/foo/bar/liba.so
0x00007ffff7dda9d4 - 0x00007ffff7dda9d8 is .bss in /home/foo/bar/liba.so
Переменная Foo является инстанциирован дважды:
один раз в liba.so (данный экземпляр не используется, когда связан с программой б)
один раз в б (этот экземпляр используется экземпляр другого в б).
(я не понимаю, почему переменная инстанциирован в исполняемый файл.)
Существует только декларация в Ь (как и ожидалось) в информаций карликовых:
$ readelf -wi b
[...]
<1><ca>: Abbrev Number: 9 (DW_TAG_variable)
<cb> DW_AT_name : foo
<cf> DW_AT_decl_file : 1
<d0> DW_AT_decl_line : 3
<d1> DW_AT_type : <0x57>
<d5> DW_AT_external : 1
<d5> DW_AT_declaration : 1
[...]
и местоположение находится в liba.so:
$ readelf -wi liba.so
[...]
<1><90>: Abbrev Number: 5 (DW_TAG_variable)
<91> DW_AT_name : foo
<95> DW_AT_decl_file : 1
<96> DW_AT_decl_line : 3
<97> DW_AT_type : <0x57>
<9b> DW_AT_external : 1
<9b> DW_AT_location : 9 bloc d'octets: 3 d0 9 20 0 0 0 0 0 (DW_OP_addr: 2009d0)
[...]
Этот адрес является местонахождение (unsued) в позиция foo в liba.so (.data).
- В итоге я получаю 2 экземпляра глобальной переменной foo (в liba.so и один в b);
- только первый вид с DWARF;
- только один secone используется.
Как отладчик должен разрешить глобальную переменную foo?