diff options
author | John Polstra <jdp@FreeBSD.org> | 1999-04-09 00:28:43 +0000 |
---|---|---|
committer | John Polstra <jdp@FreeBSD.org> | 1999-04-09 00:28:43 +0000 |
commit | d5b537d01a6711c4426da2a627b11a71cf3b11e8 (patch) | |
tree | fb707dedb5110cb675ca69b3f246fd2e79ffce0d /libexec/rtld-elf | |
parent | c98a60baa7fa0f18b4e19106ec135031c0d51723 (diff) | |
download | src-d5b537d01a6711c4426da2a627b11a71cf3b11e8.tar.gz src-d5b537d01a6711c4426da2a627b11a71cf3b11e8.zip |
Eliminate all machine-dependent code from the main source body and
the Makefile, and move it down into the architecture-specific
subdirectories.
Eliminate an asm() statement for the i386.
Make the dynamic linker work if it is built as an executable instead
of as a shared library. See i386/Makefile.inc to find out how to
do it. Note, this change is not enabled and it might never be
enabled. But it might be useful in the future. Building the
dynamic linker as an executable should make it start up faster,
because it won't have any relocations. But in practice I suspect
the difference is negligible.
Notes
Notes:
svn path=/head/; revision=45501
Diffstat (limited to 'libexec/rtld-elf')
-rw-r--r-- | libexec/rtld-elf/Makefile | 39 | ||||
-rw-r--r-- | libexec/rtld-elf/alpha/Makefile.inc | 1 | ||||
-rw-r--r-- | libexec/rtld-elf/alpha/reloc.c | 15 | ||||
-rw-r--r-- | libexec/rtld-elf/alpha/rtld_machdep.h | 35 | ||||
-rw-r--r-- | libexec/rtld-elf/amd64/Makefile.inc | 5 | ||||
-rw-r--r-- | libexec/rtld-elf/amd64/elf_rtld.x | 131 | ||||
-rw-r--r-- | libexec/rtld-elf/amd64/reloc.c | 12 | ||||
-rw-r--r-- | libexec/rtld-elf/amd64/rtld_machdep.h | 36 | ||||
-rw-r--r-- | libexec/rtld-elf/i386/Makefile.inc | 5 | ||||
-rw-r--r-- | libexec/rtld-elf/i386/elf_rtld.x | 131 | ||||
-rw-r--r-- | libexec/rtld-elf/i386/reloc.c | 12 | ||||
-rw-r--r-- | libexec/rtld-elf/i386/rtld_machdep.h | 36 | ||||
-rw-r--r-- | libexec/rtld-elf/rtld.c | 106 | ||||
-rw-r--r-- | libexec/rtld-elf/rtld.h | 12 |
14 files changed, 488 insertions, 88 deletions
diff --git a/libexec/rtld-elf/Makefile b/libexec/rtld-elf/Makefile index f6a10544abea..bceb2a27d02c 100644 --- a/libexec/rtld-elf/Makefile +++ b/libexec/rtld-elf/Makefile @@ -1,25 +1,40 @@ # -# $Id: Makefile,v 1.4 1998/09/04 19:03:57 dfr Exp $ +# $Id: Makefile,v 1.5 1999/02/15 05:02:54 nate Exp $ # - PROG= ld-elf.so.1 SRCS= rtld_start.S rtld.c map_object.c malloc.c xmalloc.c debug.c \ reloc.c NOMAN= true -CFLAGS+= -fpic -Wall -DFREEBSD_ELF -I${.CURDIR} -LDADD+= -lc_pic +CFLAGS+= -Wall -DFREEBSD_ELF -I${.CURDIR}/${MACHINE_ARCH} -I${.CURDIR} +LDFLAGS+= -nostdlib -e .rtld_start +INSTALLFLAGS+= -fschg -C +.if exists(${.CURDIR}/${MACHINE_ARCH}/Makefile.inc) +.include "${.CURDIR}/${MACHINE_ARCH}/Makefile.inc" +.endif -.if ${MACHINE_ARCH} == "alpha" -CFLAGS+= -mno-fp-regs -LDFLAGS+= -nostdlib -Wl,-Bshareable,-Bsymbolic -e .rtld_start -.elif ${MACHINE_ARCH} == "i386" -CFLAGS+= -elf -LDFLAGS+= -elf -nostdlib -Wl,-Bshareable,-Bsymbolic +# If LDSCRIPT is defined, we build the dynamic linker as an +# executable. Otherwise we build it as a shared object. We ignore +# LDSCRIPT if the running kernel is too old to support it. +.if defined(LDSCRIPT) +KERN_OSRELDATE!= /sbin/sysctl -n kern.osreldate 2>/dev/null || echo 0 +.if ${KERN_OSRELDATE} >= 400001 +LDSO_IS_EXECUTABLE= yes +.endif .endif -# Atomic installation with "-C" is very important for this program. -INSTALLFLAGS+= -fschg -C +.ifdef LDSO_IS_EXECUTABLE +OBJS+= dyn_hack.so +LDFLAGS+= -Wl,-T,${LDSCRIPT} -Wl,-E -Wl,-Bstatic +LDADD+= -lc +.else +CFLAGS+= -fpic -DPIC +LDFLAGS+= -shared -Wl,-Bsymbolic +LDADD+= -lc_pic +.endif + +dyn_hack.so: + ${CC} -shared -nostdlib -o dyn_hack.so -x c /dev/null .PATH: ${.CURDIR}/${MACHINE_ARCH} diff --git a/libexec/rtld-elf/alpha/Makefile.inc b/libexec/rtld-elf/alpha/Makefile.inc new file mode 100644 index 000000000000..c764115abdae --- /dev/null +++ b/libexec/rtld-elf/alpha/Makefile.inc @@ -0,0 +1 @@ +CFLAGS+= -mno-fp-regs diff --git a/libexec/rtld-elf/alpha/reloc.c b/libexec/rtld-elf/alpha/reloc.c index c88162c97efa..e5837b81ec6a 100644 --- a/libexec/rtld-elf/alpha/reloc.c +++ b/libexec/rtld-elf/alpha/reloc.c @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: reloc.c,v 1.2 1998/09/08 09:47:35 dfr Exp $ + * $Id: reloc.c,v 1.3 1998/09/11 18:30:55 dfr Exp $ */ /* @@ -307,3 +307,16 @@ do_copy_relocations(Obj_Entry *dstobj) return 0; } + +/* Initialize the special PLT entries. */ +void +init_pltgot(Obj_Entry *obj) +{ + if (obj->pltgot != NULL && + (obj->pltrelsize != 0 || obj->pltrelasize != 0)) { + /* This function will be called to perform the relocation. */ + obj->pltgot[2] = (Elf_Addr) &_rtld_bind_start; + /* Identify this shared object */ + obj->pltgot[3] = (Elf_Addr) obj; + } +} diff --git a/libexec/rtld-elf/alpha/rtld_machdep.h b/libexec/rtld-elf/alpha/rtld_machdep.h new file mode 100644 index 000000000000..03632b677dd5 --- /dev/null +++ b/libexec/rtld-elf/alpha/rtld_machdep.h @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 1999 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#ifndef RTLD_MACHDEP_H +#define RTLD_MACHDEP_H 1 + +/* Return the address of the .dynamic section in the dynamic linker. */ +#define rtld_dynamic(obj) (&_DYNAMIC) + +#endif diff --git a/libexec/rtld-elf/amd64/Makefile.inc b/libexec/rtld-elf/amd64/Makefile.inc new file mode 100644 index 000000000000..ba39193cf89a --- /dev/null +++ b/libexec/rtld-elf/amd64/Makefile.inc @@ -0,0 +1,5 @@ +CFLAGS+= -elf +LDFLAGS+= -elf +# Uncomment this to build the dynamic linker as an executable instead +# of a shared library: +#LDSCRIPT= ${.CURDIR}/${MACHINE_ARCH}/elf_rtld.x diff --git a/libexec/rtld-elf/amd64/elf_rtld.x b/libexec/rtld-elf/amd64/elf_rtld.x new file mode 100644 index 000000000000..e19168cb8808 --- /dev/null +++ b/libexec/rtld-elf/amd64/elf_rtld.x @@ -0,0 +1,131 @@ +OUTPUT_FORMAT("elf32-i386", "elf32-i386", + "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) +SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/obj/usr/src/tmp/usr/i386-unknown-freebsdelf/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0x08000000 + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.text : + { *(.rel.text) *(.rel.gnu.linkonce.t*) } + .rela.text : + { *(.rela.text) *(.rela.gnu.linkonce.t*) } + .rel.data : + { *(.rel.data) *(.rel.gnu.linkonce.d*) } + .rela.data : + { *(.rela.data) *(.rela.gnu.linkonce.d*) } + .rel.rodata : + { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } + .rela.rodata : + { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } =0x9090 + .plt : { *(.plt) } + .text : + { + *(.text) + *(.stub) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t*) + } =0x9090 + _etext = .; + PROVIDE (etext = .); + .fini : { *(.fini) } =0x9090 + .rodata : { *(.rodata) *(.gnu.linkonce.r*) } + .rodata1 : { *(.rodata1) } + /* 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 - 1)); + .data : + { + *(.data) + *(.gnu.linkonce.d*) + CONSTRUCTORS + } + .data1 : { *(.data1) } + .ctors : + { + *(.ctors) + } + .dtors : + { + *(.dtors) + } + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : + { + *(.dynbss) + *(.bss) + *(COMMON) + } + . = ALIGN(32 / 8); + _end = . ; + PROVIDE (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) } + .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) } + /* These must appear regardless of . */ +} diff --git a/libexec/rtld-elf/amd64/reloc.c b/libexec/rtld-elf/amd64/reloc.c index d34d892b9036..82c0e8e13578 100644 --- a/libexec/rtld-elf/amd64/reloc.c +++ b/libexec/rtld-elf/amd64/reloc.c @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: rtld.c,v 1.3 1998/05/01 08:39:27 dfr Exp $ + * $Id: reloc.c,v 1.1 1998/09/04 19:03:57 dfr Exp $ */ /* @@ -107,6 +107,16 @@ do_copy_relocations(Obj_Entry *dstobj) return 0; } +/* Initialize the special GOT entries. */ +void +init_pltgot(Obj_Entry *obj) +{ + if (obj->pltgot != NULL) { + obj->pltgot[1] = (Elf_Addr) obj; + obj->pltgot[2] = (Elf_Addr) &_rtld_bind_start; + } +} + /* Process the non-PLT relocations. */ int reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld) diff --git a/libexec/rtld-elf/amd64/rtld_machdep.h b/libexec/rtld-elf/amd64/rtld_machdep.h new file mode 100644 index 000000000000..89a93222c1a4 --- /dev/null +++ b/libexec/rtld-elf/amd64/rtld_machdep.h @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 1999 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#ifndef RTLD_MACHDEP_H +#define RTLD_MACHDEP_H 1 + +/* Return the address of the .dynamic section in the dynamic linker. */ +#define rtld_dynamic(obj) \ + ((const Elf_Dyn *)((obj)->relocbase + (Elf_Addr)&_DYNAMIC)) + +#endif diff --git a/libexec/rtld-elf/i386/Makefile.inc b/libexec/rtld-elf/i386/Makefile.inc new file mode 100644 index 000000000000..ba39193cf89a --- /dev/null +++ b/libexec/rtld-elf/i386/Makefile.inc @@ -0,0 +1,5 @@ +CFLAGS+= -elf +LDFLAGS+= -elf +# Uncomment this to build the dynamic linker as an executable instead +# of a shared library: +#LDSCRIPT= ${.CURDIR}/${MACHINE_ARCH}/elf_rtld.x diff --git a/libexec/rtld-elf/i386/elf_rtld.x b/libexec/rtld-elf/i386/elf_rtld.x new file mode 100644 index 000000000000..e19168cb8808 --- /dev/null +++ b/libexec/rtld-elf/i386/elf_rtld.x @@ -0,0 +1,131 @@ +OUTPUT_FORMAT("elf32-i386", "elf32-i386", + "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) +SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/obj/usr/src/tmp/usr/i386-unknown-freebsdelf/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0x08000000 + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.text : + { *(.rel.text) *(.rel.gnu.linkonce.t*) } + .rela.text : + { *(.rela.text) *(.rela.gnu.linkonce.t*) } + .rel.data : + { *(.rel.data) *(.rel.gnu.linkonce.d*) } + .rela.data : + { *(.rela.data) *(.rela.gnu.linkonce.d*) } + .rel.rodata : + { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } + .rela.rodata : + { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } =0x9090 + .plt : { *(.plt) } + .text : + { + *(.text) + *(.stub) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t*) + } =0x9090 + _etext = .; + PROVIDE (etext = .); + .fini : { *(.fini) } =0x9090 + .rodata : { *(.rodata) *(.gnu.linkonce.r*) } + .rodata1 : { *(.rodata1) } + /* 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 - 1)); + .data : + { + *(.data) + *(.gnu.linkonce.d*) + CONSTRUCTORS + } + .data1 : { *(.data1) } + .ctors : + { + *(.ctors) + } + .dtors : + { + *(.dtors) + } + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : + { + *(.dynbss) + *(.bss) + *(COMMON) + } + . = ALIGN(32 / 8); + _end = . ; + PROVIDE (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) } + .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) } + /* These must appear regardless of . */ +} diff --git a/libexec/rtld-elf/i386/reloc.c b/libexec/rtld-elf/i386/reloc.c index d34d892b9036..82c0e8e13578 100644 --- a/libexec/rtld-elf/i386/reloc.c +++ b/libexec/rtld-elf/i386/reloc.c @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: rtld.c,v 1.3 1998/05/01 08:39:27 dfr Exp $ + * $Id: reloc.c,v 1.1 1998/09/04 19:03:57 dfr Exp $ */ /* @@ -107,6 +107,16 @@ do_copy_relocations(Obj_Entry *dstobj) return 0; } +/* Initialize the special GOT entries. */ +void +init_pltgot(Obj_Entry *obj) +{ + if (obj->pltgot != NULL) { + obj->pltgot[1] = (Elf_Addr) obj; + obj->pltgot[2] = (Elf_Addr) &_rtld_bind_start; + } +} + /* Process the non-PLT relocations. */ int reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld) diff --git a/libexec/rtld-elf/i386/rtld_machdep.h b/libexec/rtld-elf/i386/rtld_machdep.h new file mode 100644 index 000000000000..89a93222c1a4 --- /dev/null +++ b/libexec/rtld-elf/i386/rtld_machdep.h @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 1999 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#ifndef RTLD_MACHDEP_H +#define RTLD_MACHDEP_H 1 + +/* Return the address of the .dynamic section in the dynamic linker. */ +#define rtld_dynamic(obj) \ + ((const Elf_Dyn *)((obj)->relocbase + (Elf_Addr)&_DYNAMIC)) + +#endif diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 5faa5d73809d..8aff91cc3160 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: rtld.c,v 1.18 1999/04/07 02:43:11 jdp Exp $ + * $Id: rtld.c,v 1.19 1999/04/07 02:48:43 jdp Exp $ */ /* @@ -105,23 +105,6 @@ void xprintf(const char *, ...); static const char *basename(const char *); #endif -/* Assembly language entry point for lazy binding. */ -extern void _rtld_bind_start(void); - -/* - * Assembly language macro for getting the GOT pointer. - */ -#ifdef __i386__ -#define get_got_address() \ - ({ Elf_Addr *thegot; \ - __asm__("movl %%ebx,%0" : "=rm"(thegot)); \ - thegot; }) -#elif __alpha__ -#define get_got_address() NULL -#else -#error "This file only supports the i386 and alpha architectures" -#endif - /* * Data declarations. */ @@ -146,7 +129,7 @@ static Elf_Sym sym_zero; /* For resolving undefined weak refs. */ #define GDB_STATE(s) r_debug.r_state = s; r_debug_state(); extern Elf_Dyn _DYNAMIC; - +#pragma weak _DYNAMIC /* * These are the functions the dynamic linker exports to application @@ -243,6 +226,8 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) debug = 1; dbg("%s is initialized, base address = %p", __progname, (caddr_t) aux_info[AT_BASE]->a_un.a_ptr); + dbg("RTLD dynamic = %p", obj_rtld.dynamic); + dbg("RTLD pltgot = %p", obj_rtld.pltgot); /* * Load the main program, or process its program header if it is @@ -491,8 +476,7 @@ digest_dynamic(Obj_Entry *obj) break; case DT_NEEDED: - assert(!obj->rtld); - { + if (!obj->rtld) { Needed_Entry *nep = NEW(Needed_Entry); nep->name = dynp->d_un.d_val; nep->obj = NULL; @@ -504,7 +488,7 @@ digest_dynamic(Obj_Entry *obj) break; case DT_PLTGOT: - obj->got = (Elf_Addr *) (obj->relocbase + dynp->d_un.d_ptr); + obj->pltgot = (Elf_Addr *) (obj->relocbase + dynp->d_un.d_ptr); break; case DT_TEXTREL: @@ -841,30 +825,24 @@ init_rtld(caddr_t mapbase) obj_rtld.path = "/usr/libexec/ld-elf.so.1"; obj_rtld.rtld = true; obj_rtld.mapbase = mapbase; +#ifdef PIC obj_rtld.relocbase = mapbase; - obj_rtld.got = get_got_address(); -#ifdef __alpha__ - obj_rtld.dynamic = (const Elf_Dyn *) &_DYNAMIC; -#else - obj_rtld.dynamic = (const Elf_Dyn *) (obj_rtld.mapbase + obj_rtld.got[0]); #endif + if (&_DYNAMIC != 0) { + obj_rtld.dynamic = rtld_dynamic(&obj_rtld); + digest_dynamic(&obj_rtld); + assert(obj_rtld.needed == NULL); + assert(!obj_rtld.textrel); - digest_dynamic(&obj_rtld); -#ifdef __alpha__ -/* XXX XXX XXX */ -obj_rtld.got = NULL; -#endif - assert(obj_rtld.needed == NULL); - assert(!obj_rtld.textrel); - - /* - * Temporarily put the dynamic linker entry into the object list, so - * that symbols can be found. - */ - obj_list = &obj_rtld; - obj_tail = &obj_rtld.next; + /* + * Temporarily put the dynamic linker entry into the object list, so + * that symbols can be found. + */ + obj_list = &obj_rtld; + obj_tail = &obj_rtld.next; - relocate_objects(&obj_rtld, true); + relocate_objects(&obj_rtld, true); + } /* Make the object list empty again. */ obj_list = NULL; @@ -1074,19 +1052,8 @@ relocate_objects(Obj_Entry *first, bool bind_now) obj->magic = RTLD_MAGIC; obj->version = RTLD_VERSION; - /* Set the special GOT entries. */ - if (obj->got) { -#ifdef __i386__ - obj->got[1] = (Elf_Addr) obj; - obj->got[2] = (Elf_Addr) &_rtld_bind_start; -#endif -#ifdef __alpha__ - /* This function will be called to perform the relocation. */ - obj->got[2] = (Elf_Addr) &_rtld_bind_start; - /* Identify this shared object */ - obj->got[3] = (Elf_Addr) obj; -#endif - } + /* Set the special PLT or GOT entries. */ + init_pltgot(obj); } return 0; @@ -1410,25 +1377,26 @@ const Elf_Sym * symlook_obj(const char *name, unsigned long hash, const Obj_Entry *obj, bool in_plt) { - unsigned long symnum = obj->buckets[hash % obj->nbuckets]; + if (obj->buckets != NULL) { + unsigned long symnum = obj->buckets[hash % obj->nbuckets]; - while (symnum != STN_UNDEF) { - const Elf_Sym *symp; - const char *strp; + while (symnum != STN_UNDEF) { + const Elf_Sym *symp; + const char *strp; - assert(symnum < obj->nchains); - symp = obj->symtab + symnum; - assert(symp->st_name != 0); - strp = obj->strtab + symp->st_name; + assert(symnum < obj->nchains); + symp = obj->symtab + symnum; + assert(symp->st_name != 0); + strp = obj->strtab + symp->st_name; - if (strcmp(name, strp) == 0) - return symp->st_shndx != SHN_UNDEF || - (!in_plt && symp->st_value != 0 && - ELF_ST_TYPE(symp->st_info) == STT_FUNC) ? symp : NULL; + if (strcmp(name, strp) == 0) + return symp->st_shndx != SHN_UNDEF || + (!in_plt && symp->st_value != 0 && + ELF_ST_TYPE(symp->st_info) == STT_FUNC) ? symp : NULL; - symnum = obj->chains[symnum]; + symnum = obj->chains[symnum]; + } } - return NULL; } diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h index f1a9afd4ead6..1380e74218ad 100644 --- a/libexec/rtld-elf/rtld.h +++ b/libexec/rtld-elf/rtld.h @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: rtld.h,v 1.4 1998/09/02 02:51:12 jdp Exp $ + * $Id: rtld.h,v 1.5 1998/09/04 19:03:57 dfr Exp $ */ #ifndef RTLD_H /* { */ @@ -34,6 +34,8 @@ #include <elf.h> #include <stddef.h> +#include "rtld_machdep.h" + #ifndef STANDARD_LIBRARY_PATH #define STANDARD_LIBRARY_PATH "/usr/lib/elf:/usr/lib" #endif @@ -85,7 +87,7 @@ typedef struct Struct_Obj_Entry { size_t phsize; /* Size of program header in bytes */ /* Items from the dynamic section. */ - Elf_Addr *got; /* GOT table */ + Elf_Addr *pltgot; /* PLT or GOT, depending on architecture */ const Elf_Rel *rel; /* Relocation entries */ unsigned long relsize; /* Size in bytes of relocation info */ const Elf_Rela *rela; /* Relocation entries with addend */ @@ -132,11 +134,13 @@ extern Elf_Addr _GLOBAL_OFFSET_TABLE_[]; * Function declarations. */ int do_copy_relocations(Obj_Entry *); -int reloc_non_plt(Obj_Entry *, Obj_Entry *); -int reloc_plt(Obj_Entry *, bool); unsigned long elf_hash(const char *); const Elf_Sym *find_symdef(unsigned long, const Obj_Entry *, const Obj_Entry **, bool); +void init_pltgot(Obj_Entry *); +int reloc_non_plt(Obj_Entry *, Obj_Entry *); +int reloc_plt(Obj_Entry *, bool); +void _rtld_bind_start(void); const Elf_Sym *symlook_obj(const char *, unsigned long, const Obj_Entry *, bool); |