env: in 32bit linux, 64 bit 似乎有點不同??
在沒有 os 的環境下搞懂 bss 有點麻煩嗎?這次提供在 os 環境下, 看看 bss。
首先找出 bss 開始和結束的地方。先來看看 default linker script。
ld --verbose
1 GNU ld (GNU Binutils for Debian) 2.22
2 Supported emulations:
3 elf_i386
4 i386linux
5 elf32_x86_64
6 elf_x86_64
7 elf_l1om
8 elf_k1om
9 using internal linker script:
10 ==================================================
11 /* Script for -z combreloc: combine and sort reloc sections */
12 OUTPUT_FORMAT("elf32-i386", "elf32-i386",
13 "elf32-i386")
14 OUTPUT_ARCH(i386)
15 ENTRY(_start)
16 SEARCH_DIR("/usr/i486-linux-gnu/lib32"); SEARCH_DIR("=/usr/local/lib32");
SEARCH_DIR("=/lib32"); SEARCH_DIR("=/usr/lib32");
SEARCH_DIR("=/usr/local/lib/i386-linux-gnu"); SEARCH_DIR("=/usr/local/lib");
SEARCH_DIR("=/lib/i386-linux-gnu"); SEARCH_DIR("=/lib");
SEARCH_DIR("=/usr/lib/i386-linux-gnu"); SEARCH_DIR("=/usr/lib");
17 SECTIONS
18 {
19 /* Read-only sections, merged into text segment: */
20 PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x08048000));
. = SEGMENT_START("text-segment", 0x08048000) + SIZEOF_HEADERS;
21 .interp : { *(.interp) }
22 .note.gnu.build-id : { *(.note.gnu.build-id) }
23 .hash : { *(.hash) }
24 .gnu.hash : { *(.gnu.hash) }
25 .dynsym : { *(.dynsym) }
26 .dynstr : { *(.dynstr) }
27 .gnu.version : { *(.gnu.version) }
28 .gnu.version_d : { *(.gnu.version_d) }
29 .gnu.version_r : { *(.gnu.version_r) }
30 .rel.dyn :
31 {
32 *(.rel.init)
33 *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
34 *(.rel.fini)
35 *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
36 *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
37 *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
38 *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
39 *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
40 *(.rel.ctors)
41 *(.rel.dtors)
42 *(.rel.got)
43 *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
44 *(.rel.ifunc)
45 }
46 .rel.plt :
47 {
48 *(.rel.plt)
49 PROVIDE_HIDDEN (__rel_iplt_start = .);
50 *(.rel.iplt)
51 PROVIDE_HIDDEN (__rel_iplt_end = .);
52 }
53 .init :
54 {
55 KEEP (*(.init))
56 } =0x90909090
57 .plt : { *(.plt) *(.iplt) }
58 .text :
59 {
60 *(.text.unlikely .text.*_unlikely)
61 *(.text.exit .text.exit.*)
62 *(.text.startup .text.startup.*)
63 *(.text.hot .text.hot.*)
64 *(.text .stub .text.* .gnu.linkonce.t.*)
65 /* .gnu.warning sections are handled specially by elf32.em. */
66 *(.gnu.warning)
67 } =0x90909090
68 .fini :
69 {
70 KEEP (*(.fini))
71 } =0x90909090
72 PROVIDE (__etext = .);
73 PROVIDE (_etext = .);
74 PROVIDE (etext = .);
75 .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
76 .rodata1 : { *(.rodata1) }
77 .eh_frame_hdr : { *(.eh_frame_hdr) }
78 .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
79 .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
80 .gcc_except_table.*) }
81 /* These sections are generated by the Sun/Oracle C++ compiler. */
82 .exception_ranges : ONLY_IF_RO { *(.exception_ranges
83 .exception_ranges*) }
84 /* Adjust the address for the data segment. We want to adjust up to
85 the same address within the page on the next page up. */
86 . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .)
& (CONSTANT (MAXPAGESIZE) - 1));
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
87 /* Exception handling */
88 .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
89 .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
90 .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
91 /* Thread Local Storage sections */
92 .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
93 .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
94 .preinit_array :
95 {
96 PROVIDE_HIDDEN (__preinit_array_start = .);
97 KEEP (*(.preinit_array))
98 PROVIDE_HIDDEN (__preinit_array_end = .);
99 }
100 .init_array :
101 {
102 PROVIDE_HIDDEN (__init_array_start = .);
103 KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
104 KEEP (*(.init_array))
105 KEEP (*(EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
106 PROVIDE_HIDDEN (__init_array_end = .);
107 }
108 .fini_array :
109 {
110 PROVIDE_HIDDEN (__fini_array_start = .);
111 KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
112 KEEP (*(.fini_array))
113 KEEP (*(EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
114 PROVIDE_HIDDEN (__fini_array_end = .);
115 }
116 .ctors :
117 {
118 /* gcc uses crtbegin.o to find the start of
119 the constructors, so we make sure it is
120 first. Because this is a wildcard, it
121 doesn't matter if the user does not
122 actually link against crtbegin.o; the
123 linker won't look for a file to match a
124 wildcard. The wildcard also means that it
125 doesn't matter which directory crtbegin.o
126 is in. */
127 KEEP (*crtbegin.o(.ctors))
128 KEEP (*crtbegin?.o(.ctors))
129 /* We don't want to include the .ctor section from
130 the crtend.o file until after the sorted ctors.
131 The .ctor section from the crtend file contains the
132 end of ctors marker and it must be last */
133 KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
134 KEEP (*(SORT(.ctors.*)))
135 KEEP (*(.ctors))
136 }
137 .dtors :
138 {
139 KEEP (*crtbegin.o(.dtors))
140 KEEP (*crtbegin?.o(.dtors))
141 KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
142 KEEP (*(SORT(.dtors.*)))
143 KEEP (*(.dtors))
144 }
145 .jcr : { KEEP (*(.jcr)) }
146 .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*)
*(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
147 .dynamic : { *(.dynamic) }
148 .got : { *(.got) *(.igot) }
149 . = DATA_SEGMENT_RELRO_END (12, .);
150 .got.plt : { *(.got.plt) *(.igot.plt) }
151 .data :
152 {
153 *(.data .data.* .gnu.linkonce.d.*)
154 SORT(CONSTRUCTORS)
155 }
156 .data1 : { *(.data1) }
157 _edata = .; PROVIDE (edata = .);
158 __bss_start = .;
159 .bss :
160 {
161 *(.dynbss)
162 *(.bss .bss.* .gnu.linkonce.b.*)
163 *(COMMON)
164 /* Align here to ensure that the .bss section occupies space up to
165 _end. Align after .bss to ensure correct alignment even if the
166 .bss section disappears because there are no input sections.
167 FIXME: Why do we need it? When there is no .bss section, we don't
168 pad the .data section. */
169 . = ALIGN(. != 0 ? 32 / 8 : 1);
170 }
171 . = ALIGN(32 / 8);
172 . = ALIGN(32 / 8);
173 _end = .; PROVIDE (end = .);
174 . = DATA_SEGMENT_END (.);
175 /* Stabs debugging sections. */
176 .stab 0 : { *(.stab) }
177 .stabstr 0 : { *(.stabstr) }
178 .stab.excl 0 : { *(.stab.excl) }
179 .stab.exclstr 0 : { *(.stab.exclstr) }
180 .stab.index 0 : { *(.stab.index) }
181 .stab.indexstr 0 : { *(.stab.indexstr) }
182 .comment 0 : { *(.comment) }
183 /* DWARF debug sections.
184 Symbols in the DWARF debugging sections are relative to the beginning
185 of the section so we begin them at 0. */
186 /* DWARF 1 */
187 .debug 0 : { *(.debug) }
188 .line 0 : { *(.line) }
189 /* GNU DWARF 1 extensions */
190 .debug_srcinfo 0 : { *(.debug_srcinfo) }
191 .debug_sfnames 0 : { *(.debug_sfnames) }
192 /* DWARF 1.1 and DWARF 2 */
193 .debug_aranges 0 : { *(.debug_aranges) }
194 .debug_pubnames 0 : { *(.debug_pubnames) }
195 /* DWARF 2 */
196 .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
197 .debug_abbrev 0 : { *(.debug_abbrev) }
198 .debug_line 0 : { *(.debug_line) }
199 .debug_frame 0 : { *(.debug_frame) }
200 .debug_str 0 : { *(.debug_str) }
201 .debug_loc 0 : { *(.debug_loc) }
202 .debug_macinfo 0 : { *(.debug_macinfo) }
203 /* SGI/MIPS DWARF 2 extensions */
204 .debug_weaknames 0 : { *(.debug_weaknames) }
205 .debug_funcnames 0 : { *(.debug_funcnames) }
206 .debug_typenames 0 : { *(.debug_typenames) }
207 .debug_varnames 0 : { *(.debug_varnames) }
208 /* DWARF 3 */
209 .debug_pubtypes 0 : { *(.debug_pubtypes) }
210 .debug_ranges 0 : { *(.debug_ranges) }
211 .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
212 /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
213 }
214
215
216 ==================================================
我知道很長, 我和你一樣大部份有看沒有懂, 只看 L158 ~ L173 就好。
158 __bss_start = .;
159 .bss :
160 {
161 *(.dynbss)
162 *(.bss .bss.* .gnu.linkonce.b.*)
163 *(COMMON)
164 /* Align here to ensure that the .bss section occupies space up to
165 _end. Align after .bss to ensure correct alignment even if the
166 .bss section disappears because there are no input sections.
167 FIXME: Why do we need it? When there is no .bss section, we don't
168 pad the .data section. */
169 . = ALIGN(. != 0 ? 32 / 8 : 1);
170 }
171 . = ALIGN(32 / 8);
172 . = ALIGN(32 / 8);
173 _end = .; PROVIDE (end = .);
_end, __bss_start 這兩個 symbol 就是 bss section 的開始和結束。先來看看程式執行結果。
i: 0x8049734
i: 0x8049738
&__bss_start: 0x8049734
&_end: 0x804973c
ABCDEF: 11223344
bss 從 0x8049734 ~ 0x804973c 佔了 8 byte。
ABCDEF 不是預期的 0。表示成功改變 bss 這個區域。這應該簡單多了, 而且也可以馬上在 linux 上實驗。
b.c
1 #include <stdio.h>
2
3 int ABCDEF ;
4 extern int _end ;
5 extern int __bss_start ;
6
7 void fill_bss ( void )
8 {
9 int * i = 0 ;
10 for ( i = & __bss_start ; i ! = & _end ; + + i )
11 {
12 printf ( "i: %p\n " , i ) ;
13 * i = 0x11223344 ;
14 }
15
16 }
17
18 int main ( void )
19 {
20 fill_bss ( ) ;
21 printf ( "&__bss_start: %p\n " , & __bss_start ) ;
22 printf ( "&_end: %p\n " , & _end ) ;
23 printf ( "ABCDEF: %x\n " , ABCDEF ) ;
24 return 0 ;
25 }
看看 elf 裡頭的資訊:
[26] .bss NOBITS 08049734 000734 000008 00 WA 0 0 4
63: 08049738 4 OBJECT GLOBAL DEFAULT 26 ABCDEF
bss 佔 8 byte, ABCDEF 則位於 0x08049738
source code:
git clone git@github.com:descent/progs.git'
cd bss
ref:
linux kernel 完全剖析 (3.5.4 p 96)
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。