C 具有DWARF的全局变量的位置(和重定位)
将二进制文件与库动态链接时,重定位信息用于绑定不同ELF对象的变量/函数。然而,DWARF不受重新定位的影响:调试器应该如何解析全局变量 假设liba.so(a.c)定义了一个全局变量(使用GNU/Linux和GCC或Clang): foo变量实例化两次:C 具有DWARF的全局变量的位置(和重定位),c,elf,dwarf,C,Elf,Dwarf,将二进制文件与库动态链接时,重定位信息用于绑定不同ELF对象的变量/函数。然而,DWARF不受重新定位的影响:调试器应该如何解析全局变量 假设liba.so(a.c)定义了一个全局变量(使用GNU/Linux和GCC或Clang): foo变量实例化两次: 一旦进入liba.so(与程序b链接时不使用此实例) 在b中使用一次(此实例用于b中其他实例的实例) (我真的不明白为什么变量会在可执行文件中实例化。) 在DWARF信息中,b中只有一个声明(如预期的那样): $ readelf -wi
- 一旦进入liba.so(与程序b链接时不使用此实例)
- 在b中使用一次(此实例用于b中其他实例的实例)
$ 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
[...]
$readelf-wi b
[...]
:Abbrev编号:9(DW_标记_变量)
DW_AT_名称:foo
DW_AT_decl_文件:1
德克卢线的德瓦卢:3
DW_AT_类型:
DW_在_外部:1
DW_AT_声明:1
[...]
在liba中找到了一个位置。因此:
[...]
0x0000000000600c68 - 0x0000000000600c70 is .bss
[...]
0x00007ffff7dda9c8 - 0x00007ffff7dda9d4 is .data in /home/foo/bar/liba.so
0x00007ffff7dda9d4 - 0x00007ffff7dda9d8 is .bss in /home/foo/bar/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)
[...]
$readelf-wi liba.so
[...]
:Abbrev编号:5(DW_标记_变量)
DW_AT_名称:foo
DW_AT_decl_文件:1
德克卢线的德瓦卢:3
DW_AT_类型:
DW_在_外部:1
地点:9个八位组:3 d0 9 20 0 0 0(地址:2009d0)
[...]
此地址是liba.so(.data)中foo的(未命名)实例的位置
- 最后我得到了foo全局变量的两个实例(liba.so中的on和b中的一个)李>
- 只有第一个能被矮人看到李>
- 只使用secone
foo
确实在主可执行文件b
和liba中定义。因此
:
nm b | grep foo
0000000000600c68 B foo
(我阅读了@Employed俄语提供的Oracle文档。)
对非PIC代码执行全局变量重新实例化,以便在不修补非PIC代码的情况下以非PIC方式取消对变量的引用:
- 为非PIC代码复制变量李>
- 变量在可执行文件中实例化李>
- 复制重定位指令用于在动态链接时从源共享对象复制数据李>
- 不使用共享对象中的实例(在重新定位复制完成后)
$readelf -r b
Relocation section '.rela.dyn' at offset 0x638 contains 2 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000600c58 000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
000000600ca8 001200000005 R_X86_64_COPY 0000000000600ca8 foo + 0
对于函数,GOT+PLT技术的使用方式与PIC代码中的使用方式相同
$ 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)
[...]
nm b | grep foo
0000000000600c68 B foo
$readelf -r b
Relocation section '.rela.dyn' at offset 0x638 contains 2 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000600c58 000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
000000600ca8 001200000005 R_X86_64_COPY 0000000000600ca8 foo + 0