Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where do I find the assembly that creates a static variable in the .data section of my C program?

First time poster. 2nd year CS student.

I am exploring the creation of static variables in the .data section of the Virtual Address Space in the context of a C source->GCC compilation->Linux execution environment.

C program is test.c

int main()
{
   register int i = 0;
   register int sum = 0;
   static int staticVar[10] = {1,2,3,4,5,6,7,8,9,-1};
   Loop: 
        sum = sum + staticVar[i]; //optimized away
    i = i+1;
    if(i != 10)
    goto Loop; 
   return 0;
 }

Asking GDB to 'disass /m' reveals that there is no code for the staticVar[] creation because inspecting the .s file reveals the variable resides in the read/write .data segment of the virtual address space having been placed there at the time of process creation(this process is what I'm interested in).

Examining the output of (I though it was 'readelf -A test.o') the object file contains assembly for what I assume is the creation of the array in the data segment. Here is the ELF output.

(Bonus if you can tell me what command generates this output. I can not duplicate it using readelf. I picked up the command off a website and saved output. I cant remember how generated)

[snip]

    00000000 <staticVar.1359>:
   0:01 00                  add    %eax,(%eax)
   2:00 00                  add    %al,(%eax) 
   4:02 00                  add    (%eax),%al
   6:00 00                  add    %al,(%eax)
   8:03 00                  add    (%eax),%eax
   a:00 00                  add    %al,(%eax)
   c:04 00                  add    $0x0,%al
   e:00 00                  add    %al,(%eax)
  10:05 00 00 00 06         add    $0x6000000,%eax
  15:00 00                  add    %al,(%eax)
  17:00 07                  add    %al,(%edi)
  19:00 00                  add    %al,(%eax)
  1b:00 08                  add    %cl,(%eax)
  1d:00 00                  add    %al,(%eax)
  1f:00 09                  add    %cl,(%ecx)
  21:00 00                  add    %al,(%eax)
  23:00 ff                  add    %bh,%bh
  25:ff                     (bad)  
  26:ff                     (bad)  
  27:ff                     .byte 0xff

[snip]

Assumptions(please correct): This assembly exists in the executable and is run by load_elf_binary(), or some part of the execve() initiated series of functions. I have no at&t (basic intel) syntax knowledge but even intuitively I dont see how these instructions can build an array. Looks like they are just adding register values together.

Bottom Line: I would like to know as much as possible about the life cycle of this static array especially where is the "missing code" that builds it and how can I look at it? Or better yet how can I debug (step through) the loader process? I have tried setting a breakpoint before main at the __start_libc entry (or something like that) but could not identify anything promising in this area.

Links to additional info are great! Thanks for your time!

like image 520
phraxOS Avatar asked Sep 03 '13 00:09

phraxOS


People also ask

Where are static variables stored in C?

The static variables are stored in the data segment of the memory. The data segment is a part of the virtual address space of a program. All the static variables that do not have an explicit initialization or are initialized to zero are stored in the uninitialized data segment( also known as the BSS segment).

What does .data do in assembly?

data) are used to identify sections of an assembly language program. The last two (. data and . word) are used to declare and initialize variables.

Where are static variables declared?

Class variables also known as static variables are declared with the static keyword in a class, but outside a method, constructor or a block. There would only be one copy of each class variable per class, regardless of how many objects are created from it.

Where are initialized static variables stored?

When the program (executable or library) is loaded into memory, static variables are stored in the data segment of the program's address space (if initialized), or the BSS segment (if uninitialized), and are stored in corresponding sections of object files prior to loading.


1 Answers

The initializers for staticVar is stored in the .data section of the executable. Using objdump (e.g. How can I examine contents of a data section of an ELF file on Linux?) should reveal something like this for your file:

./test:     file format elf64-x86-64

Contents of section .data:
 00d2c0 00000000 00000000 00000000 00000000  ................
 00d2d0 00000000 00000000 00000000 00000000  ................
 00d2e0 01000000 02000000 03000000 04000000  ................
 00d2f0 05000000 06000000 07000000 08000000  ................
 00d300 09000000 ffffffff 00000000 00000000  ................
 00d310 00000000 00000000 00000000 00000000  ................

That content from the executable is directly mapped into the address space of your process, so there is no need for any code to create the data. Codes that operate on staticVar will refer to the content directly using memory pointers; e.g. for the loop you posted, gcc -S gave me this:

  18                .L5:
  19 0013 90            nop
  20                .L2:
  21 0014 4863C3        movslq  %ebx, %rax
  22 0017 8B148500      movl    staticVar.1707(,%rax,4), %edx
  22      000000
  23 001e 8B45F4        movl    -12(%rbp), %eax
  24 0021 01D0          addl    %edx, %eax
  25 0023 8945F4        movl    %eax, -12(%rbp)
  26 0026 83C301        addl    $1, %ebx
  27 0029 83FB0A        cmpl    $10, %ebx
  28 002c 75E5          jne .L5

Lifetime of this static array would be the lifetime of your process, similar to a global variable. In any case, there is no code that builds it. It's just some data in memory.

P/S: You may need to add volatile to sum like such: volatile int sum = 0; Otherwise gcc would probably optimize it away since the resulting value of sum is never used.

like image 86
James Chong Avatar answered Sep 27 '22 16:09

James Chong