Date: Sat, 9 Aug 2014 22:51:27 +0000 (UTC) From: Warner Losh <imp@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r269767 - head/sys/arm/arm Message-ID: <53e6a5ef.2fbb.3bbe0e71@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: imp Date: Sat Aug 9 22:51:26 2014 New Revision: 269767 URL: http://svnweb.freebsd.org/changeset/base/269767 Log: Per discussion on arm@, the compiler generates misaligned relocations. Cope with memcpy when needed. Submitted by: fabient@ (plus changes suggested by thread) Modified: head/sys/arm/arm/elf_machdep.c Modified: head/sys/arm/arm/elf_machdep.c ============================================================================== --- head/sys/arm/arm/elf_machdep.c Sat Aug 9 21:01:24 2014 (r269766) +++ head/sys/arm/arm/elf_machdep.c Sat Aug 9 22:51:26 2014 (r269767) @@ -120,6 +120,34 @@ elf32_dump_thread(struct thread *td __un { } +/* + * It is possible for the compiler to emit relocations for unaligned data. + * We handle this situation with these inlines. + */ +#define RELOC_ALIGNED_P(x) \ + (((uintptr_t)(x) & (sizeof(void *) - 1)) == 0) + +static __inline Elf_Addr +load_ptr(Elf_Addr *where) +{ + Elf_Addr res; + + if (RELOC_ALIGNED_P(where)) + return *where; + memcpy(&res, where, sizeof(res)); + return (res); +} + +static __inline void +store_ptr(Elf_Addr *where, Elf_Addr val) +{ + if (RELOC_ALIGNED_P(where)) + *where = val; + else + memcpy(where, &val, sizeof(val)); +} +#undef RELOC_ALIGNED_P + /* Process one elf relocation with addend. */ static int @@ -137,7 +165,7 @@ elf_reloc_internal(linker_file_t lf, Elf case ELF_RELOC_REL: rel = (const Elf_Rel *)data; where = (Elf_Addr *) (relocbase + rel->r_offset); - addend = *where; + addend = load_ptr(where); rtype = ELF_R_TYPE(rel->r_info); symidx = ELF_R_SYM(rel->r_info); break; @@ -155,8 +183,8 @@ elf_reloc_internal(linker_file_t lf, Elf if (local) { if (rtype == R_ARM_RELATIVE) { /* A + B */ addr = elf_relocaddr(lf, relocbase + addend); - if (*where != addr) - *where = addr; + if (load_ptr(where) != addr) + store_ptr(where, addr); } return (0); } @@ -170,7 +198,7 @@ elf_reloc_internal(linker_file_t lf, Elf addr = lookup(lf, symidx, 1); if (addr == 0) return -1; - *where += addr; + store_ptr(where, addr + load_ptr(where)); break; case R_ARM_COPY: /* none */ @@ -185,7 +213,7 @@ elf_reloc_internal(linker_file_t lf, Elf case R_ARM_JUMP_SLOT: addr = lookup(lf, symidx, 1); if (addr) { - *where = addr; + store_ptr(where, addr); return (0); } return (-1);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?53e6a5ef.2fbb.3bbe0e71>