Code:
//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);
}
Compile:
$ gcc -fPIC -o test test.c
Run: (not important)
$ ./test v_flag = 51914, &v_flag=0x601034 v_flag = 51915
Read symbol tables:
$ gcc --version gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-8) ... $ ld --version GNU ld version 2.23.52.0.1-16.el7 20130226 ... $ readelf -s test Symbol table '.dynsym' contains 4 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2) 2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2) 3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ Symbol table '.symtab' contains 65 entries: Num: Value Size Type Bind Vis Ndx Name ... 58: 0000000000601048 0 NOTYPE GLOBAL DEFAULT 25 _end 59: 0000000000400450 0 FUNC GLOBAL DEFAULT 13 _start 60: 0000000000601038 0 NOTYPE GLOBAL DEFAULT 25 __bss_start 61: 0000000000400514 89 FUNC GLOBAL DEFAULT 13 main 62: 0000000000601034 4 OBJECT GLOBAL DEFAULT 24 v_flag ...
Question 1: Why the global variable v_flag appears in symtab, but not in dynsym? (note: disable optimizations "-O0" does not help)
Following up Question 1, adding "-rdynamic" flag will make v_flag (and also others) appear in dynsym:
$ gcc -rdynamic -o test test.c $ readelf -s test Symbol table '.dynsym' contains 18 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2) 2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2) 3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ ... 11: 0000000000400670 0 FUNC GLOBAL DEFAULT 13 _start 12: 0000000000601038 0 NOTYPE GLOBAL DEFAULT 25 __bss_start 13: 0000000000400734 89 FUNC GLOBAL DEFAULT 13 main 14: 0000000000400600 0 FUNC GLOBAL DEFAULT 11 _init 15: 0000000000400800 2 FUNC GLOBAL DEFAULT 13 __libc_csu_fini 16: 0000000000400848 0 FUNC GLOBAL DEFAULT 14 _fini 17: 0000000000601034 4 OBJECT GLOBAL DEFAULT 24 v_flag Symbol table '.symtab' contains 65 entries: ...
However, according to the man page
-rdynamic Pass the flag -export-dynamic to the ELF linker, on targets that support it. This instructs the linker to add all symbols, not only used ones, to the dynamic symbol table.
Hence, question 2, can we say that v_flag is unused (hence it does not appear in dynsym)? If so, why?
Update 1:
This issue does not show up in ld version 2.20.* (Thank Konstantin Vladimirov for pointing out this).