From 091b5a94257391fe6051c83f0f32104f0d824202 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Jan 10 2013 10:07:52 +0000 Subject: Unaligned memory access issues (#891553) --- diff --git a/elfutils-0.154-binutils-pr-ld-13621.patch b/elfutils-0.154-binutils-pr-ld-13621.patch deleted file mode 100644 index 06dba1e..0000000 --- a/elfutils-0.154-binutils-pr-ld-13621.patch +++ /dev/null @@ -1,10 +0,0 @@ -diff --git a/tests/run-elflint-self.sh b/tests/run-elflint-self.sh -index 8aca9e1..d449416 100755 ---- a/tests/run-elflint-self.sh -+++ b/tests/run-elflint-self.sh -@@ -51,4 +51,4 @@ runtest ../libebl/libebl_sh.so - runtest ../libebl/libebl_sparc.so - runtest ../libebl/libebl_x86_64.so - --exit $status -+test $status == 0 || echo "binutils PR ld/13621 workaround" diff --git a/elfutils-0.155-mem-align.patch b/elfutils-0.155-mem-align.patch new file mode 100644 index 0000000..37c1891 --- /dev/null +++ b/elfutils-0.155-mem-align.patch @@ -0,0 +1,194 @@ +--- a/libdw/ChangeLog 2012-08-27 20:29:31.000000000 +0200 ++++ b/libdw/ChangeLog 2013-01-10 10:59:28.039026230 +0100 +@@ -1,3 +1,9 @@ ++2013-01-07 Roland McGrath ++ ++ * memory-access.h ++ [ALLOW_UNALIGNED] (read_8ubyte_unaligned_noncvt): New macro. ++ [!ALLOW_UNALIGNED] (read_8ubyte_unaligned_noncvt): New inline function. ++ + 2012-08-24 Mark Wielaard + + * dwarf_begin_elf.c (check_section): Only probe for dwz multi files +--- a/libdw/memory-access.h 2012-08-27 20:27:31.000000000 +0200 ++++ b/libdw/memory-access.h 2013-01-10 10:56:07.171152555 +0100 +@@ -1,5 +1,5 @@ + /* Unaligned memory access functionality. +- Copyright (C) 2000-2010 Red Hat, Inc. ++ Copyright (C) 2000-2013 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper , 2001. + +@@ -147,6 +147,8 @@ + ? (int32_t) bswap_32 (*((const int32_t *) (Addr))) \ + : *((const int32_t *) (Addr))) + ++# define read_8ubyte_unaligned_noncvt(Addr) \ ++ *((const uint64_t *) (Addr)) + # define read_8ubyte_unaligned(Dbg, Addr) \ + (unlikely ((Dbg)->other_byte_order) \ + ? bswap_64 (*((const uint64_t *) (Addr))) \ +@@ -223,6 +225,12 @@ + } + + static inline uint64_t ++read_8ubyte_unaligned_noncvt (const void *p) ++{ ++ const union unaligned *up = p; ++ return up->u8; ++} ++static inline uint64_t + read_8ubyte_unaligned_1 (bool other_byte_order, const void *p) + { + const union unaligned *up = p; +--- a/libdwfl/ChangeLog 2013-01-10 10:59:53.882008409 +0100 ++++ b/libdwfl/ChangeLog 2013-01-10 10:57:48.451130775 +0100 +@@ -1,3 +1,9 @@ ++2013-01-07 Roland McGrath ++ ++ * link_map.c (auxv_format_probe): Handle unaligned 64-bit data, but ++ still assume the data is at least 32-bit aligned anyway. ++ (dwfl_link_map_report): Handle unaligned auxv data. ++ + 2012-08-01 Petr Machata + + * offline.c (process_archive_member): Ignore entry "/SYM64/". +--- a/libdwfl/link_map.c 2012-08-27 20:27:31.000000000 +0200 ++++ b/libdwfl/link_map.c 2013-01-10 10:56:07.207002831 +0100 +@@ -1,5 +1,5 @@ + /* Report modules by examining dynamic linker data structures. +- Copyright (C) 2008-2010 Red Hat, Inc. ++ Copyright (C) 2008-2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify +@@ -28,6 +28,7 @@ + + #include + #include "libdwflP.h" ++#include "../libdw/memory-access.h" + + #include + #include +@@ -66,15 +67,22 @@ + + inline bool check64 (size_t i) + { +- if (u->a64[i].a_type == BE64 (PROBE_TYPE) +- && u->a64[i].a_un.a_val == BE64 (PROBE_VAL64)) ++ /* The AUXV pointer might not even be naturally aligned for 64-bit ++ data, because note payloads in a core file are not aligned. ++ But we assume the data is 32-bit aligned. */ ++ ++ uint64_t type = read_8ubyte_unaligned_noncvt (&u->a64[i].a_type); ++ uint64_t val = read_8ubyte_unaligned_noncvt (&u->a64[i].a_un.a_val); ++ ++ if (type == BE64 (PROBE_TYPE) ++ && val == BE64 (PROBE_VAL64)) + { + *elfdata = ELFDATA2MSB; + return true; + } + +- if (u->a64[i].a_type == LE64 (PROBE_TYPE) +- && u->a64[i].a_un.a_val == LE64 (PROBE_VAL64)) ++ if (type == LE64 (PROBE_TYPE) ++ && val == LE64 (PROBE_VAL64)) + { + *elfdata = ELFDATA2LSB; + return true; +@@ -618,29 +626,32 @@ + GElf_Xword phent = 0; + GElf_Xword phnum = 0; + +-#define AUXV_SCAN(NN, BL) do \ +- { \ +- const Elf##NN##_auxv_t *av = auxv; \ +- for (size_t i = 0; i < auxv_size / sizeof av[0]; ++i) \ +- { \ +- Elf##NN##_Addr val = BL##NN (av[i].a_un.a_val); \ +- if (av[i].a_type == BL##NN (AT_ENTRY)) \ +- entry = val; \ +- else if (av[i].a_type == BL##NN (AT_PHDR)) \ +- phdr = val; \ +- else if (av[i].a_type == BL##NN (AT_PHNUM)) \ +- phnum = val; \ +- else if (av[i].a_type == BL##NN (AT_PHENT)) \ +- phent = val; \ +- else if (av[i].a_type == BL##NN (AT_PAGESZ)) \ +- { \ +- if (val > 1 \ +- && (dwfl->segment_align == 0 \ +- || val < dwfl->segment_align)) \ +- dwfl->segment_align = val; \ +- } \ +- } \ +- } \ ++#define READ_AUXV32(ptr) read_4ubyte_unaligned_noncvt (ptr) ++#define READ_AUXV64(ptr) read_8ubyte_unaligned_noncvt (ptr) ++#define AUXV_SCAN(NN, BL) do \ ++ { \ ++ const Elf##NN##_auxv_t *av = auxv; \ ++ for (size_t i = 0; i < auxv_size / sizeof av[0]; ++i) \ ++ { \ ++ uint##NN##_t type = READ_AUXV##NN (&av[i].a_type); \ ++ uint##NN##_t val = BL##NN (READ_AUXV##NN (&av[i].a_un.a_val)); \ ++ if (type == BL##NN (AT_ENTRY)) \ ++ entry = val; \ ++ else if (type == BL##NN (AT_PHDR)) \ ++ phdr = val; \ ++ else if (type == BL##NN (AT_PHNUM)) \ ++ phnum = val; \ ++ else if (type == BL##NN (AT_PHENT)) \ ++ phent = val; \ ++ else if (type == BL##NN (AT_PAGESZ)) \ ++ { \ ++ if (val > 1 \ ++ && (dwfl->segment_align == 0 \ ++ || val < dwfl->segment_align)) \ ++ dwfl->segment_align = val; \ ++ } \ ++ } \ ++ } \ + while (0) + + if (elfclass == ELFCLASS32) +--- a/libelf/ChangeLog 2013-01-10 10:59:53.884010033 +0100 ++++ b/libelf/ChangeLog 2013-01-10 10:58:57.505003982 +0100 +@@ -1,3 +1,13 @@ ++2013-01-07 Roland McGrath ++ ++ * elf_getarsym.c (elf_getarsym): Copy FILE_DATA into stack space if it ++ would be unaligned and !ALLOW_UNALIGNED. ++ ++2013-01-07 Roland McGrath ++ ++ * elf_getarsym.c (read_number_entries): Use memcpy instead of pointer ++ dereference so as not to assume the field is naturally aligned. ++ + 2012-08-16 Roland McGrath + + * elf.h: Update from glibc. +--- a/libelf/elf_getarsym.c 2013-01-10 10:59:53.888006636 +0100 ++++ b/libelf/elf_getarsym.c 2013-01-10 10:56:07.210254028 +0100 +@@ -57,7 +57,9 @@ + + size_t w = index64_p ? 8 : 4; + if (elf->map_address != NULL) +- u = *(union u *) (elf->map_address + *offp); ++ /* Use memcpy instead of pointer dereference so as not to assume the ++ field is naturally aligned within the file. */ ++ memcpy (&u, elf->map_address + *offp, sizeof u); + else if ((size_t) pread_retry (elf->fildes, &u, w, *offp) != w) + return -1; + +@@ -241,6 +243,9 @@ + else + { + file_data = (void *) (elf->map_address + off); ++ if (!ALLOW_UNALIGNED ++ && ((uintptr_t) file_data & -(uintptr_t) n) != 0) ++ file_data = memcpy (alloca (sz), elf->map_address + off, sz); + str_data = (char *) (elf->map_address + off + sz); + } + diff --git a/elfutils.spec b/elfutils.spec index a5120fd..3b73ec2 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -1,7 +1,7 @@ Name: elfutils Summary: A collection of utilities and DSOs to handle compiled objects Version: 0.155 -%global baserelease 1 +%global baserelease 2 URL: https://fedorahosted.org/elfutils/ %global source_url http://fedorahosted.org/releases/e/l/elfutils/%{version}/ License: GPLv3+ and (GPLv2+ or LGPLv3+) @@ -46,6 +46,7 @@ Source: %{?source_url}%{name}-%{version}.tar.bz2 Patch1: %{?source_url}elfutils-robustify.patch Patch2: %{?source_url}elfutils-portability.patch Patch3: elfutils-0.155-binutils-pr-ld-13621.patch +Patch4: elfutils-0.155-mem-align.patch %if !%{compat} Release: %{baserelease}%{?dist} @@ -211,6 +212,7 @@ sed -i.scanf-m -e 's/%m/%a/g' src/addr2line.c tests/line2addr.c %endif %patch3 -p1 -b .binutils-pr-ld-13621 +%patch4 -p1 -b .mem-align find . -name \*.sh ! -perm -0100 -print | xargs chmod +x @@ -327,6 +329,9 @@ rm -rf ${RPM_BUILD_ROOT} %{_libdir}/libelf.a %changelog +* Thu Jan 10 2013 Mark Wielaard - 0.155-2 +- #891553 - unaligned memory access issues. + * Mon Aug 27 2012 Mark Wielaard - 0.155-1 - Update to 0.155. - #844270 - eu-nm invalid %N$ use detected.