diff options
Diffstat (limited to 'user/usr/bin/tests/linkermagic.h')
-rw-r--r-- | user/usr/bin/tests/linkermagic.h | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/user/usr/bin/tests/linkermagic.h b/user/usr/bin/tests/linkermagic.h new file mode 100644 index 0000000..2dfdd4f --- /dev/null +++ b/user/usr/bin/tests/linkermagic.h @@ -0,0 +1,232 @@ +#pragma once + +/* Linker variables */ +extern void *__executable_start; +extern void *_etext; +extern void *_edata; +extern void *_end; + +#define text_start ((void *)&__executable_start) +#define text_end ((void *)&_etext) +#define data_start ((void *)&_etext) +#define data_end ((void *)&_edata) +#define bss_start ((void *)&_edata) +#define bss_end ((void *)&_end) + +/* The following is the default linux linker script, for reference */ +#if 0 +/* +GNU ld (GNU Binutils for Debian) 2.18.0.20080103 + Supported emulations: + elf_i386 + i386linux + elf_x86_64 +using internal linker script: +================================================== +*/ +/* Script for -z combreloc: combine and sort reloc sections */ +OUTPUT_FORMAT("elf32-i386", "elf32-i386", + "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) +SEARCH_DIR("/usr/i486-linux-gnu/lib32"); SEARCH_DIR("/usr/local/lib32"); SEARCH_DIR("/lib32"); SEARCH_DIR("/usr/lib32"); SEARCH_DIR("/usr/i486-linux-gnu/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); +SECTIONS { + /* Read-only sections, merged into text segment: */ + PROVIDE(__executable_start = 0x08048000); . = 0x08048000 + SIZEOF_HEADERS; +.interp : { *(.interp) } +.note.gnu.build - id : { *(.note.gnu.build - id) } +.hash : { *(.hash) } +.gnu.hash : { *(.gnu.hash) } +.dynsym : { *(.dynsym) } +.dynstr : { *(.dynstr) } +.gnu.version : { *(.gnu.version) } +.gnu.version_d : { *(.gnu.version_d) } +.gnu.version_r : { *(.gnu.version_r) } +.rel.dyn : + { + *(.rel.init) + *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) + *(.rel.fini) + *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) + *(.rel.data.rel.ro *.rel.gnu.linkonce.d.rel.ro.*) + *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) + *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) + *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) + *(.rel.ctors) + *(.rel.dtors) + *(.rel.got) + *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) + } +.rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + } +.rel.plt : { *(.rel.plt) } +.rela.plt : { *(.rela.plt) } +.init : + { + KEEP(*(.init)) + } = 0x90909090 +.plt : { *(.plt) } +.text : + { + *(.text .stub .text.* .gnu.linkonce.t.*) + KEEP(*(.text.*personality *)) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } = 0x90909090 +.fini : + { + KEEP(*(.fini)) + } = 0x90909090 + PROVIDE(__etext = .); + PROVIDE(_etext = .); + PROVIDE(etext = .); +.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } +.rodata1 : { *(.rodata1) } +.eh_frame_hdr : { *(.eh_frame_hdr) } +.eh_frame : ONLY_IF_RO { KEEP(*(.eh_frame)) } +.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = ALIGN(CONSTANT(MAXPAGESIZE)) - ((CONSTANT(MAXPAGESIZE) - .) & (CONSTANT(MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN(CONSTANT(MAXPAGESIZE), CONSTANT(COMMONPAGESIZE)); + /* Exception handling */ +.eh_frame : ONLY_IF_RW { KEEP(*(.eh_frame)) } +.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + /* Thread Local Storage sections */ +.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } +.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } +.preinit_array : + { + PROVIDE_HIDDEN(__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN(__preinit_array_end = .); + } +.init_array : + { + PROVIDE_HIDDEN(__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN(__init_array_end = .); + } +.fini_array : + { + PROVIDE_HIDDEN(__fini_array_start = .); + KEEP(*(.fini_array)) + KEEP(*(SORT(.fini_array.*))) + PROVIDE_HIDDEN(__fini_array_end = .); + } +.ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP(*crtbegin.o(.ctors)) + KEEP(*crtbegin ? .o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP(*(EXCLUDE_FILE(*crtend.o *crtend ? .o) .ctors)) + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + } +.dtors : + { + KEEP(*crtbegin.o(.dtors)) + KEEP(*crtbegin ? .o(.dtors)) + KEEP(*(EXCLUDE_FILE(*crtend.o *crtend ? .o) .dtors)) + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + } +.jcr : { KEEP(*(.jcr)) } +.data.rel.ro : { *(.data.rel.ro.local *.gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro *.gnu.linkonce.d.rel.ro.*) } +.dynamic : { *(.dynamic) } +.got : { *(.got) } + . = DATA_SEGMENT_RELRO_END(12, .); +.got.plt : { *(.got.plt) } +.data : + { + *(.data .data.* .gnu.linkonce.d.*) + KEEP(*(.gnu.linkonce.d.*personality *)) + SORT(CONSTRUCTORS) + } +.data1 : { *(.data1) } + _edata = .; PROVIDE(edata = .); + __bss_start = .; +.bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we don't + pad the .data section. */ + . = ALIGN(. != 0 ? 32 / 8 : 1); + } + . = ALIGN(32 / 8); + . = ALIGN(32 / 8); + _end = .; PROVIDE(end = .); + . = DATA_SEGMENT_END(.); + /* Stabs debugging sections. */ +.stab 0 : { *(.stab) } +.stabstr 0 : { *(.stabstr) } +.stab.excl 0 : { *(.stab.excl) } +.stab.exclstr 0 : { *(.stab.exclstr) } +.stab.index 0 : { *(.stab.index) } +.stab.indexstr 0 : { *(.stab.indexstr) } +.comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ +.debug 0 : { *(.debug) } +.line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ +.debug_srcinfo 0 : { *(.debug_srcinfo) } +.debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ +.debug_aranges 0 : { *(.debug_aranges) } +.debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ +.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } +.debug_abbrev 0 : { *(.debug_abbrev) } +.debug_line 0 : { *(.debug_line) } +.debug_frame 0 : { *(.debug_frame) } +.debug_str 0 : { *(.debug_str) } +.debug_loc 0 : { *(.debug_loc) } +.debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ +.debug_weaknames 0 : { *(.debug_weaknames) } +.debug_funcnames 0 : { *(.debug_funcnames) } +.debug_typenames 0 : { *(.debug_typenames) } +.debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3 */ +.debug_pubtypes 0 : { *(.debug_pubtypes) } +.debug_ranges 0 : { *(.debug_ranges) } +.gnu.attributes 0 : { KEEP(*(.gnu.attributes)) } +/ DISCARD / : { *(.note.GNU - stack) *(.gnu_debuglink) } +} +/* + +================================================== +*/ +#endif |