From 1a399a2e7d8d7fe218e25ec0015b939ccb1ad2f8 Mon Sep 17 00:00:00 2001 From: Dale Rahn Date: Wed, 9 Jul 2003 21:01:11 +0000 Subject: changes to ld.so to be compatible with newer binutils, requires slight changes in the startup code on most archs. ok art@ brad@ --- libexec/ld.so/alpha/archdep.h | 8 ++------ libexec/ld.so/alpha/ldasm.S | 3 ++- libexec/ld.so/i386/ldasm.S | 7 ++++--- libexec/ld.so/loader.c | 8 +++++--- libexec/ld.so/powerpc/ldasm.S | 36 +++++++++++++----------------------- libexec/ld.so/sparc/ldasm.S | 18 ++++++++++++++++-- libexec/ld.so/sparc64/ldasm.S | 20 +++++++++++++++++--- 7 files changed, 59 insertions(+), 41 deletions(-) (limited to 'libexec') diff --git a/libexec/ld.so/alpha/archdep.h b/libexec/ld.so/alpha/archdep.h index edca1ea1f01..89db202c6d9 100644 --- a/libexec/ld.so/alpha/archdep.h +++ b/libexec/ld.so/alpha/archdep.h @@ -1,4 +1,4 @@ -/* $OpenBSD: archdep.h,v 1.10 2003/06/09 16:10:03 deraadt Exp $ */ +/* $OpenBSD: archdep.h,v 1.11 2003/07/09 21:01:10 drahn Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -51,12 +51,8 @@ RELOC_REL(Elf64_Rel *r, const Elf64_Sym *s, Elf64_Addr *p, unsigned long v) static inline void RELOC_RELA(Elf64_Rela *r, const Elf64_Sym *s, Elf64_Addr *p, unsigned long v) { - extern Elf_Addr _GLOBAL_OFFSET_TABLE_[]; - if (ELF64_R_TYPE(r->r_info) == RELOC_RELATIVE) { - if ((caddr_t)p < (caddr_t)_GLOBAL_OFFSET_TABLE_ || - (caddr_t)p >= (caddr_t)&_DYNAMIC) - *p += (Elf_Addr)v; + /* handled by _reloc_alpha_got */ } else if (ELF64_R_TYPE(r->r_info) == RELOC_JMP_SLOT) { Elf64_Addr val = v + s->st_value + r->r_addend - (Elf64_Addr)(p); diff --git a/libexec/ld.so/alpha/ldasm.S b/libexec/ld.so/alpha/ldasm.S index 9338d62f1ef..91b25eadc57 100644 --- a/libexec/ld.so/alpha/ldasm.S +++ b/libexec/ld.so/alpha/ldasm.S @@ -1,4 +1,4 @@ -/* $OpenBSD: ldasm.S,v 1.14 2003/06/09 16:10:03 deraadt Exp $ */ +/* $OpenBSD: ldasm.S,v 1.15 2003/07/09 21:01:10 drahn Exp $ */ /* * Copyright (c) 2001 Niklas Hallqvist @@ -95,6 +95,7 @@ L2: ldiq s3, L2 /* get where the linker thought we were */ mov a5, s5 lda s2, 0(sp) mov s2, a1 + mov 0, a2 /* dynamicp is unused on alpha */ CALL(_dl_boot_bind) mov s3, a0 /* **argv */ mov s4, a1 /* **envp */ diff --git a/libexec/ld.so/i386/ldasm.S b/libexec/ld.so/i386/ldasm.S index b298e764b2e..2bc1bccaa91 100644 --- a/libexec/ld.so/i386/ldasm.S +++ b/libexec/ld.so/i386/ldasm.S @@ -1,4 +1,4 @@ -/* $OpenBSD: ldasm.S,v 1.6 2003/06/03 01:35:30 drahn Exp $ */ +/* $OpenBSD: ldasm.S,v 1.7 2003/07/09 21:01:10 drahn Exp $ */ /* * Copyright (c) 2002 Dale Rahn @@ -15,7 +15,7 @@ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WsdfARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS @@ -40,6 +40,7 @@ _dl_start: movl %esp,%eax # save stack pointer for _rtld pushl %ebx # save ps_strings subl $DL_DATA_SIZE,%esp # allocate dl_data + pushl $0 # push 0 for dynamicp (unused on i386) movl %esp,%ebx movl %ebx,%edi # save dl_data arg for dl_boot pushl %ebx # push dl_data for dl_boot_bind @@ -67,7 +68,7 @@ _dl_start: call _dl_boot@PLT # _dl_boot(argv,envp,loff,dl_data) - addl $4*4,%esp # pop args + addl $5*4,%esp # pop args addl $DL_DATA_SIZE,%esp # return dl_data diff --git a/libexec/ld.so/loader.c b/libexec/ld.so/loader.c index 1fdc48cb4e0..2299ad6027c 100644 --- a/libexec/ld.so/loader.c +++ b/libexec/ld.so/loader.c @@ -1,4 +1,4 @@ -/* $OpenBSD: loader.c,v 1.65 2003/07/06 20:03:57 deraadt Exp $ */ +/* $OpenBSD: loader.c,v 1.66 2003/07/09 21:01:10 drahn Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -51,7 +51,7 @@ unsigned long _dl_boot(const char **, char **, const long, long *); void _dl_debug_state(void); void _dl_setup_env(char **); void _dl_dtors(void); -void _dl_boot_bind(const long, long *); +void _dl_boot_bind(const long, long *, Elf_Dyn *); const char *_dl_progname; int _dl_pagesz; @@ -414,7 +414,7 @@ _dl_boot(const char **argv, char **envp, const long loff, long *dl_data) } void -_dl_boot_bind(const long sp, long *dl_data) +_dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynamicp) { struct elf_object dynld; /* Resolver data for the loader */ AuxInfo *auxstack; @@ -464,6 +464,8 @@ _dl_boot_bind(const long sp, long *dl_data) #if defined(__alpha__) dynp = (Elf_Dyn *)((long)_DYNAMIC); +#elif defined(__sparc__) || defined(__sparc64__) || defined(__powerpc__) + dynp = dynamicp; #else dynp = (Elf_Dyn *)((long)_DYNAMIC + loff); #endif diff --git a/libexec/ld.so/powerpc/ldasm.S b/libexec/ld.so/powerpc/ldasm.S index 0204a0e4a19..77df737bc40 100644 --- a/libexec/ld.so/powerpc/ldasm.S +++ b/libexec/ld.so/powerpc/ldasm.S @@ -1,4 +1,4 @@ -/* $OpenBSD: ldasm.S,v 1.12 2003/06/09 16:10:04 deraadt Exp $ */ +/* $OpenBSD: ldasm.S,v 1.13 2003/07/09 21:01:10 drahn Exp $ */ /* * Copyright (c) 1999 Dale Rahn @@ -26,15 +26,6 @@ * */ -/* - * #ifdef blrl_never_causes_illegal_access - * background for the else of this define - * On the machine this code is being written, on a large portion - * of the tims this code is executed the blrl instruct causes an - * illegal instruction, hopefully by touching the page with a load - * will prevent the execute access from faulting. - */ - #define AUX_entry 9 #include @@ -53,13 +44,11 @@ ENTRY(_dl_start) mr 22, 5 #envp mr 23, 6 # ??? - .local .L___offset_sym - .type .L___offset_sym,@function bl 1f -.L___offset_sym: # this instruction never gets executed but can be used # to find the virtual address where the page is loaded. bl _GLOBAL_OFFSET_TABLE_@local-4 + bl _DYNAMIC@local 1: mflr 5 # this stores where we are (+4) lwz 18, 0(5) # load the instruction at offset_sym @@ -94,21 +83,22 @@ ENTRY(_dl_start) sync isync - # calculate where we want to be (via the got) - bl _GLOBAL_OFFSET_TABLE_@local-4 - mflr 28 - - - lwz 4, .L___offset_sym@got(28) - mr 6, 4 # make copy of register for debugging - + /* This calculates the address of _DYNAMIC the same way + * that the GLOBAL_OFFSET_TABLE was calculated. + */ + lwz 18, 4(5) + rlwinm 18,18,0,8,30 # mask off the offset portion of the instr. + add 8, 18, 5 # address of _DYNAMIC (arg6 for _dl_boot) + addi 18, 8, 4 # correction. + lwz 4, 4(28) # load address of _DYNAMIC according to got. + sub 4, 18, 4 # determine load offset - sub 4, 5, 4 # calculate offset (arg1 for _dl_boot) - mr 17, 4 + mr 17, 4 # save for _dl_boot subi 3, 21, 4 # Get stack pointer (arg0 for _dl_boot). addi 4, 1, 8 # dl_data + mr 5, 18 # dynamicp bl _dl_boot_bind@local diff --git a/libexec/ld.so/sparc/ldasm.S b/libexec/ld.so/sparc/ldasm.S index fee9cdc9e7e..bbe50228e43 100644 --- a/libexec/ld.so/sparc/ldasm.S +++ b/libexec/ld.so/sparc/ldasm.S @@ -1,4 +1,4 @@ -/* $OpenBSD: ldasm.S,v 1.12 2003/06/02 20:20:35 jason Exp $ */ +/* $OpenBSD: ldasm.S,v 1.13 2003/07/09 21:01:10 drahn Exp $ */ /* * Copyright (c) 2001 Jason L. Wright (jason@thought.net) @@ -82,7 +82,21 @@ _dl_start: add %l3, DL_DATA_SIZE, %o0 mov %o0, %l0 - call _dl_boot_bind ! _dl_boot_bind(sp,dl_data) + + /* + * need to figure out where _DYNAMIC is located newer binutils + * does not fill in GOT to read _DYNAMIC before relocation. + */ + call 0f + nop + call _DYNAMIC+8 ! not executed (no delay needed) +0: ld [%o7+8], %o2 ! load stub call instruction + sll %o2, 2, %o2 ! extract PC offset + sra %o2, 0, %o2 ! sign-extend + + add %o2, %o7, %o2 ! real &_DYNAMIC + + call _dl_boot_bind ! _dl_boot_bind(sp,dl_data,dynamicp) mov %l3, %o1 mov %l3, %o3 diff --git a/libexec/ld.so/sparc64/ldasm.S b/libexec/ld.so/sparc64/ldasm.S index c0b1f7e730d..03201943cb3 100644 --- a/libexec/ld.so/sparc64/ldasm.S +++ b/libexec/ld.so/sparc64/ldasm.S @@ -1,4 +1,4 @@ -/* $OpenBSD: ldasm.S,v 1.19 2003/06/02 20:20:35 jason Exp $ */ +/* $OpenBSD: ldasm.S,v 1.20 2003/07/09 21:01:10 drahn Exp $ */ /* $NetBSD: rtld_start.S,v 1.5 2001/08/14 22:17:48 eeh Exp $ */ /* @@ -100,7 +100,21 @@ _dl_start: add %l3, DL_DATA_SIZE, %o0 mov %o0, %l0 - call _dl_boot_bind ! _dl_boot_bind(sp,dl_data) + + /* + * need to figure out where _DYNAMIC is located, newer binutils + * does not fill in GOT to read _DYNAMIC before relocation. + */ + call 0f + nop + call _DYNAMIC+8 ! not executed (no delay needed) +0: ld [%o7+8], %o2 ! load stub call instruction + sll %o2, 2, %o2 ! extract PC offset + sra %o2, 0, %o2 ! sign-extend + + add %o2, %o7, %o2 ! real &_DYNAMIC + + call _dl_boot_bind ! _dl_boot_bind(sp,dl_data,dynamicp) mov %l3, %o1 mov %l3, %o3 @@ -113,7 +127,7 @@ _dl_start: addx %o3, (7*8), %l2 ldx [%l2], %o2 ! loff = dl_data[AUX_base]; - call _dl_boot ! _dl_boot(argv,envp,loff,dynp,dl_data) + call _dl_boot ! _dl_boot(argv,envp,loff,dl_data) nop add %sp, DL_DATA_SIZE, %sp ! restore stack -- cgit v1.2.3