diff options
author | 2013-03-26 18:53:47 +0000 | |
---|---|---|
committer | 2013-03-26 18:53:47 +0000 | |
commit | 379edb067b7ca6b40488dc0f4386b3563fb580cf (patch) | |
tree | 4e692bef6e4d45569399a4eaea779c5d2d10ffb1 | |
parent | Recommit the change that explicitly passes %sr0 to fic instructions. miod@ is (diff) | |
download | wireguard-openbsd-379edb067b7ca6b40488dc0f4386b3563fb580cf.tar.xz wireguard-openbsd-379edb067b7ca6b40488dc0f4386b3563fb580cf.zip |
SH is a RelA architecture, not a Rel one. Fix _dl_bind() and lazy gotplt
relocation to correctly process RelA entries.
This allows lazy binding to work so far; not enabled yet, must survive some
serious churning first.
-rw-r--r-- | libexec/ld.so/sh/rtld_machine.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/libexec/ld.so/sh/rtld_machine.c b/libexec/ld.so/sh/rtld_machine.c index c6df59ddf0b..9e11c8a9370 100644 --- a/libexec/ld.so/sh/rtld_machine.c +++ b/libexec/ld.so/sh/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.15 2011/04/06 11:36:25 miod Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.16 2013/03/26 18:53:47 miod Exp $ */ /* * Copyright (c) 2004 Dale Rahn @@ -771,7 +771,7 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) Elf_Addr ooff; const Elf_Sym *this; int i, num; - Elf_Rel *rel; + Elf_RelA *rel; /* XXX - lazy binding not supported yet */ lazy = 0; @@ -793,8 +793,6 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) if (this != NULL) object->got_size = ooff + this->st_value - object->got_addr; - object->plt_size = 0; /* Text PLT on ARM */ - if (object->got_addr == 0) object->got_start = 0; else { @@ -803,17 +801,25 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) object->got_size = ELF_ROUND(object->got_size, _dl_pagesz); } object->plt_start = 0; + object->plt_size = 0; if (!lazy) { fails = _dl_md_reloc(object, DT_JMPREL, DT_PLTRELSZ); } else { - rel = (Elf_Rel *)(object->Dyn.info[DT_JMPREL]); - num = (object->Dyn.info[DT_PLTRELSZ]); + rel = (Elf_RelA *)(object->Dyn.info[DT_JMPREL]); + num = (object->Dyn.info[DT_PLTRELSZ]) / sizeof(Elf_RelA); + + for (i = 0; i < num; i++, rel++) { + Elf_Addr *where, value; + Elf_Word type; - for (i = 0; i < num/sizeof(Elf_Rel); i++, rel++) { - Elf_Addr *where; where = (Elf_Addr *)(rel->r_offset + object->obj_base); - *where += object->obj_base; + type = ELF_R_TYPE(rel->r_info); + if (RELOC_USE_ADDEND(type)) + value = rel->r_addend; + else + value = 0; + *where += object->obj_base + value; } pltgot[1] = (Elf_Addr)object; @@ -822,24 +828,21 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) if (object->got_size != 0) _dl_mprotect((void*)object->got_start, object->got_size, PROT_READ); - if (object->plt_size != 0) - _dl_mprotect((void*)object->plt_start, object->plt_size, - PROT_READ|PROT_EXEC); return (fails); } Elf_Addr -_dl_bind(elf_object_t *object, int relidx) +_dl_bind(elf_object_t *object, int reloff) { - Elf_Rel *rel; + Elf_RelA *rel; Elf_Word *addr; const Elf_Sym *sym, *this; const char *symn; Elf_Addr ooff, newval; sigset_t savedmask; - rel = ((Elf_Rel *)object->Dyn.info[DT_JMPREL]) + (relidx); + rel = (Elf_RelA *)(object->Dyn.info[DT_JMPREL] + reloff); sym = object->dyn.symtab; sym += ELF_R_SYM(rel->r_info); |