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 Reorganize PowerPC cold a little. The ret...
details: https://anonhg.NetBSD.org/src/rev/0ffbc2af92dc
branches: trunk
changeset: 514750:0ffbc2af92dc
user: mycroft <mycroft%NetBSD.org@localhost>
date: Mon Sep 10 06:09:41 2001 +0000
description:
Reorganize PowerPC cold a little. The return value from _rtld_bind_pltgot()
was ambiguous in the case of a weak symbol that was not defined. This caused
RTLD_NOW to fail badly with shared libraries linked against the new crtbegin.o.
diffstat:
libexec/ld.elf_so/arch/powerpc/ppc_reloc.c | 146 +++++++++++++---------------
libexec/ld.elf_so/reloc.c | 12 +-
2 files changed, 74 insertions(+), 84 deletions(-)
diffs (250 lines):
diff -r 5560aaf92b50 -r 0ffbc2af92dc libexec/ld.elf_so/arch/powerpc/ppc_reloc.c
--- a/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c Mon Sep 10 06:07:56 2001 +0000
+++ b/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c Mon Sep 10 06:09:41 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ppc_reloc.c,v 1.9 2001/04/25 12:24:51 kleink Exp $ */
+/* $NetBSD: ppc_reloc.c,v 1.10 2001/09/10 06:09:41 mycroft Exp $ */
/*-
* Copyright (C) 1998 Tsubai Masanari
@@ -42,8 +42,6 @@
void _rtld_powerpc_pltcall __P((Elf_Word));
void _rtld_powerpc_pltresolve __P((Elf_Word, Elf_Word));
-static Elf_Addr _rtld_bind_pltgot __P((Obj_Entry *, const Elf_Rela *));
-
#define ha(x) ((((u_int32_t)(x) & 0x8000) ? \
((u_int32_t)(x) + 0x10000) : (u_int32_t)(x)) >> 16)
#define l(x) ((u_int32_t)(x) & 0xffff)
@@ -56,8 +54,8 @@
Obj_Entry *obj;
Elf_Word reloff;
{
- Elf_Addr addr;
const Elf_Rela *rela;
+ caddr_t addr;
if (reloff < 0 || reloff >= 0x8000) {
dbg(("_rtld_bind_powerpc: broken reloff %x", reloff));
@@ -65,11 +63,11 @@
}
rela = obj->pltrela + reloff;
- addr = _rtld_bind_pltgot(obj, rela);
- if (addr == 0)
+
+ if (_rtld_relocate_plt_object(obj, rela, &addr, true, true) < 0)
_rtld_die();
- return (caddr_t)addr;
+ return addr;
}
/*
@@ -77,90 +75,83 @@
* Initial value is "pltresolve" unless bind_now is true.
*/
int
-_rtld_reloc_powerpc_plt(
+_rtld_relocate_plt_object(
Obj_Entry *obj,
const Elf_Rela *rela,
- bool bind_now)
+ caddr_t *addrp,
+ bool bind_now,
+ bool dodebug)
{
+ Elf_Word *where = (Elf_Word *)(obj->relocbase + rela->r_offset);
+ int distance;
+
if (bind_now) {
- if (_rtld_bind_pltgot(obj, rela) == 0)
- return -1;
+ const Elf_Sym *def;
+ const Obj_Entry *defobj;
+ Elf_Addr value;
+
+ assert(ELF_R_TYPE(rela->r_info) == R_TYPE(JMP_SLOT));
+
+ def = _rtld_find_symdef(_rtld_objlist, rela->r_info, NULL, obj,
+ &defobj, true);
+ if (def == NULL)
+ return (-1);
+
+ value = (Elf_Addr)(defobj->relocbase + def->st_value);
+ distance = value - (Elf_Addr)where;
+
+ if (abs(distance) < 32*1024*1024) { /* inside 32MB? */
+ /* b value # branch directly */
+ *where = 0x48000000 | (distance & 0x03fffffc);
+ __syncicache(where, 4);
+ } else {
+ Elf_Addr *pltcall, *jmptab;
+ int N = obj->pltrelalim - obj->pltrela;
+ int reloff = rela - obj->pltrela;
+
+ if (reloff < 0 || reloff >= 0x8000)
+ return (-1);
+
+ pltcall = obj->pltgot;
+
+ jmptab = pltcall + 18 + N * 2;
+ jmptab[reloff] = value;
+
+ distance = (Elf_Addr)pltcall - (Elf_Addr)(where + 1);
+
+ /* li r11,reloff */
+ /* b pltcall # use pltcall routine */
+ where[0] = 0x39600000 | reloff;
+ where[1] = 0x48000000 | (distance & 0x03fffffc);
+ __syncicache(where, 8);
+ }
+
+ if (addrp != NULL)
+ *addrp = (caddr_t)value;
+
+ return (0);
} else {
- Elf_Word *where = (Elf_Word *)(obj->relocbase + rela->r_offset);
- char *pltresolve = (void *)&obj->pltgot[8];
- int index = rela - obj->pltrela;
- int distance;
+ Elf_Addr *pltresolve;
+ int reloff = rela - obj->pltrela;
+
+ if (reloff < 0 || reloff >= 0x8000)
+ return (-1);
- if (index < 0 || index >= 0x8000)
- return -1;
- distance = pltresolve - (char *)(where + 1);
+ pltresolve = obj->pltgot + 8;
+
+ distance = (Elf_Addr)pltresolve - (Elf_Addr)(where + 1);
- /* li r11,index */
+ /* li r11,reloff */
/* b pltresolve */
- where[0] = 0x39600000 | index;
+ where[0] = 0x39600000 | reloff;
where[1] = 0x48000000 | (distance & 0x03fffffc);
/* __syncicache(where, 8); */
}
+
return 0;
}
/*
- * Bind a pltgot entry to the symbol value.
- */
-Elf_Addr
-_rtld_bind_pltgot(obj, rela)
- Obj_Entry *obj;
- const Elf_Rela *rela;
-{
- Elf_Word *where = (Elf_Word *)(obj->relocbase + rela->r_offset);
- const Elf_Sym *def;
- const Obj_Entry *defobj;
- Elf_Addr targ_addr;
- int distance;
-
- assert(ELF_R_TYPE(rela->r_info) == R_TYPE(JMP_SLOT));
-
- def = _rtld_find_symdef(_rtld_objlist, rela->r_info, NULL, obj,
- &defobj, true);
- dbg(("sym='%s'", def ? defobj->strtab + def->st_name : "??"));
- if (def == NULL) {
- dbg(("symbol not found"));
- return 0;
- }
-
- targ_addr = (Elf_Addr)(defobj->relocbase + def->st_value);
- distance = targ_addr - (Elf_Addr)where;
-
- if (abs(distance) < 32*1024*1024) { /* inside 32MB? */
- /* b targ_addr # branch directly */
- *where = 0x48000000 | (distance & 0x03fffffc);
- __syncicache(where, 4);
- } else {
- Elf_Addr *pltcall, *jmptab;
- int N = obj->pltrelalim - obj->pltrela;
- int reloff = rela - obj->pltrela;
-
- if (reloff < 0 || reloff >= 0x8000)
- return 0;
-
- pltcall = obj->pltgot;
-
- jmptab = pltcall + 18 + N * 2;
- jmptab[reloff] = targ_addr;
-
- distance = (Elf_Addr)pltcall - (Elf_Addr)(where + 1);
-
- /* li r11,reloff */
- /* b pltcall # use pltcall routine */
- where[0] = 0x39600000 | reloff;
- where[1] = 0x48000000 | (distance & 0x03fffffc);
- __syncicache(where, 8);
- }
-
- return targ_addr;
-}
-
-/*
* Setup the plt glue routines.
*/
#define PLTCALL_SIZE 20
@@ -177,12 +168,11 @@
pltcall = obj->pltgot;
memcpy(pltcall, _rtld_powerpc_pltcall, PLTCALL_SIZE);
-
jmptab = pltcall + 18 + N * 2;
pltcall[1] |= ha(jmptab);
pltcall[2] |= l(jmptab);
- pltresolve = &pltcall[8];
+ pltresolve = obj->pltgot + 8;
memcpy(pltresolve, _rtld_powerpc_pltresolve, PLTRESOLVE_SIZE);
pltresolve[0] |= ha(_rtld_bind_start);
diff -r 5560aaf92b50 -r 0ffbc2af92dc libexec/ld.elf_so/reloc.c
--- a/libexec/ld.elf_so/reloc.c Mon Sep 10 06:07:56 2001 +0000
+++ b/libexec/ld.elf_so/reloc.c Mon Sep 10 06:09:41 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: reloc.c,v 1.41 2001/08/14 20:17:25 eeh Exp $ */
+/* $NetBSD: reloc.c,v 1.42 2001/09/10 06:09:41 mycroft Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -506,6 +506,7 @@
}
+#if !defined(__powerpc__)
int
_rtld_relocate_plt_object(obj, rela, addrp, bind_now, dodebug)
@@ -520,10 +521,6 @@
/* Fully resolve procedure addresses now */
-#if defined(__powerpc__)
- return _rtld_reloc_powerpc_plt(obj, rela, bind_now);
-#endif
-
#if defined(__alpha__) || defined(__arm__) || defined(__i386__) || \
defined(__m68k__) || defined(__vax__)
if (bind_now || obj->pltgot == NULL) {
@@ -573,7 +570,10 @@
}
return 0;
}
-#endif /* __sparc__ */
+
+#endif /* __powerpc__ */
+
+#endif /* __sparc__ || __x86_64__ */
caddr_t
_rtld_bind(obj, reloff)
Home |
Main Index |
Thread Index |
Old Index