diff options
| author | simonb <simonb@NetBSD.org> | 2006-06-28 16:48:38 +0000 |
|---|---|---|
| committer | simonb <simonb@NetBSD.org> | 2006-06-28 16:48:38 +0000 |
| commit | 428d37fad6f3900e55ee4a2042e231df2e565aaf (patch) | |
| tree | 4700effacc37e6679bccfefa41d7639b1798992b /libexec | |
| parent | 7d0c55ee3400b7759b377f7f6458d30a0b507dd3 (diff) | |
Fix unaligned loads and stores generated by gcc4. Problem described in
http://mail-index.NetBSD.org/tech-toolchain/2006/06/27/0001.html.
This cleaner version of the patch from Christos - thanks!
Diffstat (limited to 'libexec')
| -rw-r--r-- | libexec/ld.elf_so/arch/mips/mips_reloc.c | 55 |
1 files changed, 23 insertions, 32 deletions
diff --git a/libexec/ld.elf_so/arch/mips/mips_reloc.c b/libexec/ld.elf_so/arch/mips/mips_reloc.c index 4bb7deac21a..50f3e392add 100644 --- a/libexec/ld.elf_so/arch/mips/mips_reloc.c +++ b/libexec/ld.elf_so/arch/mips/mips_reloc.c @@ -1,4 +1,4 @@ -/* $NetBSD: mips_reloc.c,v 1.51 2006/04/03 13:23:15 skrll Exp $ */ +/* $NetBSD: mips_reloc.c,v 1.52 2006/06/28 16:48:38 simonb Exp $ */ /* * Copyright 1997 Michael L. Hitch <mhitch@montana.edu> @@ -30,7 +30,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: mips_reloc.c,v 1.51 2006/04/03 13:23:15 skrll Exp $"); +__RCSID("$NetBSD: mips_reloc.c,v 1.52 2006/06/28 16:48:38 simonb Exp $"); #endif /* not lint */ #include <sys/types.h> @@ -58,18 +58,23 @@ caddr_t _rtld_bind(Elf_Word, Elf_Addr, Elf_Addr, Elf_Addr); static inline Elf_Addr load_ptr(void *where) { - Elf_Addr res; + if (__predict_true(RELOC_ALIGNED_P(where))) + return *(Elf_Addr *)where; + else { + Elf_Addr res; - memcpy(&res, where, sizeof(res)); - - return res; + (void)memcpy(&res, where, sizeof(res)); + return res; + } } static inline void store_ptr(void *where, Elf_Addr val) { - - memcpy(where, &val, sizeof(val)); + if (__predict_true(RELOC_ALIGNED_P(where))) + *(Elf_Addr *)where = val; + else + (void)memcpy(where, &val, sizeof(val)); } @@ -86,7 +91,7 @@ _rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase) { const Elf_Rel *rel = 0, *rellim; Elf_Addr relsz = 0; - Elf_Addr *where; + void *where; const Elf_Sym *symtab = NULL, *sym; Elf_Addr *got = NULL; Elf_Word local_gotno = 0, symtabno = 0, gotsym = 0; @@ -133,7 +138,7 @@ _rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase) rellim = (const Elf_Rel *)((caddr_t)rel + relsz); for (; rel < rellim; rel++) { - where = (Elf_Addr *)(relocbase + rel->r_offset); + where = (void *)(relocbase + rel->r_offset); switch (ELF_R_TYPE(rel->r_info)) { case R_TYPE(NONE): @@ -143,10 +148,7 @@ _rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase) assert(ELF_R_SYM(rel->r_info) < gotsym); sym = symtab + ELF_R_SYM(rel->r_info); assert(ELF_ST_BIND(sym->st_info) == STB_LOCAL); - if (__predict_true(RELOC_ALIGNED_P(where))) - *where += relocbase; - else - store_ptr(where, load_ptr(where) + relocbase); + store_ptr(where, load_ptr(where) + relocbase); break; default: @@ -245,10 +247,11 @@ _rtld_relocate_nonplt_objects(const Obj_Entry *obj) got = obj->pltgot; for (rel = obj->rel; rel < obj->rellim; rel++) { - Elf_Addr *where, tmp; + void *where; + Elf_Addr tmp; unsigned long symnum; - where = (Elf_Addr *)(obj->relocbase + rel->r_offset); + where = obj->relocbase + rel->r_offset; symnum = ELF_R_SYM(rel->r_info); switch (ELF_R_TYPE(rel->r_info)) { @@ -260,15 +263,9 @@ _rtld_relocate_nonplt_objects(const Obj_Entry *obj) def = obj->symtab + symnum; if (symnum >= obj->gotsym) { - if (__predict_true(RELOC_ALIGNED_P(where))) - tmp = *where; - else - tmp = load_ptr(where); + tmp = load_ptr(where); tmp += got[obj->local_gotno + symnum - obj->gotsym]; - if (__predict_true(RELOC_ALIGNED_P(where))) - *where = tmp; - else - store_ptr(where, tmp); + store_ptr(where, tmp); rdbg(("REL32/G %s in %s --> %p in %s", obj->strtab + def->st_name, obj->path, @@ -290,10 +287,7 @@ _rtld_relocate_nonplt_objects(const Obj_Entry *obj) * * --rkb, Oct 6, 2001 */ - if (__predict_true(RELOC_ALIGNED_P(where))) - tmp = *where; - else - tmp = load_ptr(where); + tmp = load_ptr(where); if (def->st_info == ELF_ST_INFO(STB_LOCAL, STT_SECTION) @@ -304,10 +298,7 @@ _rtld_relocate_nonplt_objects(const Obj_Entry *obj) tmp += (Elf_Addr)def->st_value; tmp += (Elf_Addr)obj->relocbase; - if (__predict_true(RELOC_ALIGNED_P(where))) - *where = tmp; - else - store_ptr(where, tmp); + store_ptr(where, tmp); rdbg(("REL32/L %s in %s --> %p in %s", obj->strtab + def->st_name, obj->path, |
