简短的问题:有没有办法使用
elfread -a
打印函数变量的地址?
说明:我正在一个玩具编译器上做一些工作,它使用 llvm c++ API 生成一个共享库。我使用
dlopen()
和 lldb 工具对其进行了测试。
当我使用
elfread
命令查看文件中的符号表(如下所示)时,找到了我声明的函数(func1
func2
main
),但没有找到这些函数内的变量。
我现在想知道是否可以在运行时访问变量的地址?或者有什么方法可以让我从这些信息中获取它们?我对这种级别的计算相当陌生,因此任何有关 elf 格式的解释也将不胜感激。
Symbol table '.dynsym' contains 8 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC WEAK DEFAULT UND [...]@GLIBC_2.2.5 (2)
2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...]
3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[...]
5: 0000000000001120 16 FUNC GLOBAL DEFAULT 12 func1
6: 0000000000001160 75 FUNC GLOBAL DEFAULT 12 main
7: 0000000000001130 37 FUNC GLOBAL DEFAULT 12 func2
Symbol table '.symtab' contains 27 entries:
Num: Value Size Type Bind Vis Ndx Name
... ...
15: 00000000000011ac 0 FUNC LOCAL DEFAULT 13 _fini
16: 0000000000001000 0 FUNC LOCAL DEFAULT 9 _init
17: 0000000000003df0 0 OBJECT LOCAL DEFAULT 18 _DYNAMIC
18: 0000000000004030 0 OBJECT LOCAL DEFAULT 21 __TMC_END__
19: 0000000000004000 0 OBJECT LOCAL DEFAULT 20 _GLOBAL_OFFSET_TABLE_
20: 0000000000001120 16 FUNC GLOBAL DEFAULT 12 func1
21: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@G[...]
22: 0000000000001160 75 FUNC GLOBAL DEFAULT 12 main
23: 0000000000001130 37 FUNC GLOBAL DEFAULT 12 func2
24: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...]
25: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
26: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[...]
PS:我已成功将变量的调试信息添加到共享库中,我可以使用
llvm-dwarfdump
命令打印该信息:
0x0000000c: DW_TAG_compile_unit
DW_AT_producer ("demo3 Compiler")
DW_AT_language (DW_LANG_C)
DW_AT_name ("3-function.st")
DW_AT_str_offsets_base (0x00000008)
DW_AT_stmt_list (0x00000000)
DW_AT_comp_dir ("/root/Documents/llvm-compiler/ST_demo3/test/in")
DW_AT_low_pc (0x0000000000001120)
DW_AT_high_pc (0x00000000000011ab)
DW_AT_addr_base (0x00000008)
DW_AT_loclists_base (0x0000000c)
0x00000027: DW_TAG_subprogram
DW_AT_low_pc (0x0000000000001120)
DW_AT_high_pc (0x0000000000001130)
DW_AT_frame_base (DW_OP_reg7 RSP)
DW_AT_name ("func1")
DW_AT_decl_file ("/root/Documents/llvm-compiler/ST_demo3/test/in/3-function.st")
DW_AT_decl_line (2)
DW_AT_external (true)
0x00000032: DW_TAG_formal_parameter
DW_AT_location (DW_OP_fbreg -4)
DW_AT_name ("func1")
DW_AT_decl_file ("/root/Documents/llvm-compiler/ST_demo3/test/in/3-function.st")
DW_AT_decl_line (2)
DW_AT_type (0x00000096 "int")
0x0000003d: DW_TAG_formal_parameter
DW_AT_location (DW_OP_fbreg -2)
DW_AT_name ("var_2")
DW_AT_decl_file ("/root/Documents/llvm-compiler/ST_demo3/test/in/3-function.st")
DW_AT_decl_line (4)
DW_AT_type (0x00000096 "int")
0x00000048: NULL
我现在想知道我是否可以在运行时访问变量的地址?
您似乎在询问 local (又名自动)变量。这些变量位于距当前帧基址 (
fbreg
) 的偏移处,并且在运行时之前不有地址。
在运行时,确保您可以获得当前帧基地址(由于 ASLR,每次运行可能会有所不同),然后然后计算任何局部变量的位置(假设它有一个地址)。
此信息不存储在符号表中,仅存储在调试信息中。