day4- ldによるセクション配置の確認(readelf -S編)
[hirasawa@aspire-white gcc-Programming-Kobo]$ cat address.c #include <stdio.h> int a1; int a2 = 0x11111111; int a3; int a4 = 0x22222222; static int a5; static int a6 = 0x33333333; const char * a7 = "const_char_string"; void func( int b1 , int b2 ) { int c1; int c2 = 0x55555555; static int c3; static int c4 = 0x66666666; printf("func (&func) locates at %p\n",&func); printf("func (func) locates at %p\n",func); printf("f-argv-b1 %X locates at %p\n",b1,&b1); printf("f-argv-b2 %X locates at %p\n",b2,&b2); printf("f-auto-c1 %X locates at %p\n",c1,&c1); printf("f-auto-c2 %X locates at %p\n",c2,&c2); printf("f-static-int-NOTinit-c3 %X locates at %p\n",c3,&c3); printf("f-static-int-inited-c4 %X locates at %p\n",c4,&c4); printf("\n"); } int main(void) { printf("main (&main) locates at %p\n",&main); printf("main (main) loaates at %p\n",main); printf("m-a1 %X loaates at %p\n",a1,&a1); printf("m-a2 %X loaates at %p\n",a2,&a2); printf("m-a3 %X loaates at %p\n",a3,&a3); printf("m-a4 %X loaates at %p\n",a4,&a4); printf("m-a5 %X loaates at %p\n",a5,&a5); printf("m-a6 %X loaates at %p\n",a6,&a6); printf("m-a7 %p loaates at %p\n",a7,&a7); printf("*(m-a7) %s loaates at %p\n",a7,a7); printf("\n"); func(1,2); return 0; } [hirasawa@aspire-white gcc-Programming-Kobo]$ gcc -Wall -save-temps -o address address.c [hirasawa@aspire-white gcc-Programming-Kobo]$ ./address | sort -k5 func (&func) locates at 0x80483f4 func (func) locates at 0x80483f4 main (&main) locates at 0x80484e3 main (main) loaates at 0x80484e3 *(m-a7) const_char_string loaates at 0x8048700 m-a2 11111111 loaates at 0x804a018 m-a4 22222222 loaates at 0x804a01c m-a6 33333333 loaates at 0x804a020 m-a7 0x8048700 loaates at 0x804a024 f-static-int-inited-c4 66666666 locates at 0x804a028 m-a5 0 loaates at 0x804a034 f-static-int-NOTinit-c3 0 locates at 0x804a038 m-a3 0 loaates at 0x804a03c m-a1 0 loaates at 0x804a040 f-auto-c2 55555555 locates at 0xbfa3cc58 f-auto-c1 26CFF4 locates at 0xbfa3cc5c f-argv-b1 1 locates at 0xbfa3cc70 f-argv-b2 2 locates at 0xbfa3cc74 [hirasawa@aspire-white gcc-Programming-Kobo]$ [hirasawa@aspire-white gcc-Programming-Kobo]$
readelf -Sで確認
[hirasawa@aspire-white gcc-Programming-Kobo]$ readelf -S address | grep -E "text|data|rodata|bss" [13] .text PROGBITS 08048340 000340 00039c 00 AX 0 0 16 [15] .rodata PROGBITS 080486f8 0006f8 00020b 00 A 0 0 4 [23] .data PROGBITS 0804a010 001010 00001c 00 WA 0 0 4 [24] .bss NOBITS 0804a02c 00102c 000018 00 WA 0 0 4 [hirasawa@aspire-white gcc-Programming-Kobo]$
address | sort -k5 と readelf -Sの結果を重ねあわせてみると
[13] .text PROGBITS 08048340 000340 00039c 00 AX 0 0 16 func (&func) locates at 0x80483f4 func (func) locates at 0x80483f4 main (&main) locates at 0x80484e3 main (main) loaates at 0x80484e3
ちなみに、32ビットのELF形式のプログラムの格納開始アドレス(_start kana?)
は0x08048000
開始アドレスを起点に上位に向かって関数などが配置されるんですな
[15] .rodata PROGBITS 080486f8 0006f8 00020b 00 A 0 0 4 *(m-a7) const_char_string loaates at 0x8048700
.dataと.rodataはともにWフラッグがついていないので、readonly。
[23] .data PROGBITS 0804a010 001010 00001c 00 WA 0 0 4 m-a2 11111111 loaates at 0x804a018 m-a4 22222222 loaates at 0x804a01c m-a6 33333333 loaates at 0x804a020 m-a7 0x8048700 loaates at 0x804a024 f-static-int-inited-c4 66666666 locates at 0x804a028
.dataと.bssは隣合わせですね。
どっちもWAフラッグがたってるし、ひとつにまとめてもいいんぢゃない、と考えるが、
初期化、非初期化変数の区別を付けてる理由は、
実行ファイルがメモリ上にロードされる際に、カーネルがヘッダー情報にしたがって、.bssセクション全体を初期化する、ってだそうです。
なるほど
[24] .bss NOBITS 0804a02c 00102c 000018 00 WA 0 0 4 m-a5 0 loaates at 0x804a034 f-static-int-NOTinit-c3 0 locates at 0x804a038 m-a3 0 loaates at 0x804a03c m-a1 0 loaates at 0x804a040
こっからスタックになるんですな
いわゆるAuto変数
f-auto-c2 55555555 locates at 0xbfa3cc58 f-auto-c1 26CFF4 locates at 0xbfa3cc5c f-argv-b1 1 locates at 0xbfa3cc70 f-argv-b2 2 locates at 0xbfa3cc74
0xC0000000から上位のアドレスはLinuxのカーネルプロセス空間であり、
オート変数は、ユーザープロセス空間の中だが、境界ぎりぎりの所に
配置されてることになる。
こっちは、下位アドレスにむかって伸びていくんですな
つまり、
void func( int b1 , int b2 )
{
int c1;
int c2 = 0x55555555;
をcallする際には、b2,b1,c1,c2の順番で下アドレスに向かって成長。