summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland McGrath <[email protected]>2005-12-08 01:36:18 +0000
committerRoland McGrath <[email protected]>2005-12-08 01:36:18 +0000
commit7747de9206b36a719abdbb4b2e66ed8dca13c97e (patch)
tree7db99d1f324506ccabac169e667e5acfb79508f5
parentf3684edbf6d312b1f56575d311efb7c0d29cc62d (diff)
2005-12-07 Roland McGrath <[email protected]>
* gelf_xlate.c [! ALLOW_UNALIGNED] (union unaligned): New type. (FETCH, STORE): New macros. (INLINE3): Use those to do alignment-friendly conversion. * elf32_getshdr.c: Include map_address and start_offset in alignment calculations. * elf32_getphdr.c: Likewise.
-rw-r--r--libelf/ChangeLog10
-rw-r--r--libelf/elf32_getphdr.c10
-rw-r--r--libelf/elf32_getshdr.c6
-rw-r--r--libelf/gelf_xlate.c67
4 files changed, 61 insertions, 32 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index ba1bb952..2714ff34 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,13 @@
+2005-12-07 Roland McGrath <[email protected]>
+
+ * gelf_xlate.c [! ALLOW_UNALIGNED] (union unaligned): New type.
+ (FETCH, STORE): New macros.
+ (INLINE3): Use those to do alignment-friendly conversion.
+
+ * elf32_getshdr.c: Include map_address and start_offset in alignment
+ calculations.
+ * elf32_getphdr.c: Likewise.
+
2005-11-19 Roland McGrath <[email protected]>
* elf.h: Update from glibc.
diff --git a/libelf/elf32_getphdr.c b/libelf/elf32_getphdr.c
index 341acf09..4544fabb 100644
--- a/libelf/elf32_getphdr.c
+++ b/libelf/elf32_getphdr.c
@@ -85,8 +85,9 @@ elfw2(LIBELFBITS,getphdr) (elf)
/* All the data is already mapped. Use it. */
if (ehdr->e_ident[EI_DATA] == MY_ELFDATA
&& (ALLOW_UNALIGNED
- || (ehdr->e_phoff
- & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) - 1)) == 0))
+ || ((((uintptr_t) elf->map_address + elf->start_offset
+ + ehdr->e_phoff)
+ & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) - 1)) == 0)))
/* Simply use the mapped data. */
elf->state.ELFW(elf,LIBELFBITS).phdr = (ElfW2(LIBELFBITS,Phdr) *)
((char *) elf->map_address + elf->start_offset + ehdr->e_phoff);
@@ -110,8 +111,9 @@ elfw2(LIBELFBITS,getphdr) (elf)
/* Now copy the data and at the same time convert the
byte order. */
if (ALLOW_UNALIGNED
- || (ehdr->e_phoff
- & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) - 1)) == 0)
+ || ((((uintptr_t) elf->map_address + elf->start_offset
+ + ehdr->e_phoff)
+ & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) - 1)) == 0))
notcvt = (ElfW2(LIBELFBITS,Phdr) *)
((char *) elf->map_address
+ elf->start_offset + ehdr->e_phoff);
diff --git a/libelf/elf32_getshdr.c b/libelf/elf32_getshdr.c
index cf7a41fd..73a4e68e 100644
--- a/libelf/elf32_getshdr.c
+++ b/libelf/elf32_getshdr.c
@@ -91,13 +91,15 @@ elfw2(LIBELFBITS,getshdr) (scn)
directly this would already have happened. */
assert (ehdr->e_ident[EI_DATA] != MY_ELFDATA
|| (! ALLOW_UNALIGNED
- && (ehdr->e_shoff
+ && (((uintptr_t) elf->map_address + elf->start_offset
+ + ehdr->e_shoff)
& (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) != 0));
/* Now copy the data and at the same time convert the byte
order. */
if (ALLOW_UNALIGNED
- || (ehdr->e_shoff
+ || (((uintptr_t) elf->map_address + elf->start_offset
+ + ehdr->e_shoff)
& (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) == 0)
notcvt = (ElfW2(LIBELFBITS,Shdr) *)
((char *) elf->map_address
diff --git a/libelf/gelf_xlate.c b/libelf/gelf_xlate.c
index bbb133a3..b32e92b3 100644
--- a/libelf/gelf_xlate.c
+++ b/libelf/gelf_xlate.c
@@ -22,6 +22,7 @@
#include <byteswap.h>
#include <stdint.h>
#include <string.h>
+#include <stdlib.h>
#include "libelfP.h"
@@ -47,15 +48,25 @@ static void
bit. We need only functions for 16, 32, and 64 bits. The
functions referenced in the table will be aliases for one of these
functions. Which one is decided by the ELFxx_FSZ_type. */
-#define LEN2_SWAP(Src) bswap_16 (*((uint16_t *) Src))
-#define word2_t uint16_t
-#define LEN4_SWAP(Src) bswap_32 (*((uint32_t *) Src))
-#define word4_t uint32_t
+#if ALLOW_UNALIGNED
-#define LEN8_SWAP(Src) bswap_64 (*((uint64_t *) Src))
-#define word8_t uint64_t
+#define FETCH(Bits, ptr) (*(const uint##Bits##_t *) ptr)
+#define STORE(Bits, ptr, val) (*(uint##Bits##_t *) ptr = val)
+#else
+
+union unaligned
+ {
+ uint16_t u16;
+ uint32_t u32;
+ uint64_t u64;
+ } __attribute__ ((packed));
+
+#define FETCH(Bits, ptr) (((const union unaligned *) ptr)->u##Bits)
+#define STORE(Bits, ptr, val) (((union unaligned *) ptr)->u##Bits = val)
+
+#endif
/* Now define the conversion functions for the basic types. We use here
the fact that file and memory types are the same and that we have the
@@ -67,37 +78,41 @@ static void
INLINE2 (ELFW2(Bits,FSZ_##NAME), ElfW2(Bits,cvt_##Name), ElfW2(Bits,Name))
#define INLINE2(Bytes, FName, TName) \
INLINE3 (Bytes, FName, TName)
-#define INLINE3(Bytes, FName, TName) \
+#define INLINE3(Bytes, FName, TName) \
+ static inline void FName##1 (void *dest, const void *ptr) \
+ { \
+ switch (Bytes) \
+ { \
+ case 2: STORE (16, dest, bswap_16 (FETCH (16, ptr))); break; \
+ case 4: STORE (32, dest, bswap_32 (FETCH (32, ptr))); break; \
+ case 8: STORE (64, dest, bswap_64 (FETCH (64, ptr))); break; \
+ default: \
+ abort (); \
+ } \
+ } \
+ \
static void FName (void *dest, const void *ptr, size_t len, \
int encode __attribute__ ((unused))) \
{ \
size_t n = len / sizeof (TName); \
if (dest < ptr) \
- { \
- word##Bytes##_t *tdest = (word##Bytes##_t *) dest; \
- const word##Bytes##_t *tptr = (const word##Bytes##_t *) ptr; \
- while (n-- > 0) \
- { \
- *tdest++ = LEN##Bytes##_SWAP (tptr); \
- tptr++; \
- } \
- } \
+ while (n-- > 0) \
+ { \
+ FName##1 (dest, ptr); \
+ dest += Bytes; \
+ ptr += Bytes; \
+ } \
else \
{ \
- word##Bytes##_t *tdest = (word##Bytes##_t *) dest + n; \
- const word##Bytes##_t *tptr = (const word##Bytes##_t *) ptr + n; \
+ dest += len; \
+ ptr += len; \
while (n-- > 0) \
{ \
- --tptr; \
- *--tdest = LEN##Bytes##_SWAP (tptr); \
+ ptr -= Bytes; \
+ dest -= Bytes; \
+ FName##1 (dest, ptr); \
} \
} \
- } \
- \
- static inline void FName##1 (void *dest, const void *ptr) \
- { \
- *((word##Bytes##_t *) dest) = \
- LEN##Bytes##_SWAP ((((word##Bytes##_t *) ptr))); \
}