summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2010-09-14 03:51:22 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2010-09-14 03:55:11 +0200
commitfaa99cfbe3dbac26021df620a19c3f671a0a2613 (patch)
tree7b0d15762bd72d6901898d59bb7c7fec73d6c420
parent660d90c5e0a60902e9ec94ea585c50c55a25c10c (diff)
Fix ifunc entries
* i386/ldscript: Update to the version from binutils 2.20.51.20100617. Remove SEARCH_DIR calls. * Makefile.am (clib_routines): Accept undefined __rel_iplt_start and __rel_iplt_end as these come from the ldscript. * i386/i386at/boothdr.S (boot_entry): Call ifunc hooks at boot. * i386/xen/xen_boothdr.S (start): Likewise.
-rw-r--r--Makefile.am1
-rw-r--r--i386/i386at/boothdr.S17
-rw-r--r--i386/ldscript62
-rw-r--r--i386/xen/xen_boothdr.S17
4 files changed, 66 insertions, 31 deletions
diff --git a/Makefile.am b/Makefile.am
index bc8a9e8..04885dd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -137,6 +137,7 @@ clib_routines := memcmp memcpy memmove memset bcopy bzero \
strchr strstr strsep strpbrk strtok \
htonl htons ntohl ntohs \
udivdi3 __udivdi3 \
+ __rel_iplt_start __rel_iplt_end \
_START _start etext _edata end _end # actually ld magic, not libc.
gnumach-undef: gnumach.$(OBJEXT)
$(NM) -u $< | sed 's/ *U *//' | sort -u > $@
diff --git a/i386/i386at/boothdr.S b/i386/i386at/boothdr.S
index 27d0405..45cd599 100644
--- a/i386/i386at/boothdr.S
+++ b/i386/i386at/boothdr.S
@@ -58,6 +58,23 @@ boot_entry:
/* Push the boot_info pointer to be the second argument. */
pushl %ebx
+ /* Fix ifunc entries */
+ movl $__rel_iplt_start,%esi
+ movl $__rel_iplt_end,%edi
+iplt_cont:
+ cmpl %edi,%esi
+ jae iplt_done
+ movl (%esi),%ebx /* r_offset */
+ movb 4(%esi),%al /* info */
+ cmpb $42,%al /* IRELATIVE */
+ jnz iplt_next
+ call *(%ebx) /* call ifunc */
+ movl %eax,(%ebx) /* fixed address */
+iplt_next:
+ addl $8,%esi
+ jmp iplt_cont
+iplt_done:
+
/* Jump into C code. */
call EXT(c_boot_entry)
diff --git a/i386/ldscript b/i386/ldscript
index 7e4e3b0..f2b90fa 100644
--- a/i386/ldscript
+++ b/i386/ldscript
@@ -3,14 +3,8 @@ OUTPUT_FORMAT("elf32-i386", "elf32-i386",
"elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
-SEARCH_DIR("/usr/i486-linux-gnu/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
SECTIONS
{
- .init :
- {
- KEEP (*(.init))
- } =0x90909090
- .plt : { *(.plt) }
/*
* There are specific requirements about entry points, so we have it
* configurable via `_START': `.text' will begin there and `.text.start' will
@@ -22,10 +16,15 @@ SECTIONS
{
*(.text.start)
*(.text .stub .text.* .gnu.linkonce.t.*)
+ *(.text.unlikely .text.*_unlikely)
KEEP (*(.text.*personality*))
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
} =0x90909090
+ .init :
+ {
+ KEEP (*(.init))
+ } =0x90909090
.fini :
{
KEEP (*(.fini))
@@ -37,39 +36,35 @@ SECTIONS
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = .);
.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.init : { *(.rel.init) }
- .rela.init : { *(.rela.init) }
.rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
- .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
.rel.fini : { *(.rel.fini) }
- .rela.fini : { *(.rela.fini) }
.rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
- .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
.rel.data.rel.ro : { *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*) }
- .rela.data.rel.ro : { *(.rela.data.rel.ro* .rela.gnu.linkonce.d.rel.ro.*) }
.rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
- .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
.rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
- .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
.rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
- .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
.rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
.rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
.rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
- .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
-
+ .rel.ifunc : { *(.rel.ifunc) }
+ .rel.plt :
+ {
+ *(.rel.plt)
+ PROVIDE_HIDDEN (__rel_iplt_start = .);
+ *(.rel.iplt)
+ PROVIDE_HIDDEN (__rel_iplt_end = .);
+ }
+ .plt : { *(.plt) *(.iplt) }
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.eh_frame_hdr : { *(.eh_frame_hdr) }
@@ -77,7 +72,7 @@ SECTIONS
.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 (0x1000) - ((0x1000 - .) & (0x1000 - 1)); . = DATA_SEGMENT_ALIGN (0x1000, 0x1000);
+ . = 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.*) }
@@ -100,8 +95,8 @@ SECTIONS
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
- KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
+ KEEP (*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
}
.ctors :
@@ -115,32 +110,33 @@ SECTIONS
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
- KEEP (*crtbegin*.o(.ctors))
+ 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 ) .ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
- KEEP (*crtbegin*.o(.dtors))
- KEEP (*(EXCLUDE_FILE (*crtend*.o ) .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) }
+ .got : { *(.got) *(.igot) }
. = DATA_SEGMENT_RELRO_END (12, .);
- .got.plt : { *(.got.plt) }
+ .got.plt : { *(.got.plt) *(.igot.plt) }
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
- KEEP (*(.gnu.linkonce.d.*personality*))
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
@@ -195,5 +191,9 @@ SECTIONS
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
- /DISCARD/ : { *(.note.GNU-stack) }
+ /* DWARF 3 */
+ .debug_pubtypes 0 : { *(.debug_pubtypes) }
+ .debug_ranges 0 : { *(.debug_ranges) }
+ .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+ /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
}
diff --git a/i386/xen/xen_boothdr.S b/i386/xen/xen_boothdr.S
index 3d84e0c..604e13b 100644
--- a/i386/xen/xen_boothdr.S
+++ b/i386/xen/xen_boothdr.S
@@ -90,6 +90,23 @@ _start:
subl $KERNELBASE,%esi
pushl %esi
+ /* Fix ifunc entries */
+ movl $__rel_iplt_start,%esi
+ movl $__rel_iplt_end,%edi
+iplt_cont:
+ cmpl %edi,%esi
+ jae iplt_done
+ movl (%esi),%ebx /* r_offset */
+ movb 4(%esi),%al /* info */
+ cmpb $42,%al /* IRELATIVE */
+ jnz iplt_next
+ call *(%ebx) /* call ifunc */
+ movl %eax,(%ebx) /* fixed address */
+iplt_next:
+ addl $8,%esi
+ jmp iplt_cont
+iplt_done:
+
/* Jump into C code. */
call EXT(c_boot_entry)