Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/libexec/ld.elf_so/arch/alpha Implement _rtld_relocate_nonplt...
details: https://anonhg.NetBSD.org/src/rev/7f8cacfa37b0
branches: trunk
changeset: 536226:7f8cacfa37b0
user: mycroft <mycroft%NetBSD.org@localhost>
date: Wed Sep 11 18:18:37 2002 +0000
description:
Implement _rtld_relocate_nonplt_self() on Alpha.
diffstat:
libexec/ld.elf_so/arch/alpha/alpha_reloc.c | 54 ++++++++++++++++++++---------
libexec/ld.elf_so/arch/alpha/rtld_start.S | 41 +++++-----------------
2 files changed, 46 insertions(+), 49 deletions(-)
diffs (163 lines):
diff -r 8a984f2dad90 -r 7f8cacfa37b0 libexec/ld.elf_so/arch/alpha/alpha_reloc.c
--- a/libexec/ld.elf_so/arch/alpha/alpha_reloc.c Wed Sep 11 17:23:23 2002 +0000
+++ b/libexec/ld.elf_so/arch/alpha/alpha_reloc.c Wed Sep 11 18:18:37 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: alpha_reloc.c,v 1.14 2002/09/08 02:48:28 thorpej Exp $ */
+/* $NetBSD: alpha_reloc.c,v 1.15 2002/09/11 18:18:37 mycroft Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -72,6 +72,8 @@
#define adbg(x) /* nothing */
#endif
+void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr);
+
void
_rtld_setup_pltgot(const Obj_Entry *obj)
{
@@ -133,6 +135,33 @@
__asm __volatile("imb");
}
+void
+_rtld_relocate_nonplt_self(dynp, relocbase)
+ Elf_Dyn *dynp;
+ Elf_Addr relocbase;
+{
+ const Elf_Rela *rela = 0, *relalim;
+ Elf_Addr relasz = 0;
+ Elf_Addr *where;
+
+ for (; dynp->d_tag != DT_NULL; dynp++) {
+ switch (dynp->d_tag) {
+ case DT_RELA:
+ rela = (const Elf_Rela *)(relocbase + dynp->d_un.d_ptr);
+ break;
+ case DT_RELASZ:
+ relasz = dynp->d_un.d_val;
+ break;
+ }
+ }
+ relalim = (const Elf_Rela *)((caddr_t)rela + relasz);
+ for (; rela < relalim; rela++) {
+ where = (Elf_Addr *)(relocbase + rela->r_offset);
+ /* XXX For some reason I see a few GLOB_DAT relocs here. */
+ *where += (Elf_Addr)relocbase;
+ }
+}
+
int
_rtld_relocate_nonplt_objects(obj, self, dodebug)
const Obj_Entry *obj;
@@ -141,6 +170,9 @@
{
const Elf_Rela *rela;
+ if (self)
+ return 0;
+
for (rela = obj->rela; rela < obj->relalim; rela++) {
Elf_Addr *where;
const Elf_Sym *def;
@@ -184,22 +216,10 @@
break;
case R_TYPE(RELATIVE):
- {
- extern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
- extern Elf_Addr _GOT_END_[];
-
- /* This is the ...iffy hueristic. */
- if (!self ||
- (caddr_t)where < (caddr_t)_GLOBAL_OFFSET_TABLE_ ||
- (caddr_t)where >= (caddr_t)_GOT_END_) {
- *where += (Elf_Addr)obj->relocbase;
- rdbg(dodebug, ("RELATIVE in %s --> %p",
- obj->path, (void *)*where));
- } else
- rdbg(dodebug, ("RELATIVE in %s stays at %p",
- obj->path, (void *)*where));
+ *where += (Elf_Addr)obj->relocbase;
+ rdbg(dodebug, ("RELATIVE in %s --> %p",
+ obj->path, (void *)*where));
break;
- }
case R_TYPE(COPY):
/*
@@ -398,7 +418,7 @@
if (-0x100000 <= idisp && idisp < 0x100000) {
insn[insncnt++] = 0x30 << 26 | 31 << 21 |
(idisp & 0x1fffff);
- rdbg(dodebug, (" BR $31,%p", (void *)target));
+ rdbg(dodebug, (" BR $31,%p", (void *)new_value));
} else {
insn[insncnt++] = 0x1a << 26 | 31 << 21 |
27 << 16 | (idisp & 0x3fff);
diff -r 8a984f2dad90 -r 7f8cacfa37b0 libexec/ld.elf_so/arch/alpha/rtld_start.S
--- a/libexec/ld.elf_so/arch/alpha/rtld_start.S Wed Sep 11 17:23:23 2002 +0000
+++ b/libexec/ld.elf_so/arch/alpha/rtld_start.S Wed Sep 11 18:18:37 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld_start.S,v 1.10 2002/09/08 02:48:28 thorpej Exp $ */
+/* $NetBSD: rtld_start.S,v 1.11 2002/09/11 18:18:37 mycroft Exp $ */
/*
* Copyright 1996 Matt Thomas <matt%3am-software.com@localhost>
@@ -30,7 +30,6 @@
#include <machine/asm.h>
.extern _GLOBAL_OFFSET_TABLE_
- .extern _GOT_END_
/*
* Note: we can call ourselves LEAF even though we use callee-saved
@@ -41,40 +40,18 @@
br pv, 1f
1: LDGP(pv)
- /* XXX Partially relocate ourself. */
-
- /* Step 1 -- Figure out the displacement */
-
+ /*
+ * Relocate ourself.
+ */
br t2, 2f /* get our PC */
2: ldiq t3, 2b /* get where the linker thought we were */
- subq t2, t3, t8 /* calculate the displacement */
-
-
- /* Step 2 -- Find bounds of global offset table */
-
- lda t5, _GLOBAL_OFFSET_TABLE_
- addq t8, t5, t9 /* add the displacement */
- lda t4, _GOT_END_ /* Get the address of the end of the GOT */
- addq t8, t4, t10 /* add the displacement */
+ subq t2, t3, a1 /* calculate the displacement */
- /*
- * Step 3 -- Every entry in the global offset table needs to
- * modified for the displacement before any code will work.
- */
+ lda t5, _DYNAMIC
+ addq a1, t5, a0 /* add the displacement */
-3: ldq t1, 0(t9) /* load the value */
- addq t8, t1, t1 /* add the displacement */
- stq t1, 0(t9) /* save the new value */
- lda t9, 8(t9) /* point to next entry */
- cmpult t9, t10, t1 /* are we done? */
- bne t1, 3b /* no, do more */
-
- /*
- * Ya! Things are far enough so we can do some dynamic linking!
- */
-
- /* Squirrel away ps_strings. */
- mov a3, s0
+ bsr ra, _rtld_relocate_nonplt_self
+ LDGP(ra)
/*
* Allocate space on the stack for the cleanup and obj_main
Home |
Main Index |
Thread Index |
Old Index