rtld: Reorganize reloc_plt and reloc_jmpslots
authorJohn Marino <draco@marino.st>
Sat, 14 Jan 2012 15:19:06 +0000 (16:19 +0100)
committerJohn Marino <draco@marino.st>
Mon, 16 Jan 2012 18:47:31 +0000 (19:47 +0100)
In the future, more reloc types than just R_$ARCH_JMP_SLOT will be
supported.  FreeBSD already has them and converted to a switch statement
and introduced a new rtld_error message rather than use an ASSERT.
Follow suit and fix a mismatching const as well.

libexec/rtld-elf/i386/reloc.c
libexec/rtld-elf/x86_64/reloc.c

index adf7774..f1292d3 100644 (file)
@@ -317,15 +317,22 @@ reloc_plt(Obj_Entry *obj)
     const Elf_Rel *rellim;
     const Elf_Rel *rel;
 
-    rellim = (const Elf_Rel *)((const char *)obj->pltrel + obj->pltrelsize);
+    rellim = (const Elf_Rel *)((char *)obj->pltrel + obj->pltrelsize);
     for (rel = obj->pltrel;  rel < rellim;  rel++) {
        Elf_Addr *where;
 
-       assert(ELF_R_TYPE(rel->r_info) == R_386_JMP_SLOT);
-
-       /* Relocate the GOT slot pointing into the PLT. */
-       where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
-       *where += (Elf_Addr)obj->relocbase;
+       switch (ELF_R_TYPE(rel->r_info)) {
+       case R_386_JMP_SLOT:
+         /* Relocate the GOT slot pointing into the PLT. */
+         where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
+         *where += (Elf_Addr)obj->relocbase;
+         break;
+
+       default:
+         _rtld_error("Unknown relocation type %x in PLT",
+           ELF_R_TYPE(rel->r_info));
+         return (-1);
+       }
     }
     return 0;
 }
@@ -345,14 +352,23 @@ reloc_jmpslots(Obj_Entry *obj)
        const Elf_Sym *def;
        const Obj_Entry *defobj;
 
-       assert(ELF_R_TYPE(rel->r_info) == R_386_JMP_SLOT);
-       where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
-       def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true, NULL);
-       if (def == NULL)
-           return -1;
-       target = (Elf_Addr)(defobj->relocbase + def->st_value);
-       reloc_jmpslot(where, target, defobj, obj, rel);
+       switch (ELF_R_TYPE(rel->r_info)) {
+       case R_386_JMP_SLOT:
+         where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
+         def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true, NULL);
+         if (def == NULL)
+             return (-1);
+         target = (Elf_Addr)(defobj->relocbase + def->st_value);
+         reloc_jmpslot(where, target, defobj, obj, rel);
+         break;
+
+       default:
+         _rtld_error("Unknown relocation type %x in PLT",
+           ELF_R_TYPE(rel->r_info));
+         return (-1);
+       }
     }
+
     obj->jmpslots_done = true;
     return 0;
 }
@@ -384,4 +400,3 @@ __tls_get_addr_tcb(struct tls_tcb *tcb, tls_index *ti)
 {
     return tls_get_addr_common((Elf_Addr **)&tcb->tcb_dtv, ti->ti_module, ti->ti_offset);
 }
-
index ca11a80..574cc99 100644 (file)
@@ -342,11 +342,18 @@ reloc_plt(Obj_Entry *obj)
     for (rela = obj->pltrela;  rela < relalim;  rela++) {
        Elf_Addr *where;
 
-       assert(ELF_R_TYPE(rela->r_info) == R_X86_64_JMP_SLOT);
-
-       /* Relocate the GOT slot pointing into the PLT. */
-       where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
-       *where += (Elf_Addr)obj->relocbase;
+       switch(ELF_R_TYPE(rela->r_info)) {
+       case R_X86_64_JMP_SLOT:
+         /* Relocate the GOT slot pointing into the PLT. */
+         where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
+         *where += (Elf_Addr)obj->relocbase;
+         break;
+
+       default:
+         _rtld_error("Unknown relocation type %x in PLT",
+           (unsigned int)ELF_R_TYPE(rela->r_info));
+         return (-1);
+       }
     }
     return 0;
 }
@@ -366,13 +373,21 @@ reloc_jmpslots(Obj_Entry *obj)
        const Elf_Sym *def;
        const Obj_Entry *defobj;
 
-       assert(ELF_R_TYPE(rela->r_info) == R_X86_64_JMP_SLOT);
-       where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
-       def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, true, NULL);
-       if (def == NULL)
-           return -1;
-       target = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend);
-       reloc_jmpslot(where, target, defobj, obj, (const Elf_Rel *)rela);
+       switch (ELF_R_TYPE(rela->r_info)) {
+       case R_X86_64_JMP_SLOT:
+         where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
+         def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, true, NULL);
+         if (def == NULL)
+             return (-1);
+         target = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend);
+         reloc_jmpslot(where, target, defobj, obj, (const Elf_Rel *)rela);
+         break;
+
+       default:
+         _rtld_error("Unknown relocation type %x in PLT",
+           (unsigned int)ELF_R_TYPE(rela->r_info));
+         return (-1);
+       }
     }
     obj->jmpslots_done = true;
     return 0;