【发布时间】:2015-05-31 11:56:10
【问题描述】:
代码:
//test.c
#include <stdio.h>
int v_flag = 0xCACA;
void main(int argc, char* argv[]){
printf("v_flag = %d, &v_flag=%p \n", v_flag, &v_flag);
v_flag++;
printf("v_flag = %d\n", v_flag);
}
编译:
$ gcc -fPIC -o test test.c
运行:(不重要)
$ ./测试 v_flag = 51914, &v_flag=0x601034 v_flag = 51915读取符号表:
$ gcc --版本 gcc (GCC) 4.4.7 20120313 (红帽 4.4.7-8) ... $ ld --版本 GNU ld 版本 2.23.52.0.1-16.el7 20130226 ... $ readelf -s 测试 符号表“.dynsym”包含 4 个条目: Num:值大小类型绑定 Vis Ndx 名称 0: 0000000000000000 0 NOTYPE 本地默认值 1: 0000000000000000 0 FUNC 全局默认值和 printf@GLIBC_2.2.5 (2) 2:0000000000000000 0 FUNC 全局默认值和 __libc_start_main@GLIBC_2.2.5 (2) 3:0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ 符号表 '.symtab' 包含 65 个条目: Num:值大小类型绑定 Vis Ndx 名称 ... 58: 0000000000601048 0 NOTYPE 全球默认值 25 _end 59: 0000000000400450 0 FUNC 全局默认值 13 _start 60: 0000000000601038 0 NOTYPE 全局默认值 25 __bss_start 61: 0000000000400514 89 FUNC 全局默认值 13 主要 62: 0000000000601034 4 对象全局默认值 24 v_flag ...问题1:为什么全局变量v_flag出现在symtab中,而不出现在dynsym中? (注意:禁用优化“-O0”没有帮助)
跟进问题1,添加“-rdynamic”标志将使v_flag(以及其他)出现在dynsym中:
$ gcc -rdynamic -o 测试 test.c $ readelf -s 测试 符号表 '.dynsym' 包含 18 个条目: Num:值大小类型绑定 Vis Ndx 名称 0: 0000000000000000 0 NOTYPE 本地默认值 1: 0000000000000000 0 FUNC 全局默认值和 printf@GLIBC_2.2.5 (2) 2:0000000000000000 0 FUNC 全局默认值和 __libc_start_main@GLIBC_2.2.5 (2) 3:0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ ... 11:0000000000400670 0 FUNC 全局默认值 13 _start 12:0000000000601038 0 NOTYPE 全局默认值 25 __bss_start 13:0000000000400734 89 FUNC 全局默认值 13 主要 14:0000000000400600 0 FUNC 全局默认值 11 _init 15:0000000000400800 2 FUNC 全局默认值 13 __libc_csu_fini 16:0000000000400848 0 FUNC 全局默认值 14 _fini 17:0000000000601034 4 对象全局默认值 24 v_flag 符号表 '.symtab' 包含 65 个条目: ...但是,根据手册页
-r动态 在支持它的目标上将标志 -export-dynamic 传递给 ELF 链接器。这指示链接器将所有符号(不仅是使用的符号)添加到动态符号表中。因此,问题 2,我们可以说 v_flag 未使用(因此它没有出现在 dynsym)?如果有,为什么?
更新 1:
这个问题在 ld 版本 2.20 中没有出现。*(感谢 Konstantin Vladimirov 指出这一点)。
【问题讨论】: