OLD | NEW |
1 /* Script for ld --shared: link shared library */ | 1 /* Script for ld --shared: link shared library */ |
2 OUTPUT_FORMAT("elf32-nacl", "elf32-nacl", | 2 OUTPUT_FORMAT("elf32-nacl", "elf32-nacl", |
3 "elf32-nacl") | 3 "elf32-nacl") |
4 OUTPUT_ARCH(i386) | 4 OUTPUT_ARCH(i386) |
5 ENTRY(_start) | 5 ENTRY(_start) |
6 SEARCH_DIR("=/usr/local/lib32"); SEARCH_DIR("=/lib32"); SEARCH_DIR("=/usr/lib32"
); | 6 SEARCH_DIR("=/usr/local/lib32"); SEARCH_DIR("=/lib32"); SEARCH_DIR("=/usr/lib32"
); |
7 SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); | 7 SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); |
8 PHDRS | 8 PHDRS |
9 { | 9 { |
10 seg_code PT_LOAD FLAGS(5) ; /* read + execute */ | 10 seg_code PT_LOAD FLAGS(5) ; /* read + execute */ |
11 seg_rodata PT_LOAD FLAGS(4) ; /* read */ | 11 seg_rodata PT_LOAD FLAGS(4) ; /* read */ |
12 seg_rwdata PT_LOAD FLAGS(6) ; /* read + write */ | 12 seg_rwdata PT_LOAD FLAGS(6) ; /* read + write */ |
| 13 seg_bss PT_LOAD FLAGS(6) ; /* read + write */ |
13 seg_dynamic PT_DYNAMIC FLAGS(6) ; | 14 seg_dynamic PT_DYNAMIC FLAGS(6) ; |
14 seg_stack PT_GNU_STACK FLAGS(6) ; | 15 seg_stack PT_GNU_STACK FLAGS(6) ; |
15 seg_tls PT_TLS FLAGS(4) ; | 16 seg_tls PT_TLS FLAGS(4) ; |
16 } | 17 } |
17 SECTIONS | 18 SECTIONS |
18 { | 19 { |
19 /* ELF headers are not included in any PT_LOAD segment */ | 20 /* ELF headers are not included in any PT_LOAD segment */ |
20 . = SEGMENT_START("text", 0); | 21 . = SEGMENT_START("text", 0); |
21 _begin = .; | 22 _begin = .; |
22 /* The ALIGN(32) instructions below are workarounds. | 23 /* The ALIGN(32) instructions below are workarounds. |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 .got.plt : { *(.got.plt) } | 158 .got.plt : { *(.got.plt) } |
158 . = ALIGN(CONSTANT (MAXPAGESIZE)); /* nacl wants page alignment */ | 159 . = ALIGN(CONSTANT (MAXPAGESIZE)); /* nacl wants page alignment */ |
159 .data : | 160 .data : |
160 { | 161 { |
161 *(.data .data.* .gnu.linkonce.d.*) | 162 *(.data .data.* .gnu.linkonce.d.*) |
162 KEEP (*(.gnu.linkonce.d.*personality*)) | 163 KEEP (*(.gnu.linkonce.d.*personality*)) |
163 SORT(CONSTRUCTORS) | 164 SORT(CONSTRUCTORS) |
164 } | 165 } |
165 .data1 : { *(.data1) } | 166 .data1 : { *(.data1) } |
166 _edata = .; PROVIDE (edata = .); | 167 _edata = .; PROVIDE (edata = .); |
| 168 |
| 169 /* We place the BSS in a separate segment as a workaround for the |
| 170 behaviour of NaCl's mmap() on the last page in a file. When using |
| 171 copy-on-write MAP_PRIVATE, we cannot necessarily write beyond the |
| 172 file's extent within the 64k page. |
| 173 See http://code.google.com/p/nativeclient/issues/detail?id=824. |
| 174 TODO(mseaborn): A better fix would be to change the dynamic linker |
| 175 to copy the last page. This would save a page of memory because |
| 176 the BSS could share a page with the data segment. But for now, it |
| 177 is simpler to change the linker script. */ |
| 178 . = DATA_SEGMENT_END (.); |
| 179 . = ALIGN (CONSTANT (MAXPAGESIZE)); |
| 180 |
167 __bss_start = .; | 181 __bss_start = .; |
168 .bss : | 182 .bss : |
169 { | 183 { |
170 *(.dynbss) | 184 *(.dynbss) |
171 *(.bss .bss.* .gnu.linkonce.b.*) | 185 *(.bss .bss.* .gnu.linkonce.b.*) |
172 *(COMMON) | 186 *(COMMON) |
173 /* Align here to ensure that the .bss section occupies space up to | 187 /* Align here to ensure that the .bss section occupies space up to |
174 _end. Align after .bss to ensure correct alignment even if the | 188 _end. Align after .bss to ensure correct alignment even if the |
175 .bss section disappears because there are no input sections. | 189 .bss section disappears because there are no input sections. |
176 FIXME: Why do we need it? When there is no .bss section, we don't | 190 FIXME: Why do we need it? When there is no .bss section, we don't |
177 pad the .data section. */ | 191 pad the .data section. */ |
178 . = ALIGN(. != 0 ? 32 / 8 : 1); | 192 . = ALIGN(. != 0 ? 32 / 8 : 1); |
179 } | 193 } :seg_bss |
180 . = ALIGN(32 / 8); | 194 . = ALIGN(32 / 8); |
181 . = ALIGN(32 / 8); | 195 . = ALIGN(32 / 8); |
182 _end = .; PROVIDE (end = .); | 196 _end = .; PROVIDE (end = .); |
183 . = DATA_SEGMENT_END (.); | |
184 /* Stabs debugging sections. */ | 197 /* Stabs debugging sections. */ |
185 .stab 0 : { *(.stab) } | 198 .stab 0 : { *(.stab) } |
186 .stabstr 0 : { *(.stabstr) } | 199 .stabstr 0 : { *(.stabstr) } |
187 .stab.excl 0 : { *(.stab.excl) } | 200 .stab.excl 0 : { *(.stab.excl) } |
188 .stab.exclstr 0 : { *(.stab.exclstr) } | 201 .stab.exclstr 0 : { *(.stab.exclstr) } |
189 .stab.index 0 : { *(.stab.index) } | 202 .stab.index 0 : { *(.stab.index) } |
190 .stab.indexstr 0 : { *(.stab.indexstr) } | 203 .stab.indexstr 0 : { *(.stab.indexstr) } |
191 .comment 0 : { *(.comment) } | 204 .comment 0 : { *(.comment) } |
192 /* DWARF debug sections. | 205 /* DWARF debug sections. |
193 Symbols in the DWARF debugging sections are relative to the beginning | 206 Symbols in the DWARF debugging sections are relative to the beginning |
(...skipping 20 matching lines...) Expand all Loading... |
214 .debug_funcnames 0 : { *(.debug_funcnames) } | 227 .debug_funcnames 0 : { *(.debug_funcnames) } |
215 .debug_typenames 0 : { *(.debug_typenames) } | 228 .debug_typenames 0 : { *(.debug_typenames) } |
216 .debug_varnames 0 : { *(.debug_varnames) } | 229 .debug_varnames 0 : { *(.debug_varnames) } |
217 /* DWARF 3 */ | 230 /* DWARF 3 */ |
218 .debug_pubtypes 0 : { *(.debug_pubtypes) } | 231 .debug_pubtypes 0 : { *(.debug_pubtypes) } |
219 .debug_ranges 0 : { *(.debug_ranges) } | 232 .debug_ranges 0 : { *(.debug_ranges) } |
220 .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } | 233 .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } |
221 /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) } | 234 /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) } |
222 /DISCARD/ : { *(.note.ABI-tag) } | 235 /DISCARD/ : { *(.note.ABI-tag) } |
223 } | 236 } |
OLD | NEW |