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