I'm trying to understand how does symbol tables relate to the .data section in ELF. First some assumptions that I'm using as ground to start with.

A symbol is a human readable (or "as written in the source file") representation of a function or a variable that is mapped to the actual binary value (that the CPU operates on) of that.

Here is an example

int var_global_init = 5;

int main(void)
  return 0;

Let's build it and examine the binary:

$ gcc simple.c -o simple
$ objdump -t simple | grep var_global_init
  0000000000201010 g     O .data  0000000000000004              var_global_init

It lists the symbol in the .data section of the ELF file. Page 20 of the ELF documentation defines the .data section as:

These sections hold initialized data that contribute to the program's memory image.

Ok, that kind of fits. So then I ask myself Does this mean that the symbol table is embedded in the .data section?. But that seems to be disproved by the exmple below:

$ readelf -s simple
  Symbol table '.symtab' contains 66 entries:
  50: 0000000000201010     4 OBJECT  GLOBAL DEFAULT   23 var_global_init

readelf shows that there is a dedicated .symtab section in the ELF that holds the symbol.

Does the .data section need the actual symbol table. The first example points to concluding that there is one in the data section, but shouldn't it be able to execute just the binary values?

By checking hexdump I was able to detect only a single entry, so either I got the concepts wrong or some of them is lying. :)

  • Note, though it doesnt help in this case, you may sometimes like to look at the intermediate generated assembler code to see how things work. Compile with gcc -g -Wa,-alhnd=mylist simple.c and you will get in file mylist an assembler listing with the original C code mixed in.
    – meuh
    Mar 26, 2018 at 8:18

1 Answer 1


The .data section contains the data itself, i.e. the four bytes which hold the int value 5. The .symtab section contains the symbols, i.e. the names given to various parts of the binary; the var_global_init symbol name points to the four bytes of storage in the .data section.

That’s why you only see one entry: there is only one symbol, in the symbol table. But you do need both sections if you want to go from a name to a value: the symbol table tells you where to find the value corresponding to the var_global_init symbol, and the data section contains the storage for the value.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .