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 Split _rtld_relocate_plt_object() into two...



details:   https://anonhg.NetBSD.org/src/rev/574734fe7154
branches:  trunk
changeset: 536067:574734fe7154
user:      mycroft <mycroft%NetBSD.org@localhost>
date:      Fri Sep 06 03:05:35 2002 +0000

description:
Split _rtld_relocate_plt_object() into two MD functions:
* _rtld_relocate_plt_lazy() fixes up all the relocs pointing to the PLT.  (On
  most platforms it just does a simple base-relative fixup; on SPARC it does
  nothing.)
* _rtld_relocate_plt_object() does immediate binding for a PLT entry.
The basic gist is that this saves a bit of time on SPARC (where the iteration
through the pltrela table was gratuitous), and a little less time on all other
platforms.  A whole lot of #ifdef'ed crap is moved out of reloc.c, too.

NOT tested on: hppa sh x86_64

diffstat:

 libexec/ld.elf_so/arch/alpha/alpha_reloc.c |   54 ++++++++++++-
 libexec/ld.elf_so/arch/arm/mdreloc.c       |   52 +++++++++++
 libexec/ld.elf_so/arch/hppa/hppa_reloc.c   |   74 +++++++++++-----
 libexec/ld.elf_so/arch/i386/mdreloc.c      |   53 ++++++++++++
 libexec/ld.elf_so/arch/m68k/mdreloc.c      |   52 +++++++++++
 libexec/ld.elf_so/arch/mips/mips_reloc.c   |   42 ++++++---
 libexec/ld.elf_so/arch/powerpc/ppc_reloc.c |  123 ++++++++++++++-------------
 libexec/ld.elf_so/arch/sh3/mdreloc.c       |   53 ++++++++++++
 libexec/ld.elf_so/arch/sparc/mdreloc.c     |   24 ++--
 libexec/ld.elf_so/arch/sparc64/mdreloc.c   |   24 ++--
 libexec/ld.elf_so/arch/vax/mdreloc.c       |   53 ++++++++++++
 libexec/ld.elf_so/arch/x86_64/mdreloc.c    |  105 ++++++++++++-----------
 libexec/ld.elf_so/reloc.c                  |  126 +---------------------------
 libexec/ld.elf_so/rtld.h                   |    7 +-
 14 files changed, 552 insertions(+), 290 deletions(-)

diffs (truncated from 1160 to 300 lines):

diff -r 9e020044dd2d -r 574734fe7154 libexec/ld.elf_so/arch/alpha/alpha_reloc.c
--- a/libexec/ld.elf_so/arch/alpha/alpha_reloc.c        Fri Sep 06 02:40:56 2002 +0000
+++ b/libexec/ld.elf_so/arch/alpha/alpha_reloc.c        Fri Sep 06 03:05:35 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: alpha_reloc.c,v 1.9 2002/09/05 21:31:30 mycroft Exp $  */
+/*     $NetBSD: alpha_reloc.c,v 1.10 2002/09/06 03:05:35 mycroft Exp $ */
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -206,3 +206,55 @@
        }
        return 0;
 }
+
+int
+_rtld_relocate_plt_lazy(obj, dodebug)
+       Obj_Entry *obj;
+       bool dodebug;
+{
+       const Elf_Rela *rela;
+
+       if (obj->mainprog)
+               return 0;
+
+       for (rela = obj->pltrela; rela < obj->pltrelalim; rela++) {
+               Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
+
+               assert(ELF_R_TYPE(rela->r_info) == R_TYPE(JMP_SLOT));
+
+               /* Just relocate the GOT slots pointing into the PLT */
+               *where += (Elf_Addr)obj->relocbase;
+               rdbg(dodebug, ("fixup !main in %s --> %p", obj->path,
+                   (void *)*where));
+       }
+
+       return 0;
+}
+
+int
+_rtld_relocate_plt_object(obj, rela, addrp, dodebug)
+       Obj_Entry *obj;
+       const Elf_Rela *rela;
+       caddr_t *addrp;
+       bool dodebug;
+{
+       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)
+               return -1;
+
+       new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
+       rdbg(dodebug, ("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;
+
+       *addrp = (caddr_t)new_value;
+       return 0;
+}
diff -r 9e020044dd2d -r 574734fe7154 libexec/ld.elf_so/arch/arm/mdreloc.c
--- a/libexec/ld.elf_so/arch/arm/mdreloc.c      Fri Sep 06 02:40:56 2002 +0000
+++ b/libexec/ld.elf_so/arch/arm/mdreloc.c      Fri Sep 06 03:05:35 2002 +0000
@@ -123,3 +123,55 @@
        }
        return 0;
 }
+
+int
+_rtld_relocate_plt_lazy(obj, dodebug)
+       Obj_Entry *obj;
+       bool dodebug;
+{
+       const Elf_Rel *rel;
+
+       if (obj->mainprog)
+               return 0;
+
+       for (rel = obj->pltrel; rel < obj->pltrellim; rel++) {
+               Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
+
+               assert(ELF_R_TYPE(rel->r_info) == R_TYPE(JUMP_SLOT));
+
+               /* Just relocate the GOT slots pointing into the PLT */
+               *where += (Elf_Addr)obj->relocbase;
+               rdbg(dodebug, ("fixup !main in %s --> %p", obj->path,
+                   (void *)*where));
+       }
+
+       return 0;
+}
+
+int
+_rtld_relocate_plt_object(obj, rela, addrp, dodebug)
+       Obj_Entry *obj;
+       const Elf_Rela *rela;
+       caddr_t *addrp;
+       bool dodebug;
+{
+       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(JUMP_SLOT));
+
+       def = _rtld_find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, true);
+       if (def == NULL)
+               return -1;
+
+       new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
+       rdbg(dodebug, ("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;
+
+       *addrp = (caddr_t)new_value;
+       return 0;
+}
diff -r 9e020044dd2d -r 574734fe7154 libexec/ld.elf_so/arch/hppa/hppa_reloc.c
--- a/libexec/ld.elf_so/arch/hppa/hppa_reloc.c  Fri Sep 06 02:40:56 2002 +0000
+++ b/libexec/ld.elf_so/arch/hppa/hppa_reloc.c  Fri Sep 06 03:05:35 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: hppa_reloc.c,v 1.7 2002/09/05 21:31:32 mycroft Exp $   */
+/*     $NetBSD: hppa_reloc.c,v 1.8 2002/09/06 03:05:36 mycroft Exp $   */
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -265,7 +265,7 @@
  */
 int
 _rtld_relocate_plt_object(Obj_Entry *obj, const Elf_Rela *rela, caddr_t *addrp,
-    bool bind_now, bool dodebug)
+    bool dodebug)
 {
        Elf_Addr        *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
        const Elf_Sym   *def;
@@ -286,7 +286,7 @@
        /*
         * If we must bind now, fully resolve the PLT entry.
         */
-       else if (bind_now) {
+       else {
 
                /*
                 * Look up the symbol.  While we're relocating self,
@@ -302,29 +302,12 @@
        }
 
        /*
-        * Otherwise set up for lazy binding.
-        */
-       else {
-       
-               /*
-                * This function pointer points to the PLT
-                * stub added by the linker, and instead of
-                * a shared linkage value, we stash this
-                * relocation's offset.  The PLT stub has
-                * already been set up to transfer to
-                * _rtld_bind_start.
-                */
-               func_pc = ((Elf_Addr)HPPA_OBJ_GOT(obj)) - 16;
-               func_sl = (Elf_Addr)((caddr_t)rela - (caddr_t)obj->pltrela);
-       }
-
-       /*
         * Fill this PLT entry and return.
         */
        where[0] = func_pc;
        where[1] = func_sl;
-       if (addrp != NULL)
-               *addrp = (caddr_t)where;
+
+       *addrp = (caddr_t)where;
        return 0;
 }
 
@@ -484,3 +467,50 @@
        }
        return 0;
 }
+
+int
+_rtld_relocate_plt_lazy(obj, dodebug)
+       Obj_Entry *obj;
+       bool dodebug;
+{
+       const Elf_Rela *rela;
+
+       for (rela = obj->pltrela; rela < obj->pltrelalim; rela++) {
+               Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
+               Elf_Addr func_pc, func_sl;
+
+               assert(ELF_R_TYPE(rela->r_info) == R_TYPE(IPLT));
+
+               /*
+                * If this is an IPLT reloc for a static function,
+                * fully resolve the PLT entry now.
+                */
+               if (ELF_R_SYM(rela->r_info) == 0) {
+                       func_pc = (Elf_Addr)(obj->relocbase + rela->r_addend);
+                       func_sl = (Elf_Addr)HPPA_OBJ_SL(obj);
+               }
+
+               /*
+                * Otherwise set up for lazy binding.
+                */
+               else {
+                       /*
+                        * This function pointer points to the PLT
+                        * stub added by the linker, and instead of
+                        * a shared linkage value, we stash this
+                        * relocation's offset.  The PLT stub has
+                        * already been set up to transfer to
+                        * _rtld_bind_start.
+                        */
+                       func_pc = ((Elf_Addr)HPPA_OBJ_GOT(obj)) - 16;
+                       func_sl = (Elf_Addr)((caddr_t)rela - (caddr_t)obj->pltrela);
+               }
+
+               /*
+                * Fill this PLT entry and return.
+                */
+               where[0] = func_pc;
+               where[1] = func_sl;
+       }
+       return 0;
+}
diff -r 9e020044dd2d -r 574734fe7154 libexec/ld.elf_so/arch/i386/mdreloc.c
--- a/libexec/ld.elf_so/arch/i386/mdreloc.c     Fri Sep 06 02:40:56 2002 +0000
+++ b/libexec/ld.elf_so/arch/i386/mdreloc.c     Fri Sep 06 03:05:35 2002 +0000
@@ -17,6 +17,7 @@
        bool dodebug;
 {
        const Elf_Rel *rel;
+#define COMBRELOC
 #ifdef COMBRELOC
        unsigned long lastsym = -1;
 #endif
@@ -120,3 +121,55 @@
        }
        return 0;
 }
+
+int
+_rtld_relocate_plt_lazy(obj, dodebug)
+       Obj_Entry *obj;
+       bool dodebug;
+{
+       const Elf_Rel *rel;
+
+       if (obj->mainprog)
+               return 0;
+
+       for (rel = obj->pltrel; rel < obj->pltrellim; rel++) {
+               Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
+
+               assert(ELF_R_TYPE(rel->r_info) == R_TYPE(JMP_SLOT));
+
+               /* Just relocate the GOT slots pointing into the PLT */
+               *where += (Elf_Addr)obj->relocbase;
+               rdbg(dodebug, ("fixup !main in %s --> %p", obj->path,
+                   (void *)*where));
+       }
+
+       return 0;
+}
+
+int
+_rtld_relocate_plt_object(obj, rela, addrp, dodebug)
+       Obj_Entry *obj;
+       const Elf_Rela *rela;
+       caddr_t *addrp;
+       bool dodebug;
+{
+       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)
+               return -1;
+
+       new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
+       rdbg(dodebug, ("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;
+
+       *addrp = (caddr_t)new_value;
+       return 0;



Home | Main Index | Thread Index | Old Index