Meditation, The Art of Exploitation

Thinking? At last I have discovered it--thought; this alone is inseparable from me. I am, I exist--that is certain. But for how long? For as long as I am thinking. For it could be, that were I totally to cease from thinking, I should totally cease to exist....I am, then, in the strict sense only a thing that thinks.

Friday, December 15, 2006

C/C++ local and global static variables

There appears to be some confusion in people's mind how static variables operate. Quote from CLC++:

The implication of this is that the compiler has to generate
a hidden static flag to prevent re-initialization, and that flag
has to be checked every time control passes the local static
definition.The implication of this is that the compiler has to generate
a hidden static flag to prevent re-initialization, and that flag
has to be checked every time control passes the local static
definition.

As will be demonstrated by the following code, local static variables are usualy implemented exactly the same as global static variables,

# more static_t.c
static int si;

void foo(int x){
static int z;
z = z + x;
si = x;
return;
}

#gcc -c static_t.c
[feiliu@maple c]$ objdump -d static_t1a.o

static_t1a.o: file format elf32-i386

Disassembly of section .text:

00000000 :
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: a1 00 00 00 00 mov 0x0,%eax <------------ RELOCATABLE RECORD
8: 03 45 08 add 0x8(%ebp),%eax
b: a3 00 00 00 00 mov %eax,0x0 <------------ RELOCATABLE RECORD
10: 8b 45 08 mov 0x8(%ebp),%eax
13: a3 04 00 00 00 mov %eax,0x4 <------------ RELOCATABLE RECORD
18: 5d pop %ebp
19: c3 ret
[feiliu@maple c]$ objdump -x static_t1a.o

static_t1a.o: file format elf32-i386
static_t1a.o
architecture: i386, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000001a 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000000 00000000 00000000 00000050 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000008 00000000 00000000 00000050 2**2
ALLOC
3 .comment 0000002d 00000000 00000000 00000050 2**0
CONTENTS, READONLY
4 .note.GNU-stack 00000000 00000000 00000000 0000007d 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00000000 l df *ABS* 00000000 static_t1a.c
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l O .bss 00000004 z.1281
00000004 l O .bss 00000004 si
00000000 l d .note.GNU-stack 00000000 .note.GNU-stack
00000000 l d .comment 00000000 .comment
00000000 g F .text 0000001a foo


RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
00000004 R_386_32 .bss
0000000c R_386_32 .bss
00000014 R_386_32 .bss

The compiler has generated identical machine code for the both global and static variables and the relocatable records indicate that their storage segment is .bss segment. Refer to a previous article on this subject about how static variables are implemented by compilers/linkers.