Expand Elf_Rel relocations to include DT_JMPREL. Inspect DT_PLTREL value
authorkurt <kurt@openbsd.org>
Wed, 24 Dec 2014 14:04:09 +0000 (14:04 +0000)
committerkurt <kurt@openbsd.org>
Wed, 24 Dec 2014 14:04:09 +0000 (14:04 +0000)
to determine if DT_JMPREL relocations are REL or RELA and conditionally
perform DT_JMPREL in either REL or RELA as needed (idea from kettenis@).
Remove unneeded i386 RELA implementation. i386 static pie working now.

okay kettenis@

lib/csu/boot.h
libexec/ld.so/i386/archdep.h

index 068805b..177f801 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: boot.h,v 1.5 2014/12/24 08:58:46 kettenis Exp $ */
+/*     $OpenBSD: boot.h,v 1.6 2014/12/24 14:04:09 kurt Exp $ */
 
 /*
  * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -159,27 +159,40 @@ _dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynamicp)
                table[i++] = DT_FINI;
                table[i++] = DT_REL;
                table[i++] = DT_JMPREL;
+               table[i++] = DT_PLTREL;
                /* other processors insert their extras here */
                table[i++] = DT_NULL;
                for (i = 0; table[i] != DT_NULL; i++) {
                        val = table[i];
                        if (val >= DT_LOPROC && val < DT_LOPROC + DT_PROCNUM)
                                val = val - DT_LOPROC + DT_NUM;
-                       else if (val >= DT_NUM)
+                       else if (val >= DT_NUM || val == DT_PLTREL)
                                continue;
                        if (dynld.Dyn.info[val] != 0)
                                dynld.Dyn.info[val] += loff;
                }
        }
 
-       {
+       for (n = 0; n < 2; n++) {
                u_int32_t rs;
                Elf_Rel *rp;
                int     i;
 
-               rp = (Elf_Rel *)(dynld.Dyn.info[DT_REL]);
-               rs = dynld.dyn.relsz;
-
+               switch (n) {
+               case 0:
+                       if (dynld.Dyn.info[DT_PLTREL] != DT_REL)
+                               continue;
+                       rp = (Elf_Rel *)(dynld.Dyn.info[DT_JMPREL]);
+                       rs = dynld.dyn.pltrelsz;
+                       break;
+               case 1:
+                       rp = (Elf_Rel *)(dynld.Dyn.info[DT_REL]);
+                       rs = dynld.dyn.relsz;
+                       break;
+               default:
+                       rp = NULL;
+                       rs = 0;
+               }
                for (i = 0; i < rs; i += sizeof (Elf_Rel), rp++) {
                        Elf_Addr *ra;
                        const Elf_Sym *sp;
@@ -214,6 +227,8 @@ _dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynamicp)
 
                switch (n) {
                case 0:
+                       if (dynld.Dyn.info[DT_PLTREL] != DT_RELA)
+                               continue;
                        rp = (Elf_RelA *)(dynld.Dyn.info[DT_JMPREL]);
                        rs = dynld.dyn.pltrelsz;
                        break;
index bfa203f..a08d058 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: archdep.h,v 1.12 2014/12/22 21:58:25 kurt Exp $ */
+/*     $OpenBSD: archdep.h,v 1.13 2014/12/24 14:04:09 kurt Exp $ */
 
 /*
  * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -79,17 +79,6 @@ static inline void
 RELOC_RELA(Elf32_Rela *r, const Elf32_Sym *s, Elf32_Addr *p, unsigned long v,
     Elf_Addr *pltgot)
 {
-       /* does i386 use RELA type relocations? - XXX */
-
-       if (ELF32_R_TYPE(r->r_info) == RELOC_RELATIVE) {
-               *p = v + r->r_addend;
-       } else if (ELF32_R_TYPE(r->r_info) == RELOC_GLOB_DAT) {
-               *p = v + s->st_value + r->r_addend;
-       } else if (ELF32_R_TYPE(r->r_info) == RELOC_NONE) {
-       } else {
-               _dl_printf("unknown bootstrap relocation\n");
-               _dl_exit(6);
-       }
 }
 
 #define RELOC_GOT(obj, offs)