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_nonplt_object() into ...



details:   https://anonhg.NetBSD.org/src/rev/8ce60eb11826
branches:  trunk
changeset: 536052:8ce60eb11826
user:      mycroft <mycroft%NetBSD.org@localhost>
date:      Thu Sep 05 18:25:45 2002 +0000

description:
Split _rtld_relocate_nonplt_object() into separate MD files.

diffstat:

 libexec/ld.elf_so/arch/alpha/alpha_reloc.c |   97 ++++++-
 libexec/ld.elf_so/arch/arm/mdreloc.c       |  109 +++++++
 libexec/ld.elf_so/arch/hppa/hppa_reloc.c   |  145 +++++++++-
 libexec/ld.elf_so/arch/i386/mdreloc.c      |   85 +++++
 libexec/ld.elf_so/arch/m68k/mdreloc.c      |   87 +++++
 libexec/ld.elf_so/arch/powerpc/ppc_reloc.c |   74 ++++-
 libexec/ld.elf_so/arch/sh3/mdreloc.c       |  112 +++++++
 libexec/ld.elf_so/arch/sparc/mdreloc.c     |  160 +++++-----
 libexec/ld.elf_so/arch/sparc64/mdreloc.c   |  275 +++++++++---------
 libexec/ld.elf_so/arch/vax/mdreloc.c       |   73 ++++
 libexec/ld.elf_so/arch/x86_64/mdreloc.c    |  112 +++---
 libexec/ld.elf_so/reloc.c                  |  435 +----------------------------
 12 files changed, 1052 insertions(+), 712 deletions(-)

diffs (truncated from 1900 to 300 lines):

diff -r be6aaa5b9595 -r 8ce60eb11826 libexec/ld.elf_so/arch/alpha/alpha_reloc.c
--- a/libexec/ld.elf_so/arch/alpha/alpha_reloc.c        Thu Sep 05 17:58:02 2002 +0000
+++ b/libexec/ld.elf_so/arch/alpha/alpha_reloc.c        Thu Sep 05 18:25:45 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: alpha_reloc.c,v 1.4 2002/09/05 15:38:23 mycroft Exp $  */
+/*     $NetBSD: alpha_reloc.c,v 1.5 2002/09/05 18:25:46 mycroft Exp $  */
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -107,3 +107,98 @@
 
        __asm __volatile("imb");
 }
+
+int
+_rtld_relocate_nonplt_object(obj, rela, dodebug)
+       Obj_Entry *obj;
+       const Elf_Rela *rela;
+       bool dodebug;
+{
+       Elf_Addr        *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
+       const Elf_Sym   *def;
+       const Obj_Entry *defobj;
+       Elf_Addr         tmp;
+
+       switch (ELF_R_TYPE(rela->r_info)) {
+
+       case R_TYPE(NONE):
+               break;
+
+       case R_TYPE(REFQUAD):
+               def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
+               if (def == NULL)
+                       return -1;
+
+               tmp = (Elf_Addr)(defobj->relocbase + def->st_value) +
+                   *where + rela->r_addend;
+               if (*where != tmp)
+                       *where = tmp;
+               rdbg(dodebug, ("REFQUAD %s in %s --> %p in %s",
+                   defobj->strtab + def->st_name, obj->path,
+                   (void *)*where, defobj->path));
+               break;
+
+       case R_TYPE(GLOB_DAT):
+               def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
+               if (def == NULL)
+                       return -1;
+
+               tmp = (Elf_Addr)(defobj->relocbase + def->st_value) +
+                   rela->r_addend;
+               if (*where != tmp)
+                       *where = tmp;
+               rdbg(dodebug, ("GLOB_DAT %s in %s --> %p in %s",
+                   defobj->strtab + def->st_name, obj->path,
+                   (void *)*where, defobj->path));
+               break;
+
+       case R_TYPE(RELATIVE):
+           {
+               extern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
+               extern Elf_Addr _GOT_END_[];
+
+               /* This is the ...iffy hueristic. */
+               if (!dodebug ||
+                   (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));
+               break;
+           }
+
+       case R_TYPE(COPY):
+               /*
+                * These are deferred until all other relocations have
+                * been done.  All we do here is make sure that the COPY
+                * relocation is not in a shared library.  They are allowed
+                * only in executable files.
+                */
+               if (!obj->mainprog) {
+                       _rtld_error(
+                       "%s: Unexpected R_COPY relocation in shared library",
+                           obj->path);
+                       return -1;
+               }
+               rdbg(dodebug, ("COPY (avoid in main)"));
+               break;
+
+       default:
+               def = _rtld_find_symdef(rela->r_info, obj, &defobj, true);
+               rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
+                   "addend = %p, contents = %p, symbol = %s",
+                   (u_long)ELF_R_SYM(rela->r_info),
+                   (u_long)ELF_R_TYPE(rela->r_info),
+                   (void *)rela->r_offset, (void *)rela->r_addend,
+                   (void *)*where,
+                   def ? defobj->strtab + def->st_name : "??"));
+               _rtld_error("%s: Unsupported relocation type %ld "
+                   "in non-PLT relocations\n",
+                   obj->path, (u_long) ELF_R_TYPE(rela->r_info));
+               return -1;
+       }
+       return 0;
+}
diff -r be6aaa5b9595 -r 8ce60eb11826 libexec/ld.elf_so/arch/arm/mdreloc.c
--- a/libexec/ld.elf_so/arch/arm/mdreloc.c      Thu Sep 05 17:58:02 2002 +0000
+++ b/libexec/ld.elf_so/arch/arm/mdreloc.c      Thu Sep 05 18:25:45 2002 +0000
@@ -10,3 +10,112 @@
        obj->pltgot[1] = (Elf_Addr) obj;
        obj->pltgot[2] = (Elf_Addr) &_rtld_bind_start;
 }
+
+int
+_rtld_relocate_nonplt_object(obj, rela, dodebug)
+       Obj_Entry *obj;
+       const Elf_Rela *rela;
+       bool dodebug;
+{
+       Elf_Addr        *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
+       const Elf_Sym   *def;
+       const Obj_Entry *defobj;
+       Elf_Addr         tmp;
+
+       switch (ELF_R_TYPE(rela->r_info)) {
+
+       case R_TYPE(NONE):
+               break;
+
+#if 1 /* XXX should not occur */
+       case R_TYPE(PC24): {    /* word32 S - P + A */
+               Elf32_Sword addend;
+
+               /*
+                * Extract addend and sign-extend if needed.
+                */
+               addend = *where;
+               if (addend & 0x00800000)
+                       addend |= 0xff000000;
+
+               def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
+               if (def == NULL)
+                       return -1;
+               tmp = (Elf_Addr)obj->relocbase + def->st_value
+                   - (Elf_Addr)where + (addend << 2);
+               if ((tmp & 0xfe000000) != 0xfe000000 &&
+                   (tmp & 0xfe000000) != 0) {
+                       _rtld_error(
+                       "%s: R_ARM_PC24 relocation @ %p to %s failed "
+                       "(displacement %ld (%#lx) out of range)",
+                           obj->path, where, defobj->strtab + def->st_name,
+                           (long) tmp, (long) tmp);
+                       return -1;
+               }
+               tmp >>= 2;
+               *where = (*where & 0xff000000) | (tmp & 0x00ffffff);
+               rdbg(dodebug, ("PC24 %s in %s --> %p @ %p in %s",
+                   defobj->strtab + def->st_name, obj->path,
+                   (void *)*where, where, defobj->path));
+               break;
+       }
+#endif
+
+       case R_TYPE(ABS32):     /* word32 B + S + A */
+               def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
+               if (def == NULL)
+                       return -1;
+               *where += (Elf_Addr)defobj->relocbase + def->st_value;
+               rdbg(dodebug, ("ABS32 %s in %s --> %p @ %p in %s",
+                   defobj->strtab + def->st_name, obj->path,
+                   (void *)*where, where, defobj->path));
+               break;
+
+       case R_TYPE(GLOB_DAT):  /* word32 B + S */
+               def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
+               if (def == NULL)
+                       return -1;
+               *where = (Elf_Addr)(defobj->relocbase + def->st_value);
+               rdbg(dodebug, ("GLOB_DAT %s in %s --> %p @ %p in %s",
+                   defobj->strtab + def->st_name, obj->path,
+                   (void *)*where, where, defobj->path));
+               break;
+
+       case R_TYPE(RELATIVE):  /* word32 B + A */
+               *where += (Elf_Addr)obj->relocbase;
+               rdbg(dodebug, ("RELATIVE in %s --> %p @ %p", obj->path,
+                   (void *)*where, where));
+               break;
+
+       case R_TYPE(COPY):
+               /*
+                * These are deferred until all other relocations have
+                * been done.  All we do here is make sure that the COPY
+                * relocation is not in a shared library.  They are allowed
+                * only in executable files.
+                */
+               if (!obj->mainprog) {
+                       _rtld_error(
+                       "%s: Unexpected R_COPY relocation in shared library",
+                           obj->path);
+                       return -1;
+               }
+               rdbg(dodebug, ("COPY (avoid in main)"));
+               break;
+
+       default:
+               def = _rtld_find_symdef(rela->r_info, obj, &defobj, true);
+               rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
+                   "addend = %p, contents = %p, symbol = %s",
+                   (u_long)ELF_R_SYM(rela->r_info),
+                   (u_long)ELF_R_TYPE(rela->r_info),
+                   (void *)rela->r_offset, (void *)rela->r_addend,
+                   (void *)*where,
+                   def ? defobj->strtab + def->st_name : "??"));
+               _rtld_error("%s: Unsupported relocation type %ld "
+                   "in non-PLT relocations\n",
+                   obj->path, (u_long) ELF_R_TYPE(rela->r_info));
+               return -1;
+       }
+       return 0;
+}
diff -r be6aaa5b9595 -r 8ce60eb11826 libexec/ld.elf_so/arch/hppa/hppa_reloc.c
--- a/libexec/ld.elf_so/arch/hppa/hppa_reloc.c  Thu Sep 05 17:58:02 2002 +0000
+++ b/libexec/ld.elf_so/arch/hppa/hppa_reloc.c  Thu Sep 05 18:25:45 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: hppa_reloc.c,v 1.3 2002/09/05 16:33:57 junyoung Exp $  */
+/*     $NetBSD: hppa_reloc.c,v 1.4 2002/09/05 18:25:46 mycroft Exp $   */
 
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -333,3 +333,146 @@
 {
        __rtld_setup_hppa_pltgot(obj, HPPA_OBJ_GOT(obj));
 }
+
+int
+_rtld_relocate_nonplt_object(obj, rela, dodebug)
+       Obj_Entry *obj;
+       const Elf_Rela *rela;
+       bool dodebug;
+{
+       Elf_Addr        *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
+       const Elf_Sym   *def;
+       const Obj_Entry *defobj;
+       Elf_Addr         tmp;
+
+       switch (ELF_R_TYPE(rela->r_info)) {
+
+       case R_TYPE(NONE):
+               break;
+
+       case R_TYPE(DIR32):
+               if (ELF_R_SYM(rela->r_info)) {
+                       /*
+                        * This is either a DIR32 against a symbol
+                        * (def->st_name != 0), or against a local 
+                        * section (def->st_name == 0).
+                        */
+                       def = obj->symtab + ELF_R_SYM(rela->r_info);
+                       defobj = obj;
+                       if (def->st_name != 0)
+                               /*
+                                * While we're relocating self, _rtld_objlist
+                                * is NULL, so we just pass in self.
+                                */
+                               def = _rtld_find_symdef(rela->r_info, obj,
+                                   &defobj, false);
+                       if (def == NULL)
+                               return -1;
+
+                       tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
+                           rela->r_addend);
+
+                       if (*where != tmp)
+                               *where = tmp;
+                       rdbg(dodebug, ("DIR32 %s in %s --> %p in %s",
+                           defobj->strtab + def->st_name, obj->path,
+                           (void *)*where, defobj->path));
+               } else {
+                       extern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
+                       extern Elf_Addr _GOT_END_[];
+
+                       tmp = (Elf_Addr)(obj->relocbase + rela->r_addend);
+
+                       /* This is the ...iffy hueristic. */
+                       if (!dodebug ||
+                           (caddr_t)where < (caddr_t)_GLOBAL_OFFSET_TABLE_ ||
+                           (caddr_t)where >= (caddr_t)_GOT_END_) {
+                               if (*where != tmp)
+                                       *where = tmp;
+                               rdbg(dodebug, ("DIR32 in %s --> %p", obj->path,
+                                   (void *)*where));
+                       } else
+                               rdbg(dodebug, ("DIR32 in %s stays at %p",
+                                   obj->path, (void *)*where));
+               }
+               break;



Home | Main Index | Thread Index | Old Index