Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where are global variables located in the elf file

Tags:

c

linux

elf

I want to learn about elf files, but when I think of global variables, global static variables and scope static variables, I have some confusion. For example:

int a = 2;
int b;

static int c = 4;
static int d;

void fun(){
  static int e = 6;
  static int f;
}


int main(void){
   fun();
}

Who can tell which segment each variable belongs to? in my opinion, b, d and f belong to the .bss segment and a,c and e belong to the data segment, but I don't know the difference between global static variables and global variables in elf file.

like image 394
CrystalJake Avatar asked Jun 18 '13 02:06

CrystalJake


People also ask

Where are global variables located?

Global variables are stored in the data segment of memory. Local variables are stored in a stack in memory.

Where global variables are stored in microcontroller?

Code segments are stored in flash memory. The stack is located in RAM. Global variables are stored in flash or RAM, depending on whether they are writable.

Where are global and static variables stored in memory?

A data segment is a portion of the virtual address space of a program, which contains the global variables and static variables that are initialized by the programmer.

Where are globally allocated variables stored locally allocated?

All allocation made by malloc(), calloc() or realloc() are stored on the heap, while all local variables are stored on the stack. All global and static variables are stored in the data segment, while constants are stored in the code segment.


2 Answers

You can use objdump -t to view the symbol table:

$ objdump -t foo | grep -P '      \b(a|b|c|d|e|f)\b'
0000000000601034 l     O .data  0000000000000004              c
0000000000601040 l     O .bss   0000000000000004              d
0000000000601044 l     O .bss   0000000000000004              f.1710
0000000000601038 l     O .data  0000000000000004              e.1709
0000000000601048 g     O .bss   0000000000000004              b
0000000000601030 g     O .data  0000000000000004              a

You are right that b, d, and f are .bss while a, c, and e are .data. Whether the symbol is static or not is recorded in a separate flag of the symbol table—that’s the l or g flag in the second column.

The elf(5) man page says that these are recorded using the STB_LOCAL and STB_GLOBAL values for the st_info member of the symbol table. /usr/include/elf.h says that STB_GLOBAL is 1, while STB_LOCAL is 0. There is a macro ST_BIND to retrieve the binding bits of the st_info field.


There are tons of other flags for objdump—see the man page. objdump works with all architectures, but there is also an elfdump tool that does a bit better job of showing elf-specific stuff. objdump and the underlying BFD library can do a bad job of showing some file-format-specific data.

like image 107
andrewdotn Avatar answered Oct 20 '22 13:10

andrewdotn


In general, the data segment of the executable contains initialized global/static variables and the BSS segment contains uninitialized global/static variables.

When the loader loads your program into memory, the unitialized global/static variables are automatically zero-filled.

In C, static variables (initialized or not) inside a function just mean the variables have local/function scope (sometimes referred to as internal static), but they still live in the Data/BSS segments depending on whether or not they are initialized.

So regardless of how many times fun() gets called, the static variables are initilized only once when the program is loaded.

Variables defined as static and outside any functions still live in either the data or bss segments, but have file scope only.

When your code is compiled, there is an import and export list that is part of each object file and is used by the linkage editor. Your static variables will not be in the export list and therefore inaccessable to other object files.

By excluding the static keyword, your global variables are placed in the export list and can be referred to by other object modules and the linkage editor will be able to find the symbols when creating the executable.

For a pictoral view:

+--------- TEXT ---------+  Low memory
| main()                 |
| fun()                  |
+--------- DATA ---------+
| int a (global scope)   |
| int c (file scope)     |
| int e (function scope) |
+---------- BSS ---------+
| int b (global scope)   |
| int d (file scope)     |
| int f (function scope) |
+------------------------+
like image 31
ffhaddad Avatar answered Oct 20 '22 13:10

ffhaddad