summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-elf/alpha/reloc.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2002-02-18 02:24:10 +0000
committerpeter <peter@FreeBSD.org>2002-02-18 02:24:10 +0000
commitcc757467188b1933c356a3895eb1032d3f428a83 (patch)
treee6a2e3b5fdf668ea328e132a7ec844ff3c60d305 /libexec/rtld-elf/alpha/reloc.c
parentbf46cf3a970cc30c6a24905a3b0fe51de08e976d (diff)
downloadFreeBSD-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.c18
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;
}
OpenPOWER on IntegriCloud