From cea7389ce7367bb3a39faf9c6a6e335edda4fe0f Mon Sep 17 00:00:00 2001 From: kurt Date: Wed, 24 Dec 2014 14:04:09 +0000 Subject: [PATCH] Expand Elf_Rel relocations to include DT_JMPREL. Inspect DT_PLTREL value 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 | 27 +++++++++++++++++++++------ libexec/ld.so/i386/archdep.h | 13 +------------ 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/lib/csu/boot.h b/lib/csu/boot.h index 068805bf194..177f8016bff 100644 --- a/lib/csu/boot.h +++ b/lib/csu/boot.h @@ -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; diff --git a/libexec/ld.so/i386/archdep.h b/libexec/ld.so/i386/archdep.h index bfa203fee87..a08d058dc6c 100644 --- a/libexec/ld.so/i386/archdep.h +++ b/libexec/ld.so/i386/archdep.h @@ -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) -- 2.20.1