]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwfl_link_map_report: Handle unaligned auxv data.
authorRoland McGrath <roland@hack.frob.com>
Mon, 7 Jan 2013 22:53:37 +0000 (14:53 -0800)
committerRoland McGrath <roland@hack.frob.com>
Mon, 7 Jan 2013 23:10:33 +0000 (15:10 -0800)
Signed-off-by: Roland McGrath <roland@hack.frob.com>
libdw/ChangeLog
libdw/memory-access.h
libdwfl/ChangeLog
libdwfl/link_map.c

index 24f4bb488d17c1b3116594728a881e7ff5271512..3cf303249c2e581cedf15fee05adbf8bddd6dee6 100644 (file)
@@ -1,3 +1,9 @@
+2013-01-07  Roland McGrath  <roland@hack.frob.com>
+
+       * memory-access.h
+       [ALLOW_UNALIGNED] (read_8ubyte_unaligned_noncvt): New macro.
+       [!ALLOW_UNALIGNED] (read_8ubyte_unaligned_noncvt): New inline function.
+
 2012-12-18  Mark Wielaard  <mjw@redhat.com>
 
        * dwarf_begin_elf.c (valid_p): Call Dwarf_Sig8_Hash_free if invalid.
index 5773e5c9bf29bd7dca9d8e3f26f299d20ccc9329..16471990dfa032258842bdb8da641822de587060 100644 (file)
@@ -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 <drepper@redhat.com>, 2001.
 
@@ -147,6 +147,8 @@ __libdw_get_sleb128 (int64_t acc, unsigned int i, const unsigned char **addrp)
    ? (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)))                                 \
@@ -222,6 +224,12 @@ read_4sbyte_unaligned_1 (bool other_byte_order, const void *p)
   return up->s4;
 }
 
+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)
 {
index 896ae39001408da08112b51811b698a29af90caa..62973368a3ef0ed30657d35afe4c4ca15ef79ef1 100644 (file)
@@ -1,3 +1,9 @@
+2013-01-07  Roland McGrath  <roland@hack.frob.com>
+
+       * 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-12-11  Mark Wielaard  <mjw@redhat.com>
 
        * linux-kernel-modules.c (report_kernel): Only free fname if
index 8543ed6d6b0a735055118843c5ff0e278afe0f4b..00913fe2314c0948892375aac1c1b763adfd8b12 100644 (file)
@@ -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 <config.h>
 #include "libdwflP.h"
+#include "../libdw/memory-access.h"
 
 #include <byteswap.h>
 #include <endian.h>
@@ -66,15 +67,22 @@ auxv_format_probe (const void *auxv, size_t size,
 
   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 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
       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)