title: GCC: why global variable missing in dynamic symbol table?
body: <p>Code:</p>
  
  <pre><code>//test.c
  #include &lt;stdio.h&gt;
  int v_flag = 0xCACA;
  
  void main(int argc, char* argv[]){
    printf("v_flag = %d, &amp;v_flag=%p \n", v_flag, &amp;v_flag);
    v_flag++;
    printf("v_flag = %d\n", v_flag);
  
  }
  </code></pre>
  
  <p>Compile:</p>
  
  <pre><code>$ gcc -fPIC -o test test.c
  </code></pre>
  
  <p>Run: (not important)</p>
  
  <pre>
  $ ./test
  
  v_flag = 51914, &v_flag=0x601034
  v_flag = 51915
  
  </pre>
  
  <p>Read symbol tables:</p>
  
  <pre>
  
  $ 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
                              ...
  
  </pre>
  
  <p><strong>Question 1</strong>: Why the global variable <em>v_flag</em> appears in <em>symtab</em>, but not in <em>dynsym</em>? (note: disable optimizations "-O0" does not help)</p>
  
  <p>Following up Question 1, adding "<em>-rdynamic</em>" flag will make <em>v_flag</em> (and also others) appear in <em>dynsym</em>:</p>
  
  <pre>
  
  $ 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:
                              ...
  </pre>
  
  <p>However, according to the man page</p>
  
  <pre>
  
  -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.
  
  </pre>
  
  <p>Hence, <strong>question 2</strong>, can we say that <em>v_flag</em> is <strong>unused</strong> (hence it does not appear in <em>dynsym</em>)? If so, why?</p>
  
  <p><strong>Update 1:</strong></p>
  
  <p>This issue does not show up in ld version 2.20.* (Thank Konstantin Vladimirov for pointing out this).</p>