understanding storage class using nm
TRANSCRIPT
Prepared by Mohammed Sikander Technical Lead Cranes Software International Limited
int g_var = 5; int main( ) { int l_var = 8; }
00000000 D g_var 00000000 T main
• Symbol table does not contain the entries of local/automatic variables. • gl is stored in Initialized Data Segment • main is stored in Text / Code Segment
int global = 5; static int stglobal = 9; int main( ) { int local = 8; static int stlocal = 3; }
00000000 D global
00000000 T main
00000004 d stglobal
00000008 d stlocal.0
• d stands for Internal Linkage
• External variables will not have any
name mangling.
• Internal Linkage variables might have
name mangling.
1. Can we have two static variables with same name but different functions.
2. What is the memory segment of x.
3. How does the compiler avoid name clashes.
void print( ) { static int x = 5; } void display( ) { static int x = 8; } int main( ) { }
00000005 T display 0000000a T main 00000000 T print 00000000 d x.0 00000004 d x.1
Compiler uses different names for x.
int x = 5; int main( ) { int x = 10; printf(“x = %d \n “ , x); }
static int x = 5; int main( ) { static int x = 10; { static int x = 12; printf(“x = %d \n “ , x); } }
FILE1.C
int x = 5; void func( ); int main( ) { func( ); }
FILE2.C
int x = 8; void func( ) { printf(" x = %d \n" , x); }
• Compile file1.c • Compile file2.c • Link file1.o and file2.o • Observe the output
• [sikander@localhost nm]$ gcc file1.c -c • [sikander@localhost nm]$ gcc file2.c –c • [sikander@localhost nm]$ gcc file1.o file2.o • file2.o(.data+0x0): multiple definition of `x' • file1.o(.data+0x0): first defined here • collect2: ld returned 1 exit status
[sikander@localhost nm]$ nm file1.o U func 00000000 T main 00000000 D x [sikander@localhost nm]$ nm file2.o 00000000 T func U printf 00000000 D x
FILE1.C
static int x = 5; void func( ); int main( ) { printf(__func__ ); printf(" x = %d \n",x); func( ); }
FILE2.C
static int x = 8; void func( ) { printf("%s x = %d \n" ,__func__ , x); }
• Compile file1.c • Compile file2.c • Link file1.o and file2.o • Observe the output
• $ gcc -c file1.c • $ gcc -c file2.c • $ gcc file1.o file2.o • $ ./a.out • main x = 5 • func x = 8
$ nm file1.o U func 00000000 r __func__.0 00000000 T main U printf 00000000 d x
$ nm file2.o 00000000 T func 00000000 r __func__.0 U printf 00000000 d x
080495dc d x 080495e0 d x
FILE1.C
int x = 5; void func( ); int main( ) { printf(__func__ ); printf(" x = %d \n",x); func( ); }
FILE2.C
extern int x; void func( ) { printf("%s x = %d \n" ,__func__ , x); }
• Compile file1.c • Compile file2.c • Link file1.o and file2.o • Observe the output
FILE1.C
int x = 5; void func( ); int main( ) { printf(__func__ ); printf(" x = %d \n",x); func( ); }
FILE2.C
extern int x; void func( ) { printf("%s x = %d \n" ,__func__ , x); }
• Compile file1.c • Compile file2.c • Link file1.o and file2.o • Observe the output
• $ gcc -c file1.c • $ gcc -c file2.c • $ gcc file1.o file2.o • $ ./a.out main x = 5 &x = 0x8049618 func x = 5 &x = 0x8049618
]$ nm file1.o U func 00000000 r __func__.0 00000000 T main U printf
00000000 D x
]$ nm file2.o 00000000 T func 00000000 r __func__.0 U printf
U x
$nm a.out 08049618 D x
FILE1.C
static int x = 5; void func( ); int main( ) { printf(__func__ ); printf(" x = %d \n",x); func( ); }
FILE2.C
extern int x; void func( ) { printf("%s x = %d \n" ,__func__ , x); }
• Compile file1.c • Compile file2.c • Link file1.o and file2.o • Observe the output
• $ gcc -c file1.c • $ gcc -c file2.c • $ gcc file1.o file2.o • file2.o(.text+0xb): In function `func': • : undefined reference to `x‘ • collect2: ld returned 1 exit status
]$ nm file1.o U func 00000000 r __func__.0 00000000 T main U printf
00000000 d x
]$ nm file2.o 00000000 T func 00000000 r __func__.0 U printf
U x
static int x = 5; int main( ) { int x; printf(“x = %d \n”,x); }
static int x = 5; int main( ) { extern int x; printf(“x = %d \n”,x); }
int a = 5; int b; static int c = 7; static int d; int main( ) { }
• Mention the memory segments of variables after compiling (.o file) and after linking (a.out) • What is the difference between a and c. • Use nm utility to view the memory segments $gcc –c file.c $nm file.o $gcc file.c $nm ./a.out
$ gcc file.c -c $ nm file.o 00000000 D a 00000004 C b 00000004 d c 00000000 b d 00000000 T main
•“C” The symbol is common.
• Common symbols are uninitialized
data.
• When linking, multiple common
symbols may appear with the same
name.
• If the symbol is defined anywhere, the
common symbols are treated as
undefined references. $ nm a.out 08049534 D a 08049544 B b 08049538 d c 08049540 b d
int x ; int main( ) { printf(“Main &x= %p” , &x); printf(“x = %d \n”, x); func( ); }
int x ; void func( ) { printf(“Func &x= %p” , &x); printf(“x = %d \n”, x); }
$ nm file1.o U func 00000000 T main U printf 00000004 C x
]$ nm file2.o 00000000 T func U printf 00000004 C x
$nm a.out 08049600 B x
int x ; int main( ) { printf(“Main &x= %p” , &x); printf(“x = %d \n”, x); func( ); }
int x = 5 ; void func( ) { printf(“Func &x= %p” , &x); printf(“x = %d \n”, x); }
$ nm file2.o 00000000 T func U printf 00000000 D x
$ nm file1.o U func 00000000 T main U printf 00000004 C x
$nm a.out 08049600 D x
C C
B
C D
D
D D
Multiple Definition
d d
No Conflict, two different variables
b b
No Conflict, two different variables
d b
No Conflict, two different variables
b d
No Conflict, two different variables
b D
No Conflict, two different variables
void func( ); int x = 5; //D int main( ) { printf(“Main &x= %p” , &x); printf(“x = %d \n”, x); func( ); }
int x = 10; //D void func( ) { printf(“Func &x= %p” , &x); printf(“x = %d \n”, x); }
void func( ); static int x = 5; //d int main( ) { printf(“Main &x= %p” , &x); printf(“x = %d \n”, x); func( ); }
int x = 10; //D void func( ) { printf(“Func &x= %p” , &x); printf(“x = %d \n”, x); }
const int gc = 10; static const int gsc = 12; int main( ) { const int lc = 5; static const int lsc = 8; }
00000000 R gc 00000004 r gsc 00000008 r lsc.0 00000000 T main
const int gc = 15; //Read Only int main( ) { const int lc = 5; //Stack printf(“Enter the value for local const variable : “); scanf(“ %d”,&lc); printf(“Local Const = %d \n” , lc); printf(“Enter the value for global const variable : “); scanf(“ %d”,&gc); printf(“Global Const = %d \n”,gc); }
[sikander@localhost ~]$ ./a.out Enter the value for local const variable : 89 Local Const = 89 Enter the value for global const variable : 6 Segmentation fault
[sikander@localhost ~]$ nm f1.o 00000000 t display 0000000a T main 00000005 T print
static void display() { } void print() { } int main( ) { display( ); print( ); }
For any queries and feedback Mail to [email protected] [email protected]