Determining the BSS Size for an Object File

Wikipedia mentions that "the bss section usually includes all uninitialized variables declared in the file area." Given the following file:

int uninit; int main() { uninit = 1; return 0; } 

When I compile this with the executable, I see that the bss segment is correctly populated:

 $ gcc prog1.c -o prog1 $ size prog1 text data bss dec hex filename 1115 552 8 1675 68b prog1 

However, if I compile it as an object file, I cannot see the bss segment (I expect it to be 4):

 $ gcc -c prog1.c $ size prog1.o text data bss dec hex filename 72 0 0 72 48 prog1.o 

Is there something obvious that I'm missing?

I am using gcc version 4.8.1.

+7
c gcc linker
source share
1 answer

If we use readelf -s to view the character table, we will see:

 $ readelf -s prog1.o Symbol table '.symtab' contains 10 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS bss.c 2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 3: 0000000000000000 0 SECTION LOCAL DEFAULT 3 4: 0000000000000000 0 SECTION LOCAL DEFAULT 4 5: 0000000000000000 0 SECTION LOCAL DEFAULT 6 6: 0000000000000000 0 SECTION LOCAL DEFAULT 7 7: 0000000000000000 0 SECTION LOCAL DEFAULT 5 8: 0000000000000004 4 OBJECT GLOBAL DEFAULT COM uninit <<<< 9: 0000000000000000 16 FUNC GLOBAL DEFAULT 1 main 

We see that your uninit character ("variable") at this stage is a "common" character. He has not yet been "nominated" by the BSS.

See this question for more information on โ€œcommonโ€ characters: What does โ€œCOMโ€ mean in the Ndx column of a .symtab section?

Once your final executable is linked together, it will be placed in BSS, as you expected.


You can get around this behavior by passing the -fno-common flag to GCC:

 $ gcc -fno-common -c bss.c $ size bss.o text data bss dec hex filename 72 0 4 76 4c bss.o 

Instead, you can mark uninit as static . Thus, the compiler will know that no other .o file can reference it, so it will not be a โ€œcommonโ€ character. Instead, it will be placed in BSS immediately, as you expected:

 $ cat bss.c 
 static int uninit; int main() { uninit = 1; return 0; } 
 $ gcc -c bss.c $ size bss.o text data bss dec hex filename 72 0 4 76 4c bss.o 
+5
source share

All Articles