summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authormarcus <marcus@NetBSD.org>2003-06-30 00:50:46 +0000
committermarcus <marcus@NetBSD.org>2003-06-30 00:50:46 +0000
commit6aeeb40d4a0371dbf012b4f2ffbd0fdd1a8d615a (patch)
tree950758149c1fe48b7f41204c87ffba79099f329a /libexec
parent5404577abfb743e1ecaca06d3f3746ec0e672fc8 (diff)
Updated to work with current rtld code.
Diffstat (limited to 'libexec')
-rw-r--r--libexec/ld.elf_so/arch/sh3/mdreloc.c52
-rw-r--r--libexec/ld.elf_so/arch/sh3/rtld_start.S65
2 files changed, 76 insertions, 41 deletions
diff --git a/libexec/ld.elf_so/arch/sh3/mdreloc.c b/libexec/ld.elf_so/arch/sh3/mdreloc.c
index b6eda072963..6a101b53586 100644
--- a/libexec/ld.elf_so/arch/sh3/mdreloc.c
+++ b/libexec/ld.elf_so/arch/sh3/mdreloc.c
@@ -1,4 +1,4 @@
-/* $NetBSD: mdreloc.c,v 1.14 2002/10/03 20:39:23 mycroft Exp $ */
+/* $NetBSD: mdreloc.c,v 1.15 2003/06/30 00:50:46 marcus Exp $ */
#include <sys/types.h>
#include <sys/stat.h>
@@ -15,6 +15,30 @@ _rtld_setup_pltgot(const Obj_Entry *obj)
obj->pltgot[2] = (Elf_Addr) &_rtld_bind_start;
}
+void
+_rtld_relocate_nonplt_self(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);
+ *where = (Elf_Addr)(relocbase + rela->r_addend);
+ }
+}
+
int
_rtld_relocate_nonplt_objects(obj)
const Obj_Entry *obj;
@@ -152,6 +176,32 @@ _rtld_relocate_plt_lazy(obj)
return 0;
}
+caddr_t
+_rtld_bind(obj, reloff)
+ const Obj_Entry *obj;
+ Elf_Word reloff;
+{
+ const Elf_Rela *rela = (const Elf_Rela *)((caddr_t)obj->pltrela + reloff);
+ Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
+ Elf_Addr new_value;
+ const Elf_Sym *def;
+ const Obj_Entry *defobj;
+
+ assert(ELF_R_TYPE(rela->r_info) == R_TYPE(JMP_SLOT));
+
+ def = _rtld_find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, true);
+ if (def == NULL)
+ _rtld_die();
+
+ new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
+ rdbg(("bind now/fixup in %s --> old=%p new=%p",
+ defobj->strtab + def->st_name, (void *)*where, (void *)new_value));
+ if (*where != new_value)
+ *where = new_value;
+
+ return (caddr_t)new_value;
+}
+
int
_rtld_relocate_plt_object(obj, rela, addrp)
const Obj_Entry *obj;
diff --git a/libexec/ld.elf_so/arch/sh3/rtld_start.S b/libexec/ld.elf_so/arch/sh3/rtld_start.S
index 5b05c852457..eae0f184467 100644
--- a/libexec/ld.elf_so/arch/sh3/rtld_start.S
+++ b/libexec/ld.elf_so/arch/sh3/rtld_start.S
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld_start.S,v 1.2 2002/02/04 18:18:51 thorpej Exp $ */
+/* $NetBSD: rtld_start.S,v 1.3 2003/06/30 00:50:47 marcus Exp $ */
/*-
* Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
@@ -44,43 +44,25 @@
.type .rtld_start,@function
.rtld_start:
+ mova 2f,r0
+ mov.l @r0,r2
+ add r0,r2 /* GOT */
+ mov.l @(4,r0),r4
+ add r2,r4 /* _DYNAMIC */
+ mov.l @(12,r0),r1
+ mov.l @(8,r0),r0
+ mov r4,r5
+ mov.l @(r0,r2),r0 /* Where linker thinks _DYNAMIC is */
+ sub r0,r5 /* compute relocation base */
+ bsrf r1 /* _rtld_relocate_nonplt_self(dynp, relocbase) */
+ mov.l r5,@-r15 /* delay slot: save relocbase */
- /* relocate GOT, so that we can use global function calls in rtld.c */
-
- mova 1f,r0
- mov.l @r0,r1
- add r1,r0 /* r0 = _GLOBAL_OFFSET_TABLE_ */
-
- mov.l 2f,r1
- add r0,r1 /* r1 = GOT end */
- mov.l 3f,r2
- mov.l @(r0,r2),r3 /* r3 = where the linker thinks GOT end is */
- mov r1,r2
- sub r3,r2 /* r2 = displacement */
-4:
- mov.l @r0+,r3 /* add displacement to all GOT entries */
- cmp/hs r1,r0
- add #-4,r0
- add r2,r3
- mov.l r3,@r0
- bf/s 4b
- add #4,r0
-
- bra 4f /* all done */
- nop
-
- .align 2
-1: .long _GLOBAL_OFFSET_TABLE_
-2: .long _DYNAMIC@GOTOFF
-3: .long _DYNAMIC@GOT
-
-
-4:
+4:
+ mov.l @r15+,r5 /* restore relocbase */
add #-8,r15 /* Make room for return args */
mov r15,r4
mov.l 1f,r0
- add #(1f-3f),r0
- bsrf r0 /* _rtld(sp) */
+ bsrf r0 /* _rtld(sp, relocbase) */
mov.l r9,@-r15 /* save ps_strings */
3:
mov.l @r15+,r9 /* restore ps_strings */
@@ -99,13 +81,17 @@
jmp @r0
add #8,r6
.align 2
-1: .long _rtld-.
+1: .long _rtld-3b
+2: .long _GLOBAL_OFFSET_TABLE_
+ .long _DYNAMIC@GOTOFF
+ .long _DYNAMIC@GOT
+ .long _rtld_relocate_nonplt_self-4b
.size .rtld_start,.-.rtld_start
.align 2
.globl _rtld_bind_start
.type _rtld_bind_start,@function
-_rtld_bind_start: /* r0 = flag, r1 = reloff, r2 = obj */
+_rtld_bind_start: /* r0 = obj, r1 = reloff */
mov.l r3,@-r15 /* save registers */
mov.l r4,@-r15
mov.l r5,@-r15
@@ -115,11 +101,10 @@ _rtld_bind_start: /* r0 = flag, r1 = reloff, r2 = obj */
sts.l macl,@-r15
sts.l pr,@-r15
+ mov r0,r4 /* copy of obj */
mov.l 2f,r0
- add #(2f-4f),r0
- mov r2,r4 /* copy of obj */
bsrf r0 /* call the binder */
- mov r1,r5 /* copy of relobj */
+ mov r1,r5 /* copy of reloff */
4:
lds.l @r15+,pr /* restore registers */
lds.l @r15+,macl
@@ -131,7 +116,7 @@ _rtld_bind_start: /* r0 = flag, r1 = reloff, r2 = obj */
jmp @r0
mov.l @r15+,r3
.align 2
-2: .long _rtld_bind-.
+2: .long _rtld_bind-4b
.size _rtld_bind_start,.-_rtld_bind_start
.end