From 881fb4d392c137412861ebd3acbcb1f0c5316445 Mon Sep 17 00:00:00 2001 From: florian Date: Sat, 6 Jan 2007 18:39:09 +0000 Subject: [PATCH] * working linker script for x86_64 libraries git-svn-id: trunk@5827 - --- compiler/systems/t_linux.pas | 337 ++++------------------------------- 1 file changed, 31 insertions(+), 306 deletions(-) diff --git a/compiler/systems/t_linux.pas b/compiler/systems/t_linux.pas index c6b142a118..4081d9d60d 100644 --- a/compiler/systems/t_linux.pas +++ b/compiler/systems/t_linux.pas @@ -505,19 +505,16 @@ begin {Entry point.} add('ENTRY(_start)'); -{ {$ifdef x86_64} {$define LINKERSCRIPT_INCLUDED} - { taken from - GNU ld version 2.14.90 20040120 - - Newly inserted stuff is marked, please take care of it when updating this script - } - add('SECTIONS'); add('{'); - add(' /* Read-only sections, merged into text segment: */'); - add(' PROVIDE (__executable_start = 0x400000); . = 0x400000 + SIZEOF_HEADERS;'); + {Read-only sections, merged into text segment:} + if current_module.islibrary then + add(' . = 0 + SIZEOF_HEADERS;') + else + add(' PROVIDE (__executable_start = 0x0400000); . = 0x0400000 + SIZEOF_HEADERS;'); + add(' . = 0 + SIZEOF_HEADERS;'); add(' .interp : { *(.interp) }'); add(' .hash : { *(.hash) }'); add(' .dynsym : { *(.dynsym) }'); @@ -531,11 +528,10 @@ begin add(' *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)'); add(' *(.rel.fini)'); add(' *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)'); + add(' *(.rel.data.rel.ro*)'); add(' *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)'); add(' *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)'); add(' *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)'); - add(' *(.rel.ctors)'); - add(' *(.rel.dtors)'); add(' *(.rel.got)'); add(' *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)'); add(' }'); @@ -548,8 +544,6 @@ begin add(' *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)'); add(' *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)'); add(' *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)'); - add(' *(.rela.ctors)'); - add(' *(.rela.dtors)'); add(' *(.rela.got)'); add(' *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)'); add(' }'); @@ -563,326 +557,58 @@ begin add(' .text :'); add(' {'); add(' *(.text .stub .text.* .gnu.linkonce.t.*)'); - add(' /* .gnu.warning sections are handled specially by elf32.em. */'); - add(' *(.gnu.warning)'); - add(' } =0x90909090'); - add(' .fini :'); - add(' {'); - add(' KEEP (*(.fini))'); - add(' } =0x90909090'); - add(' PROVIDE (__etext = .);'); - add(' PROVIDE (_etext = .);'); - add(' PROVIDE (etext = .);'); - add(' .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }'); - add(' .rodata1 : { *(.rodata1) }'); - add(' .eh_frame_hdr : { *(.eh_frame_hdr) }'); - add(' /* Adjust the address for the data segment. We want to adjust up to'); - add(' the same address within the page on the next page up. */'); - add(' . = ALIGN (0x100000) - ((0x100000 - .) & (0x100000 - 1));'); - // was: add(' . = ALIGN (0x100000) - ((0x100000 - .) & (0x100000 - 1)); . = DATA_SEGMENT_ALIGN (0x100000, 0x1000);'); - add(' /* Ensure the __preinit_array_start label is properly aligned. We'); - add(' could instead move the label definition inside the section, but'); - add(' the linker would then create the section even if it turns out to'); - add(' be empty, which isn''t pretty. */'); - add(' . = ALIGN(64 / 8);'); - add(' PROVIDE (__preinit_array_start = .);'); - add(' .preinit_array : { *(.preinit_array) }'); - add(' PROVIDE (__preinit_array_end = .);'); - add(' PROVIDE (__init_array_start = .);'); - add(' .init_array : { *(.init_array) }'); - add(' PROVIDE (__init_array_end = .);'); - add(' PROVIDE (__fini_array_start = .);'); - add(' .fini_array : { *(.fini_array) }'); - add(' PROVIDE (__fini_array_end = .);'); - add(' .data :'); - add(' {'); - add(' *(.data .data.* .gnu.linkonce.d.*)'); -{ inserted } - add(' KEEP (*(.fpc .fpc.version .fpc.links))'); -{ end of insert } - add(' SORT(CONSTRUCTORS)'); - add(' }'); - add(' .data1 : { *(.data1) }'); - add(' .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }'); - add(' .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }'); - add(' .eh_frame : { KEEP (*(.eh_frame)) }'); - add(' .gcc_except_table : { *(.gcc_except_table) }'); - add(' .dynamic : { *(.dynamic) }'); - add(' .ctors :'); - add(' {'); - add(' /* gcc uses crtbegin.o to find the start of'); - add(' the constructors, so we make sure it is'); - add(' first. Because this is a wildcard, it'); - add(' doesn''t matter if the user does not'); - add(' actually link against crtbegin.o; the'); - add(' linker won''t look for a file to match a'); - add(' wildcard. The wildcard also means that it'); - add(' doesn''t matter which directory crtbegin.o'); - add(' is in. */'); - add(' KEEP (*crtbegin*.o(.ctors))'); - add(' /* We don''t want to include the .ctor section from'); - add(' from the crtend.o file until after the sorted ctors.'); - add(' The .ctor section from the crtend file contains the'); - add(' end of ctors marker and it must be last */'); - add(' KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))'); - add(' KEEP (*(SORT(.ctors.*)))'); - add(' KEEP (*(.ctors))'); - add(' }'); - add(' .dtors :'); - add(' {'); - add(' KEEP (*crtbegin*.o(.dtors))'); - add(' KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))'); - add(' KEEP (*(SORT(.dtors.*)))'); - add(' KEEP (*(.dtors))'); - add(' }'); - add(' .jcr : { KEEP (*(.jcr)) }'); - add(' .got : { *(.got.plt) *(.got) }'); - add(' _edata = .;'); - add(' PROVIDE (edata = .);'); -{ inserted } - add(' .threadvar : { *(.threadvar .threadvar.* .gnu.linkonce.tv.*) }'); -{ end of insert } - add(' __bss_start = .;'); - add(' .bss :'); - add(' {'); - add(' *(.dynbss)'); - add(' *(.bss .bss.* .gnu.linkonce.b.*)'); - add(' *(COMMON)'); - add(' /* Align here to ensure that the .bss section occupies space up to'); - add(' _end. Align after .bss to ensure correct alignment even if the'); - add(' .bss section disappears because there are no input sections. */'); - add(' . = ALIGN(64 / 8);'); - add(' }'); - add(' . = ALIGN(64 / 8);'); - add(' _end = .;'); - add(' PROVIDE (end = .);'); -// add(' . = DATA_SEGMENT_END (.);'); - add(' /* Stabs debugging sections. */'); - add(' .stab 0 : { *(.stab) }'); - add(' .stabstr 0 : { *(.stabstr) }'); - add(' .stab.excl 0 : { *(.stab.excl) }'); - add(' .stab.exclstr 0 : { *(.stab.exclstr) }'); - add(' .stab.index 0 : { *(.stab.index) }'); - add(' .stab.indexstr 0 : { *(.stab.indexstr) }'); - add(' .comment 0 : { *(.comment) }'); - add(' /* DWARF debug sections.'); - add(' Symbols in the DWARF debugging sections are relative to the beginning'); - add(' of the section so we begin them at 0. */'); - add(' /* DWARF 1 */'); - add(' .debug 0 : { *(.debug) }'); - add(' .line 0 : { *(.line) }'); - add(' /* GNU DWARF 1 extensions */'); - add(' .debug_srcinfo 0 : { *(.debug_srcinfo) }'); - add(' .debug_sfnames 0 : { *(.debug_sfnames) }'); - add(' /* DWARF 1.1 and DWARF 2 */'); - add(' .debug_aranges 0 : { *(.debug_aranges) }'); - add(' .debug_pubnames 0 : { *(.debug_pubnames) }'); - add(' /* DWARF 2 */'); - add(' .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }'); - add(' .debug_abbrev 0 : { *(.debug_abbrev) }'); - add(' .debug_line 0 : { *(.debug_line) }'); - add(' .debug_frame 0 : { *(.debug_frame) }'); - add(' .debug_str 0 : { *(.debug_str) }'); - add(' .debug_loc 0 : { *(.debug_loc) }'); - add(' .debug_macinfo 0 : { *(.debug_macinfo) }'); - add(' /* SGI/MIPS DWARF 2 extensions */'); - add(' .debug_weaknames 0 : { *(.debug_weaknames) }'); - add(' .debug_funcnames 0 : { *(.debug_funcnames) }'); - add(' .debug_typenames 0 : { *(.debug_typenames) }'); - add(' .debug_varnames 0 : { *(.debug_varnames) }'); - add(' /DISCARD/ : { *(.note.GNU-stack) }'); - add('}'); - -{ from GNU ld version 2.16.91 20060118 Debian GNU/Linux, - unused because not usable with older LDs - add('SECTIONS'); - add('{'); - add(' /* Read-only sections, merged into text segment: */'); - add(' PROVIDE (__executable_start = 0x400000); . = 0x400000 + SIZEOF_HEADERS;'); - add(' .interp : { *(.interp) }'); - add(' .hash : { *(.hash) }'); - add(' .dynsym : { *(.dynsym) }'); - add(' .dynstr : { *(.dynstr) }'); - add(' .gnu.version : { *(.gnu.version) }'); - add(' .gnu.version_d : { *(.gnu.version_d) }'); - add(' .gnu.version_r : { *(.gnu.version_r) }'); - add(' .rel.dyn :'); - add(' {'); - add(' *(.rel.init)'); - add(' *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)'); - add(' *(.rel.fini)'); - add(' *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)'); - add(' *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)'); - add(' *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)'); - add(' *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)'); - add(' *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)'); - add(' *(.rel.ctors)'); - add(' *(.rel.dtors)'); - add(' *(.rel.got)'); - add(' *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)'); - add(' *(.rel.ldata .rel.ldata.* .rel.gnu.linkonce.l.*)'); - add(' *(.rel.lbss .rel.lbss.* .rel.gnu.linkonce.lb.*)'); - add(' *(.rel.lrodata .rel.lrodata.* .rel.gnu.linkonce.lr.*)'); - add(' }'); - add(' .rela.dyn :'); - add(' {'); - add(' *(.rela.init)'); - add(' *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)'); - add(' *(.rela.fini)'); - add(' *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)'); - add(' *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)'); - add(' *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)'); - add(' *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)'); - add(' *(.rela.ctors)'); - add(' *(.rela.dtors)'); - add(' *(.rela.got)'); - add(' *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)'); - add(' *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)'); - add(' *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)'); - add(' *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)'); - add(' }'); - add(' .rel.plt : { *(.rel.plt) }'); - add(' .rela.plt : { *(.rela.plt) }'); - add(' .init :'); - add(' {'); - add(' KEEP (*(.init))'); - add(' } =0x90909090'); - add(' .plt : { *(.plt) }'); - add(' .text :'); - add(' {'); - add(' *(.text .stub .text.* .gnu.linkonce.t.*)'); add(' KEEP (*(.text.*personality*))'); - add(' /* .gnu.warning sections are handled specially by elf32.em. */'); + {.gnu.warning sections are handled specially by elf32.em.} add(' *(.gnu.warning)'); add(' } =0x90909090'); add(' .fini :'); add(' {'); add(' KEEP (*(.fini))'); add(' } =0x90909090'); - add(' PROVIDE (__etext = .);'); add(' PROVIDE (_etext = .);'); - add(' PROVIDE (etext = .);'); - add(' .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }'); - add(' .rodata1 : { *(.rodata1) }'); - add(' .eh_frame_hdr : { *(.eh_frame_hdr) }'); - add(' .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }'); - add(' .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }'); - add(' /* Adjust the address for the data segment. We want to adjust up to'); - add(' the same address within the page on the next page up. */'); - add(' . = ALIGN (0x100000) - ((0x100000 - .) & (0x100000 - 1));'); // . = DATA_SEGMENT_ALIGN (0x100000, 0x1000);'); - add(' /* Exception handling */'); - add(' .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }'); - add(' .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }'); - add(' /* Thread Local Storage sections */'); - add(' .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }'); - add(' .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }'); - add(' .preinit_array :'); + add(' .rodata :'); add(' {'); - add(' PROVIDE_HIDDEN (__preinit_array_start = .);'); - add(' KEEP (*(.preinit_array))'); - add(' PROVIDE_HIDDEN (__preinit_array_end = .);'); + add(' *(.rodata .rodata.* .gnu.linkonce.r.*)'); add(' }'); - add(' .init_array :'); - add(' {'); - add(' PROVIDE_HIDDEN (__init_array_start = .);'); - add(' KEEP (*(SORT(.init_array.*)))'); - add(' KEEP (*(.init_array))'); - add(' PROVIDE_HIDDEN (__init_array_end = .);'); - add(' }'); - add(' .fini_array :'); - add(' {'); - add(' PROVIDE_HIDDEN (__fini_array_start = .);'); - add(' KEEP (*(.fini_array))'); - add(' KEEP (*(SORT(.fini_array.*)))'); - add(' PROVIDE_HIDDEN (__fini_array_end = .);'); - add(' }'); - add(' .ctors :'); - add(' {'); - add(' /* gcc uses crtbegin.o to find the start of'); - add(' the constructors, so we make sure it is'); - add(' first. Because this is a wildcard, it'); - add(' doesn''t matter if the user does not'); - add(' actually link against crtbegin.o; the'); - add(' linker won''t look for a file to match a'); - add(' wildcard. The wildcard also means that it'); - add(' doesn''t matter which directory crtbegin.o'); - add(' is in. */'); - add(' KEEP (*crtbegin*.o(.ctors))'); - add(' /* We don''t want to include the .ctor section from'); - add(' the crtend.o file until after the sorted ctors.'); - add(' The .ctor section from the crtend file contains the'); - add(' end of ctors marker and it must be last */'); - add(' KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))'); - add(' KEEP (*(SORT(.ctors.*)))'); - add(' KEEP (*(.ctors))'); - add(' }'); - add(' .dtors :'); - add(' {'); - add(' KEEP (*crtbegin*.o(.dtors))'); - add(' KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))'); - add(' KEEP (*(SORT(.dtors.*)))'); - add(' KEEP (*(.dtors))'); - add(' }'); - add(' .jcr : { KEEP (*(.jcr)) }'); - add(' .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }'); + {Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up.} + add(' . = ALIGN (0x1000) - ((0x1000 - .) & (0x1000 - 1));'); add(' .dynamic : { *(.dynamic) }'); add(' .got : { *(.got) }'); - add(' . = DATA_SEGMENT_RELRO_END (24, .);'); add(' .got.plt : { *(.got.plt) }'); add(' .data :'); add(' {'); add(' *(.data .data.* .gnu.linkonce.d.*)'); -{ inserted } add(' KEEP (*(.fpc .fpc.version .fpc.links))'); -{ end of insert } add(' KEEP (*(.gnu.linkonce.d.*personality*))'); - add(' SORT(CONSTRUCTORS)'); add(' }'); - add(' .data1 : { *(.data1) }'); - add(' _edata = .; PROVIDE (edata = .);'); -{ inserted } + add(' _edata = .;'); + add(' PROVIDE (edata = .);'); + {$ifdef zsegment_threadvars} + add(' _z = .;'); + add(' .threadvar 0 : AT (_z) { *(.threadvar .threadvar.* .gnu.linkonce.tv.*) }'); + add(' PROVIDE (_threadvar_size = SIZEOF(.threadvar));'); + add(' . = _z + SIZEOF (.threadvar);'); + {$else} add(' .threadvar : { *(.threadvar .threadvar.* .gnu.linkonce.tv.*) }'); -{ end of insert } + {$endif} add(' __bss_start = .;'); add(' .bss :'); add(' {'); add(' *(.dynbss)'); add(' *(.bss .bss.* .gnu.linkonce.b.*)'); add(' *(COMMON)'); - add(' /* Align here to ensure that the .bss section occupies space up to'); - add(' _end. Align after .bss to ensure correct alignment even if the'); - add(' .bss section disappears because there are no input sections.'); - add(' FIXME: Why do we need it? When there is no .bss section, we don''t'); - add(' pad the .data section. */'); - add(' . = ALIGN(. != 0 ? 64 / 8 : 1);'); + {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.} + add(' . = ALIGN(32 / 8);'); add(' }'); - add(' . = ALIGN(64 / 8);'); - add(' .lbss :'); - add(' {'); - add(' *(.dynlbss)'); - add(' *(.lbss .lbss.* .gnu.linkonce.lb.*)'); - add(' *(LARGE_COMMON)'); - add(' }'); - add(' .lrodata ALIGN(0x100000) + (. & (0x100000 - 1)) :'); - add(' {'); - add(' *(.lrodata .lrodata.* .gnu.linkonce.lr.*)'); - add(' }'); - add(' .ldata ALIGN(0x100000) + (. & (0x100000 - 1)) :'); - add(' {'); - add(' *(.ldata .ldata.* .gnu.linkonce.l.*)'); - add(' . = ALIGN(. != 0 ? 64 / 8 : 1);'); - add(' }'); - add(' . = ALIGN(64 / 8);'); - add(' _end = .; PROVIDE (end = .);'); - add(' . = DATA_SEGMENT_END (.);'); - add(' /* Stabs debugging sections. */'); + add(' . = ALIGN(32 / 8);'); + add(' _end = .;'); + add(' PROVIDE (end = .);'); + {Stabs debugging sections.} add(' .stab 0 : { *(.stab) }'); add(' .stabstr 0 : { *(.stabstr) }'); - add(' .stab.excl 0 : { *(.stab.excl) }'); - add(' .stab.exclstr 0 : { *(.stab.exclstr) }'); - add(' .stab.index 0 : { *(.stab.index) }'); - add(' .stab.indexstr 0 : { *(.stab.indexstr) }'); - add(' .comment 0 : { *(.comment) }'); add(' /* DWARF debug sections.'); add(' Symbols in the DWARF debugging sections are relative to the beginning'); add(' of the section so we begin them at 0. */'); @@ -910,9 +636,8 @@ begin add(' .debug_varnames 0 : { *(.debug_varnames) }'); add(' /DISCARD/ : { *(.note.GNU-stack) }'); add('}'); -} {$endif x86_64} -} + {$ifndef LINKERSCRIPT_INCLUDED} {Sections.}