Home > Mobile >  BSS vs DATA segment in memory
BSS vs DATA segment in memory

Time:06-02

//Global space
int A;
int B = 0;
int C = 0x01;
static int D;
static int E = 0;
static int F = 0x01;

void foo()
{
    static int G;
    static int H = 0;
    static int I = 0x01;
}

My understanding is that all global & static variables that are either not initialized explicitly or initialized to 0 would go into BSS section. All the global & static variables that are initialized with any valu other than 0 would go into DATA section. Am I right?

In this case, following would be correct.

A -- BSS (No Explicit init)
B -- BSS (init to 0)
C -- DATA (!= 0)
D -- BSS
E -- BSS
F -- DATA
G -- BSS
H -- BSS
I -- DATA

Please correct me or acknowledge me. Thanks in advance.

CodePudding user response:

In C every object with static storage duration IS initialized. If you don't write an explicit initializer it is implicitly initialized to zero. Only objects with automatic storage (on the stack) are truly uninitialized.

This is from the compiler's point of view. If you choose to edit the linker script you can obviously get different results. A normal linker script will do the following:

Most compilers will put C, F and I in .data.

Most compilers will put B, D, E, G and H in .bss.

The only funny one is A; many compilers will put it in COMMON.

GCC with the option -fno-common will put A in .bss.

This option is turned on by default in recent versions of GCC on some platforms.

CodePudding user response:

1.Env.: *nix, gcc compiler, ELF (Executable and Linkable Format) binary

2.Code: According to your code, here's a way to display their runtime addresses:

#include <stdio.h>

//Global space
int A;
int B = 0;
int C = 0x01;
static int D;
static int E = 0;
static int F = 0x01;

void foo()
{
    static int G;
    static int H = 0;
    static int I = 0x01;
    printf("G    : 8p\n",(void *) &G);
    printf("H    : 8p\n",(void *) &H);
    printf("I    : 8p\n",(void *) &I);
}

int main(int argc, char* argv[]) {
    printf("A    : 8p\n",(void *) &A);
    printf("B    : 8p\n",(void *) &B);
    printf("C    : 8p\n",(void *) &C);
    printf("D    : 8p\n",(void *) &D);
    printf("E    : 8p\n",(void *) &E);
    printf("F    : 8p\n",(void *) &F);

    foo();

    return 0;
}

3.Reminder:

ELF section to segment mapping: in ELF, BSS and Data sections will be mapped to the same memory segment :

Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp 
   02     .interp .note.tag .hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 
   03     .ctors .dtors .dynamic .got.plt .data .bss 
   04     .dynamic 
   05     .note.tag 
   06     .eh_frame_hdr 
   07     

As you see above, the .data and .bss sections will be mapped to the segment #3

4.ELF Symtab

From the code above from 2., we compile it through gcc on *nix OS and we can see in the ELF binary (table below is sorted on the Value field):

Symbol table (.symtab) contains 56 entries:
   Num: Value             Size Type    Bind   Vis      Ndx Name
   ---- ---------------- ----- ------- ------ -------- --- -------------------- 
    24: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crt1_c.c
     4: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    13: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    17: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS mmap.c
    55: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _init_tls@FBSD_1.0
    36: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND atexit@FBSD_1.0
    49: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND exit@FBSD_1.0
    43: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND printf@FBSD_1.0
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
    54: 0000000000400408     0 FUNC    GLOBAL HIDDEN     9 _init
    32: 0000000000400408     0 NOTYPE  LOCAL  DEFAULT    8 __rela_iplt_end
    29: 0000000000400408     0 NOTYPE  LOCAL  DEFAULT    8 __rela_iplt_start
    48: 0000000000400470   263 FUNC    GLOBAL DEFAULT   11 _start
     3: 0000000000400580   283 FUNC    LOCAL  DEFAULT   11 handle_static_init
     2: 00000000004006a0    91 FUNC    LOCAL  DEFAULT   11 finalizer
     7: 0000000000400700     0 FUNC    LOCAL  DEFAULT   11 deregister_tm_clones
     8: 0000000000400730     0 FUNC    LOCAL  DEFAULT   11 register_tm_clones
     9: 0000000000400770     0 FUNC    LOCAL  DEFAULT   11 __do_global_dtors_aux
    12: 00000000004007f0     0 FUNC    LOCAL  DEFAULT   11 frame_dummy
    44: 00000000004007f5    67 FUNC    GLOBAL DEFAULT   11 foo
    51: 0000000000400838   152 FUNC    GLOBAL DEFAULT   11 main
    16: 00000000004008d0     0 FUNC    LOCAL  DEFAULT   11 __do_global_ctors_aux
    39: 0000000000400914     0 FUNC    GLOBAL HIDDEN    12 _fini
    34: 00000000004009a4     0 NOTYPE  LOCAL  DEFAULT   14 __GNU_EH_FRAME_HDR
    15: 0000000000400a48     0 OBJECT  LOCAL  DEFAULT   15 __FRAME_END__
    25: 0000000000600a4c     0 NOTYPE  LOCAL  DEFAULT   16 __fini_array_end
    30: 0000000000600a4c     0 NOTYPE  LOCAL  DEFAULT   16 __fini_array_start
    28: 0000000000600a4c     0 NOTYPE  LOCAL  DEFAULT   16 __init_array_end
    33: 0000000000600a4c     0 NOTYPE  LOCAL  DEFAULT   16 __init_array_start
    27: 0000000000600a4c     0 NOTYPE  LOCAL  DEFAULT   16 __preinit_array_end
    26: 0000000000600a4c     0 NOTYPE  LOCAL  DEFAULT   16 __preinit_array_start
     5: 0000000000600a50     0 OBJECT  LOCAL  DEFAULT   16 __CTOR_LIST__
    14: 0000000000600a58     0 OBJECT  LOCAL  DEFAULT   16 __CTOR_END__
     6: 0000000000600a60     0 OBJECT  LOCAL  DEFAULT   17 __DTOR_LIST__
    41: 0000000000600a68     0 OBJECT  GLOBAL HIDDEN    17 __DTOR_END__
    31: 0000000000600a70     0 OBJECT  LOCAL  DEFAULT   18 _DYNAMIC
    35: 0000000000600bd0     0 OBJECT  LOCAL  DEFAULT   19 _GLOBAL_OFFSET_TABLE_
    53: 0000000000600c08     8 OBJECT  GLOBAL DEFAULT   20 __progname
    42: 0000000000600c10     0 OBJECT  GLOBAL HIDDEN    20 __dso_handle
    45: 0000000000600c18     4 OBJECT  GLOBAL DEFAULT   20 C
    20: 0000000000600c1c     4 OBJECT  LOCAL  DEFAULT   20 F
    23: 0000000000600c20     4 OBJECT  LOCAL  DEFAULT   20 I.0
    38: 0000000000600c24     0 NOTYPE  GLOBAL DEFAULT   20 _edata
    50: 0000000000600c24     0 NOTYPE  GLOBAL DEFAULT   21 __bss_start
    52: 0000000000600c28     0 OBJECT  GLOBAL HIDDEN    20 __TMC_END__
    40: 0000000000600c28     8 OBJECT  GLOBAL DEFAULT   21 environ
    10: 0000000000600c30     1 OBJECT  LOCAL  DEFAULT   21 completed.1
    11: 0000000000600c38     8 OBJECT  LOCAL  DEFAULT   21 dtor_idx.0
    46: 0000000000600c40     4 OBJECT  GLOBAL DEFAULT   21 A
    37: 0000000000600c44     4 OBJECT  GLOBAL DEFAULT   21 B
    18: 0000000000600c48     4 OBJECT  LOCAL  DEFAULT   21 D
    19: 0000000000600c4c     4 OBJECT  LOCAL  DEFAULT   21 E
    21: 0000000000600c50     4 OBJECT  LOCAL  DEFAULT   21 G.2
    22: 0000000000600c54     4 OBJECT  LOCAL  DEFAULT   21 H.1
    47: 0000000000600c58     0 NOTYPE  GLOBAL DEFAULT   21 _end

As you see:

  • data contains C, F and I
  • bss contains A, B, D, E, G and H

5.Answer:

It seems your assumption is correct.

  • Related