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/arch/mips Move GOT relocation code from _r...



details:   https://anonhg.NetBSD.org/src/rev/2132a82e6ca9
branches:  trunk
changeset: 536289:2132a82e6ca9
user:      mycroft <mycroft%NetBSD.org@localhost>
date:      Thu Sep 12 18:21:18 2002 +0000

description:
Move GOT relocation code from _rtld_setup_pltgot() to
_rtld_relocate_nonplt_objects().  Add GOT self-relocation in
_rtld_relocate_nonplt_self().
MIPS ld.elf_so can now relocate itself.

diffstat:

 libexec/ld.elf_so/arch/mips/mips_reloc.c |  173 ++++++++++++++++++------------
 1 files changed, 106 insertions(+), 67 deletions(-)

diffs (229 lines):

diff -r 6ebae1df95b4 -r 2132a82e6ca9 libexec/ld.elf_so/arch/mips/mips_reloc.c
--- a/libexec/ld.elf_so/arch/mips/mips_reloc.c  Thu Sep 12 17:51:33 2002 +0000
+++ b/libexec/ld.elf_so/arch/mips/mips_reloc.c  Thu Sep 12 18:21:18 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mips_reloc.c,v 1.17 2002/09/12 17:08:32 mycroft Exp $  */
+/*     $NetBSD: mips_reloc.c,v 1.18 2002/09/12 18:21:18 mycroft Exp $  */
 
 /*
  * Copyright 1997 Michael L. Hitch <mhitch%montana.edu@localhost>
@@ -62,65 +62,6 @@
 _rtld_setup_pltgot(obj)
        const Obj_Entry *obj;
 {
-       Elf_Addr *got = obj->pltgot;
-       const Elf_Sym *sym = obj->symtab;
-       const Elf_Sym *def;
-       const Obj_Entry *defobj;
-       int i;
-
-       i = (got[1] & 0x80000000) ? 2 : 1;
-       /* Relocate the local GOT entries */
-       while (i < obj->local_gotno)
-               got[i++] += (Elf_Word)obj->relocbase;
-       got += obj->local_gotno;
-       sym += obj->gotsym;
-       /* Now do the global GOT entries */
-       for (i = obj->gotsym; i < obj->symtabno; i++) {
-               rdbg(1, (" doing got %d sym %p (%s, %x)", i - obj->gotsym, 
-                   sym, sym->st_name + obj->strtab, *got));
-
-               def = _rtld_find_symdef(i, obj, &defobj, true);
-               if (def == NULL)
-                       _rtld_error(
-           "%s: Undefined PLT symbol \"%s\" (section type = %ld, symnum = %ld)",
-                           obj->path, sym->st_name + obj->strtab,
-                           (u_long) ELF_ST_TYPE(sym->st_info), (u_long) i);
-               else {
-                       if (sym->st_shndx == SHN_UNDEF) {
-#if 0  /* These don't seem to work? */
-
-                               if (ELF_ST_TYPE(sym->st_info) == STT_FUNC) {
-                                       if (sym->st_value)
-                                               *got = sym->st_value +
-                                                   (Elf_Word)obj->relocbase;
-                                       else
-                                               *got = def->st_value +
-                                                   (Elf_Word)defobj->relocbase;
-                               } else
-#endif
-                                       *got = def->st_value +
-                                           (Elf_Word)defobj->relocbase;
-                       } else if (sym->st_shndx == SHN_COMMON) {
-                               *got = def->st_value +
-                                   (Elf_Word)defobj->relocbase;
-                       } else if (ELF_ST_TYPE(sym->st_info) == STT_FUNC &&
-                           *got != sym->st_value) {
-                               *got += (Elf_Word)obj->relocbase;
-                       } else if (ELF_ST_TYPE(sym->st_info) == STT_SECTION &&
-                           ELF_ST_BIND(sym->st_info) == STB_GLOBAL) {
-                               if (sym->st_shndx == SHN_ABS)
-                                       *got = sym->st_value +
-                                           (Elf_Word)obj->relocbase;
-                               /* else SGI stuff ignored */
-                       } else
-                               *got = def->st_value +
-                                   (Elf_Word)defobj->relocbase;
-               }
-
-               ++sym;
-               ++got;
-       }
-
        obj->pltgot[0] = (Elf_Addr) &_rtld_bind_start;
        /* XXX only if obj->pltgot[1] & 0x80000000 ?? */
        obj->pltgot[1] |= (Elf_Addr) obj;
@@ -134,7 +75,10 @@
        const Elf_Rel *rel = 0, *rellim;
        Elf_Addr relsz = 0;
        Elf_Addr *where;
-       const Elf_Sym *def, *symtab;
+       const Elf_Sym *symtab, *sym;
+       Elf_Addr *got;
+       Elf_Word local_gotno, symtabno, gotsym;
+       int i;
 
        for (; dynp->d_tag != DT_NULL; dynp++) {
                switch (dynp->d_tag) {
@@ -147,6 +91,18 @@
                case DT_SYMTAB:
                        symtab = (const Elf_Sym *)(relocbase + dynp->d_un.d_ptr);
                        break;
+               case DT_PLTGOT:
+                       got = (Elf_Addr *)(relocbase + dynp->d_un.d_ptr);
+                       break;
+               case DT_MIPS_LOCAL_GOTNO:
+                       local_gotno = dynp->d_un.d_val;
+                       break;
+               case DT_MIPS_SYMTABNO:
+                       symtabno = dynp->d_un.d_val;
+                       break;
+               case DT_MIPS_GOTSYM:
+                       gotsym = dynp->d_un.d_val;
+                       break;
                }
        }
        rellim = (const Elf_Rel *)((caddr_t)rel + relsz);
@@ -158,12 +114,11 @@
                        break;
 
                case R_TYPE(REL32):
-                       def = symtab + ELF_R_SYM(rel->r_info);
-                       if (ELF_ST_BIND(def->st_info) == STB_LOCAL &&
-                           ELF_ST_TYPE(def->st_info) == STT_SECTION) {
-                               *where += (Elf_Addr)def->st_value;
-                               *where += (Elf_Addr)relocbase;
-                       } else
+                       sym = symtab + ELF_R_SYM(rel->r_info);
+                       if (ELF_ST_BIND(sym->st_info) == STB_LOCAL &&
+                           ELF_ST_TYPE(sym->st_info) == STT_SECTION)
+                               *where += (Elf_Addr)(sym->st_value + relocbase);
+                       else
                                abort();
                        break;
 
@@ -171,6 +126,31 @@
                        abort();
                }
        }
+
+       i = (got[1] & 0x80000000) ? 2 : 1;
+       /* Relocate the local GOT entries */
+       while (i < local_gotno)
+               got[i++] += relocbase;
+       got += local_gotno;
+       sym = symtab + gotsym;
+       /* Now do the global GOT entries */
+       for (i = gotsym; i < symtabno; i++) {
+               if (sym->st_shndx == SHN_UNDEF ||
+                   sym->st_shndx == SHN_COMMON) {
+                       *got = sym->st_value + relocbase;
+               } else if (ELF_ST_TYPE(sym->st_info) == STT_FUNC &&
+                   *got != sym->st_value) {
+                       *got += relocbase;
+               } else if (ELF_ST_TYPE(sym->st_info) == STT_SECTION &&
+                   ELF_ST_BIND(sym->st_info) == STB_GLOBAL) {
+                       if (sym->st_shndx == SHN_ABS)
+                               *got = sym->st_value + relocbase;
+                       /* else SGI stuff ignored */
+               } else
+                       *got = sym->st_value + relocbase;
+               ++sym;
+               ++got;
+       }
 }
 
 int
@@ -180,6 +160,11 @@
        bool dodebug;
 {
        const Elf_Rel *rel;
+       Elf_Addr *got = obj->pltgot;
+       const Elf_Sym *sym = obj->symtab;
+       const Elf_Sym *def;
+       const Obj_Entry *defobj;
+       int i;
 
        if (self)
                return 0;
@@ -259,6 +244,60 @@
                        return -1;
                }
        }
+
+       i = (got[1] & 0x80000000) ? 2 : 1;
+       /* Relocate the local GOT entries */
+       while (i < obj->local_gotno)
+               got[i++] += (Elf_Word)obj->relocbase;
+       got += obj->local_gotno;
+       sym += obj->gotsym;
+       /* Now do the global GOT entries */
+       for (i = obj->gotsym; i < obj->symtabno; i++) {
+               rdbg(1, (" doing got %d sym %p (%s, %x)", i - obj->gotsym, 
+                   sym, sym->st_name + obj->strtab, *got));
+
+               def = _rtld_find_symdef(i, obj, &defobj, true);
+               if (def == NULL)
+                       _rtld_error(
+           "%s: Undefined PLT symbol \"%s\" (section type = %ld, symnum = %ld)",
+                           obj->path, sym->st_name + obj->strtab,
+                           (u_long) ELF_ST_TYPE(sym->st_info), (u_long) i);
+               else {
+                       if (sym->st_shndx == SHN_UNDEF) {
+#if 0  /* These don't seem to work? */
+
+                               if (ELF_ST_TYPE(sym->st_info) == STT_FUNC) {
+                                       if (sym->st_value)
+                                               *got = sym->st_value +
+                                                   (Elf_Word)obj->relocbase;
+                                       else
+                                               *got = def->st_value +
+                                                   (Elf_Word)defobj->relocbase;
+                               } else
+#endif
+                                       *got = def->st_value +
+                                           (Elf_Word)defobj->relocbase;
+                       } else if (sym->st_shndx == SHN_COMMON) {
+                               *got = def->st_value +
+                                   (Elf_Word)defobj->relocbase;
+                       } else if (ELF_ST_TYPE(sym->st_info) == STT_FUNC &&
+                           *got != sym->st_value) {
+                               *got += (Elf_Word)obj->relocbase;
+                       } else if (ELF_ST_TYPE(sym->st_info) == STT_SECTION &&
+                           ELF_ST_BIND(sym->st_info) == STB_GLOBAL) {
+                               if (sym->st_shndx == SHN_ABS)
+                                       *got = sym->st_value +
+                                           (Elf_Word)obj->relocbase;
+                               /* else SGI stuff ignored */
+                       } else
+                               *got = def->st_value +
+                                   (Elf_Word)defobj->relocbase;
+               }
+
+               ++sym;
+               ++got;
+       }
+
        return 0;
 }
 



Home | Main Index | Thread Index | Old Index