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