summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libdw/ChangeLog6
-rw-r--r--libdw/memory-access.h10
-rw-r--r--libdwfl/ChangeLog6
-rw-r--r--libdwfl/link_map.c67
4 files changed, 60 insertions, 29 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 24f4bb48..3cf30324 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,9 @@
+2013-01-07 Roland McGrath <[email protected]>
+
+ * 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 <[email protected]>
* dwarf_begin_elf.c (valid_p): Call Dwarf_Sig8_Hash_free if invalid.
diff --git a/libdw/memory-access.h b/libdw/memory-access.h
index 5773e5c9..16471990 100644
--- a/libdw/memory-access.h
+++ b/libdw/memory-access.h
@@ -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 <[email protected]>, 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))) \
@@ -223,6 +225,12 @@ read_4sbyte_unaligned_1 (bool other_byte_order, const void *p)
}
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;
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 896ae390..62973368 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,9 @@
+2013-01-07 Roland McGrath <[email protected]>
+
+ * 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 <[email protected]>
* linux-kernel-modules.c (report_kernel): Only free fname if
diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c
index 8543ed6d..00913fe2 100644
--- a/libdwfl/link_map.c
+++ b/libdwfl/link_map.c
@@ -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)