diff options
author | peter <peter@FreeBSD.org> | 2002-02-18 02:24:10 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2002-02-18 02:24:10 +0000 |
commit | cc757467188b1933c356a3895eb1032d3f428a83 (patch) | |
tree | e6a2e3b5fdf668ea328e132a7ec844ff3c60d305 /libexec/rtld-elf/alpha/reloc.c | |
parent | bf46cf3a970cc30c6a24905a3b0fe51de08e976d (diff) | |
download | FreeBSD-src-cc757467188b1933c356a3895eb1032d3f428a83.zip FreeBSD-src-cc757467188b1933c356a3895eb1032d3f428a83.tar.gz |
ld-elf.so.1 assumed a few too many things about the ordering of sections
produced by ld(8) (ie: that _DYNAMIC immediately follows the _GOT).
The new binutils import changed that, and the intial GOT relocation
broke. Use a custom linker script to provide a real end-of-GOT symbol.
Update ld.so to deal with the new (faster) PLT format that gcc-3.1 and
binutils can produce.
This is probably incomplete, but appears to be working again.
Obtained from: NetBSD
(And a fix to a silly mistake that I made by: gallatin)
Diffstat (limited to 'libexec/rtld-elf/alpha/reloc.c')
-rw-r--r-- | libexec/rtld-elf/alpha/reloc.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/libexec/rtld-elf/alpha/reloc.c b/libexec/rtld-elf/alpha/reloc.c index 7709589..882a8ac 100644 --- a/libexec/rtld-elf/alpha/reloc.c +++ b/libexec/rtld-elf/alpha/reloc.c @@ -47,7 +47,7 @@ #include "debug.h" #include "rtld.h" -extern Elf_Dyn _DYNAMIC; +extern Elf_Dyn _GOT_END_; /* * Macros for loading/storing unaligned 64-bit values. These are @@ -111,7 +111,7 @@ reloc_non_plt_obj(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela, case R_ALPHA_RELATIVE: { if (obj != obj_rtld || (caddr_t)where < (caddr_t)_GLOBAL_OFFSET_TABLE_ || - (caddr_t)where >= (caddr_t)&_DYNAMIC) + (caddr_t)where >= (caddr_t)&_GOT_END_) store64(where, load64(where) + (Elf_Addr) obj->relocbase); } @@ -476,10 +476,20 @@ do_copy_relocations(Obj_Entry *dstobj) void init_pltgot(Obj_Entry *obj) { + u_int32_t *pltgot; + 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; + /* + * This function will be called to perform the relocation. + * Look for the ldah instruction from the old PLT format since + * that will tell us what format we are trying to relocate. + */ + pltgot = (u_int32_t *) obj->pltgot; + if ((pltgot[8] & 0xffff0000) == 0x279f0000) + obj->pltgot[2] = (Elf_Addr) &_rtld_bind_start_old; + else + obj->pltgot[2] = (Elf_Addr) &_rtld_bind_start; /* Identify this shared object */ obj->pltgot[3] = (Elf_Addr) obj; } |