summaryrefslogtreecommitdiff
path: root/elfutils/libelf/elf_getdata.c
diff options
context:
space:
mode:
Diffstat (limited to 'elfutils/libelf/elf_getdata.c')
-rw-r--r--elfutils/libelf/elf_getdata.c162
1 files changed, 64 insertions, 98 deletions
diff --git a/elfutils/libelf/elf_getdata.c b/elfutils/libelf/elf_getdata.c
index 1fa4a17f..ae5b41df 100644
--- a/elfutils/libelf/elf_getdata.c
+++ b/elfutils/libelf/elf_getdata.c
@@ -1,5 +1,5 @@
/* Return the next data element from the section after possibly converting it.
- Copyright (C) 1998-2005, 2006 Red Hat, Inc.
+ Copyright (C) 1998-2005, 2006, 2007 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 1998.
@@ -63,13 +63,6 @@
#include "elf-knowledge.h"
-#if _STRING_ARCH_unaligned
-# define ALLOW_ALIGNED 1
-#else
-# define ALLOW_ALIGNED 0
-#endif
-
-
#define TYPEIDX(Sh_Type) \
(Sh_Type >= SHT_NULL && Sh_Type < SHT_NUM \
? Sh_Type \
@@ -77,95 +70,75 @@
? SHT_NUM + Sh_Type - SHT_GNU_HASH \
: 0))
-static const struct
-{
- Elf_Type type;
- size_t size;
-#if ALLOW_ALIGNED
-# define AL(val)
-#else
- size_t align;
-# define AL(val), val
-#endif
-} shtype_map[EV_NUM - 1][ELFCLASSNUM - 1][TYPEIDX (SHT_HISUNW) + 1] =
-{
- [EV_CURRENT - 1] =
+/* Associate section types with libelf types. */
+static const Elf_Type shtype_map[EV_NUM - 1][TYPEIDX (SHT_HISUNW) + 1] =
{
- [ELFCLASS32 - 1] =
+ [EV_CURRENT - 1] =
{
- /* Associate section types with libelf types, their sizes and
- alignment. SHT_GNU_verdef is special since the section does
- not contain entries of only one size. */
-#define DEFINE(Bits) \
- [SHT_SYMTAB] = { ELF_T_SYM, sizeof (ElfW2(Bits,Sym)) \
- AL (__alignof__ (ElfW2(Bits,Sym))) }, \
- [SHT_RELA] = { ELF_T_RELA, sizeof (ElfW2(Bits,Rela)) \
- AL (__alignof__ (ElfW2(Bits,Rela))) }, \
- [SHT_HASH] = { ELF_T_WORD, sizeof (ElfW2(Bits,Word)) \
- AL (__alignof__ (ElfW2(Bits,Word))) }, \
- [SHT_DYNAMIC] = { ELF_T_DYN, sizeof (ElfW2(Bits,Dyn)) \
- AL (__alignof__ (ElfW2(Bits,Dyn))) }, \
- [SHT_REL] = { ELF_T_REL, sizeof (ElfW2(Bits,Rel)) \
- AL (__alignof__ (ElfW2(Bits,Rel))) }, \
- [SHT_DYNSYM] = { ELF_T_SYM, sizeof (ElfW2(Bits,Sym)) \
- AL (__alignof__ (ElfW2(Bits,Sym))) }, \
- [SHT_INIT_ARRAY] = { ELF_T_ADDR, sizeof (ElfW2(Bits,Addr)) \
- AL (__alignof__ (ElfW2(Bits,Addr))) }, \
- [SHT_FINI_ARRAY] = { ELF_T_ADDR, sizeof (ElfW2(Bits,Addr)) \
- AL (__alignof__ (ElfW2(Bits,Addr))) }, \
- [SHT_PREINIT_ARRAY] = { ELF_T_ADDR, sizeof (ElfW2(Bits,Addr)) \
- AL (__alignof__ (ElfW2(Bits,Addr))) }, \
- [SHT_GROUP] = { ELF_T_WORD, sizeof (Elf32_Word) \
- AL (__alignof__ (Elf32_Word)) }, \
- [SHT_SYMTAB_SHNDX] = { ELF_T_WORD, sizeof (Elf32_Word) \
- AL (__alignof__ (Elf32_Word)) }, \
- [TYPEIDX (SHT_GNU_verdef)] = { ELF_T_VDEF, 1 AL (1) }, \
- [TYPEIDX (SHT_GNU_verneed)] = { ELF_T_VNEED, \
- sizeof (ElfW2(Bits,Verneed)) \
- AL (__alignof__ (ElfW2(Bits,Verneed)))},\
- [TYPEIDX (SHT_GNU_versym)] = { ELF_T_HALF, sizeof (ElfW2(Bits,Versym)) \
- AL (__alignof__ (ElfW2(Bits,Versym))) }, \
- [TYPEIDX (SHT_SUNW_syminfo)] = { ELF_T_SYMINFO, \
- sizeof (ElfW2(Bits,Syminfo)) \
- AL(__alignof__ (ElfW2(Bits,Syminfo)))},\
- [TYPEIDX (SHT_SUNW_move)] = { ELF_T_MOVE, sizeof (ElfW2(Bits,Move)) \
- AL (__alignof__ (ElfW2(Bits,Move))) }, \
- [TYPEIDX (SHT_GNU_LIBLIST)] = { ELF_T_LIB, sizeof (ElfW2(Bits,Lib)) \
- AL (__alignof__ (ElfW2(Bits,Lib))) }
- DEFINE (32),
- [TYPEIDX (SHT_GNU_HASH)] = { ELF_T_WORD, sizeof (Elf32_Word)
- AL (__alignof__ (Elf32_Word)) }
- },
- [ELFCLASS64 - 1] =
+ [SHT_SYMTAB] = ELF_T_SYM,
+ [SHT_RELA] = ELF_T_RELA,
+ [SHT_HASH] = ELF_T_WORD,
+ [SHT_DYNAMIC] = ELF_T_DYN,
+ [SHT_REL] = ELF_T_REL,
+ [SHT_DYNSYM] = ELF_T_SYM,
+ [SHT_INIT_ARRAY] = ELF_T_ADDR,
+ [SHT_FINI_ARRAY] = ELF_T_ADDR,
+ [SHT_PREINIT_ARRAY] = ELF_T_ADDR,
+ [SHT_GROUP] = ELF_T_WORD,
+ [SHT_SYMTAB_SHNDX] = ELF_T_WORD,
+ [SHT_NOTE] = ELF_T_NHDR,
+ [TYPEIDX (SHT_GNU_verdef)] = ELF_T_VDEF,
+ [TYPEIDX (SHT_GNU_verneed)] = ELF_T_VNEED,
+ [TYPEIDX (SHT_GNU_versym)] = ELF_T_HALF,
+ [TYPEIDX (SHT_SUNW_syminfo)] = ELF_T_SYMINFO,
+ [TYPEIDX (SHT_SUNW_move)] = ELF_T_MOVE,
+ [TYPEIDX (SHT_GNU_LIBLIST)] = ELF_T_LIB,
+ [TYPEIDX (SHT_GNU_HASH)] = ELF_T_GNUHASH,
+ }
+ };
+
+#if !ALLOW_UNALIGNED
+/* Associate libelf types with their internal alignment requirements. */
+const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
+ {
+# define TYPE_ALIGNS(Bits) \
+ { \
+ [ELF_T_ADDR] = __alignof__ (ElfW2(Bits,Addr)), \
+ [ELF_T_HALF] = __alignof__ (ElfW2(Bits,Half)), \
+ [ELF_T_WORD] = __alignof__ (ElfW2(Bits,Word)), \
+ [ELF_T_SYM] = __alignof__ (ElfW2(Bits,Sym)), \
+ [ELF_T_SYMINFO] = __alignof__ (ElfW2(Bits,Syminfo)), \
+ [ELF_T_REL] = __alignof__ (ElfW2(Bits,Rel)), \
+ [ELF_T_RELA] = __alignof__ (ElfW2(Bits,Rela)), \
+ [ELF_T_DYN] = __alignof__ (ElfW2(Bits,Dyn)), \
+ [ELF_T_VDEF] = __alignof__ (ElfW2(Bits,Verdef)), \
+ [ELF_T_VDAUX] = __alignof__ (ElfW2(Bits,Verdaux)), \
+ [ELF_T_VNEED] = __alignof__ (ElfW2(Bits,Verneed)), \
+ [ELF_T_VNAUX] = __alignof__ (ElfW2(Bits,Vernaux)), \
+ [ELF_T_MOVE] = __alignof__ (ElfW2(Bits,Move)), \
+ [ELF_T_LIB] = __alignof__ (ElfW2(Bits,Lib)), \
+ [ELF_T_NHDR] = __alignof__ (ElfW2(Bits,Nhdr)), \
+ }
+ [EV_CURRENT - 1] =
{
- DEFINE (64),
- [TYPEIDX (SHT_GNU_HASH)] = { ELF_T_GNUHASH, 1
- AL (__alignof__ (Elf64_Xword)) }
+ [ELFCLASS32 - 1] = TYPE_ALIGNS (32),
+ [ELFCLASS64 - 1] = TYPE_ALIGNS (64),
}
- }
-};
+# undef TYPE_ALIGNS
+ };
+#endif
/* Convert the data in the current section. */
static void
convert_data (Elf_Scn *scn, int version __attribute__ ((unused)), int eclass,
- int data, size_t size, size_t type)
+ int data, size_t size, Elf_Type type)
{
-#if ALLOW_ALIGNED
- /* No need to compute the alignment requirement of the host. */
- const size_t align = 1;
-#else
-# if EV_NUM != 2
- size_t align = shtype_map[version - 1][eclass - 1][type].align;
-# else
- size_t align = shtype_map[0][eclass - 1][type].align;
-# endif
-#endif
+ const size_t align = __libelf_type_align (eclass, type);
if (data == MY_ELFDATA)
{
- if (ALLOW_ALIGNED
- || (((size_t) ((char *) scn->rawdata_base)) & (align - 1)) == 0)
+ if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
/* No need to copy, we can use the raw data. */
scn->data_base = scn->rawdata_base;
else
@@ -266,11 +239,12 @@ __libelf_set_rawdata (Elf_Scn *scn)
}
else
{
-#if EV_NUM != 2
- entsize = shtype_map[__libelf_version - 1][elf->class - 1][TYPEIDX (type)].size;
-#else
- entsize = shtype_map[0][elf->class - 1][TYPEIDX (type)].size;
-#endif
+ Elf_Type t = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)];
+ if (t == ELF_T_VDEF || t == ELF_T_NHDR
+ || (t == ELF_T_GNUHASH && elf->class == ELFCLASS64))
+ entsize = 1;
+ else
+ entsize = __libelf_type_sizes[LIBELF_EV_IDX][elf->class - 1][t];
}
/* We assume it is an array of bytes if it is none of the structured
@@ -343,15 +317,7 @@ __libelf_set_rawdata (Elf_Scn *scn)
? ELF_T_WORD : ELF_T_XWORD);
}
else
- {
-#if EV_NUM != 2
- scn->rawdata.d.d_type =
- shtype_map[__libelf_version - 1][elf->class - 1][TYPEIDX (type)].type;
-#else
- scn->rawdata.d.d_type =
- shtype_map[0][elf->class - 1][TYPEIDX (type)].type;
-#endif
- }
+ scn->rawdata.d.d_type = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)];
scn->rawdata.d.d_off = 0;
scn->rawdata.d.d_align = align;
if (elf->class == ELFCLASS32