summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--libdw/ChangeLog8
-rw-r--r--libdw/dwarf_begin_elf.c22
-rw-r--r--libdwfl/ChangeLog10
-rw-r--r--libdwfl/dwfl_module.c1
-rw-r--r--libdwfl/dwfl_module_getdwarf.c111
-rw-r--r--libebl/ChangeLog5
-rw-r--r--libebl/eblcorenote.c25
-rw-r--r--libelf/ChangeLog15
-rw-r--r--libelf/elf_begin.c18
-rw-r--r--libelf/elf_getdata.c161
-rw-r--r--libelf/libelfP.h18
12 files changed, 221 insertions, 175 deletions
diff --git a/NEWS b/NEWS
index a7a5e329..af232bcf 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,6 @@
Version 0.127-UNFINISHED:
-libdwfl: new function dwfl_module_addrsym
+libdwfl: new functions dwfl_module_addrsym, dwfl_report_begin_add
Version 0.126:
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 76f04bb9..c5a7f8f9 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,11 @@
+2007-03-25 Roland McGrath <roland@redhat.com>
+
+ * dwarf_begin_elf.c (check_section): Return Dwarf * instead of void.
+ Return NULL when freeing RESULT on error.
+ (global_read, scngrp_read): Check return value from check_section,
+ break out of loop after it has freed RESULT.
+ (valid_p): Handle null argument.
+
2007-03-12 Roland McGrath <roland@redhat.com>
* libdw.map (ELFUTILS_0.127): Add dwfl_report_begin_add.
diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c
index 312164ca..e6ead614 100644
--- a/libdw/dwarf_begin_elf.c
+++ b/libdw/dwarf_begin_elf.c
@@ -1,5 +1,5 @@
/* Create descriptor from ELF descriptor for processing file.
- Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005, 2007 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -84,7 +84,7 @@ static const char dwarf_scnnames[IDX_last][17] =
#define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0]))
-static void
+static Dwarf *
check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp)
{
GElf_Shdr shdr_mem;
@@ -105,7 +105,7 @@ check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp)
a section which isn't part of the section group. */
if (! inscngrp && (shdr->sh_flags & SHF_GROUP) != 0)
/* Ignore the section. */
- return;
+ return result;
/* We recognize the DWARF section by their names. This is not very
@@ -118,7 +118,7 @@ check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp)
invalid. */
__libdw_seterrno (DWARF_E_INVALID_ELF);
free (result);
- return;
+ return NULL;
}
@@ -140,6 +140,8 @@ check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp)
break;
}
+
+ return result;
}
@@ -153,9 +155,11 @@ valid_p (Dwarf *result)
XXX Which sections are absolutely necessary? Add tests if
necessary. For now we require only .debug_info. Hopefully this
is correct. */
- if (unlikely (result->sectiondata[IDX_debug_info] == NULL))
+ if (likely (result != NULL)
+ && unlikely (result->sectiondata[IDX_debug_info] == NULL))
{
__libdw_seterrno (DWARF_E_NO_DWARF);
+ free (result);
result = NULL;
}
@@ -168,8 +172,8 @@ global_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr)
{
Elf_Scn *scn = NULL;
- while ((scn = elf_nextscn (elf, scn)) != NULL)
- check_section (result, ehdr, scn, false);
+ while (result != NULL && (scn = elf_nextscn (elf, scn)) != NULL)
+ result = check_section (result, ehdr, scn, false);
return valid_p (result);
}
@@ -204,7 +208,9 @@ scngrp_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr, Elf_Scn *scngrp)
return NULL;
}
- check_section (result, ehdr, scn, true);
+ result = check_section (result, ehdr, scn, true);
+ if (result == NULL)
+ break;
}
return valid_p (result);
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 02829e30..6f8ff4bc 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,13 @@
+2007-03-26 Roland McGrath <roland@redhat.com>
+
+ * dwfl_module.c (__libdwfl_module_free): Free MOD itself.
+
+2007-03-18 Roland McGrath <roland@redhat.com>
+
+ * dwfl_module_getdwarf.c (find_debuglink): New function, broken out of
+ (find_debuginfo): ... here. Call it.
+ Don't return error for libelf errors finding .gnu_debuglink section.
+
2007-03-12 Roland McGrath <roland@redhat.com>
* dwfl_module.c (dwfl_report_begin_add): New function broken out of ...
diff --git a/libdwfl/dwfl_module.c b/libdwfl/dwfl_module.c
index 08730ec6..e3bce544 100644
--- a/libdwfl/dwfl_module.c
+++ b/libdwfl/dwfl_module.c
@@ -103,6 +103,7 @@ __libdwfl_module_free (Dwfl_Module *mod)
free_file (&mod->main);
free (mod->name);
+ free (mod);
}
void
diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c
index 3a22c3be..c0aeadd1 100644
--- a/libdwfl/dwfl_module_getdwarf.c
+++ b/libdwfl/dwfl_module_getdwarf.c
@@ -115,74 +115,77 @@ find_file (Dwfl_Module *mod)
mod->elferr = open_elf (mod, &mod->main);
}
-/* Find the separate debuginfo file for this module and open libelf on it.
- When we return success, MOD->debug is set up. */
-static Dwfl_Error
-find_debuginfo (Dwfl_Module *mod)
+/* Search an ELF file for a ".gnu_debuglink" section. */
+static const char *
+find_debuglink (Elf *elf, GElf_Word *crc)
{
- if (mod->debug.elf != NULL)
- return DWFL_E_NOERROR;
-
size_t shstrndx;
- if (elf_getshstrndx (mod->main.elf, &shstrndx) < 0)
- return DWFL_E_LIBELF;
+ if (elf_getshstrndx (elf, &shstrndx) < 0)
+ return NULL;
- Elf_Scn *scn = elf_getscn (mod->main.elf, 0);
- if (scn == NULL)
- return DWFL_E_LIBELF;
- do
+ Elf_Scn *scn = NULL;
+ while ((scn = elf_nextscn (elf, scn)) != NULL)
{
- GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem);
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
if (shdr == NULL)
- return DWFL_E_LIBELF;
+ return NULL;
- const char *name = elf_strptr (mod->main.elf, shstrndx, shdr->sh_name);
+ const char *name = elf_strptr (elf, shstrndx, shdr->sh_name);
if (name == NULL)
- return DWFL_E_LIBELF;
+ return NULL;
if (!strcmp (name, ".gnu_debuglink"))
break;
+ }
- scn = elf_nextscn (mod->main.elf, scn);
- } while (scn != NULL);
+ if (scn == NULL)
+ return NULL;
- const char *debuglink_file = NULL;
- GElf_Word debuglink_crc = 0;
- if (scn != NULL)
+ /* Found the .gnu_debuglink section. Extract its contents. */
+ Elf_Data *rawdata = elf_rawdata (scn, NULL);
+ if (rawdata == NULL)
+ return NULL;
+
+ Elf_Data crcdata =
{
- /* Found the .gnu_debuglink section. Extract its contents. */
- Elf_Data *rawdata = elf_rawdata (scn, NULL);
- if (rawdata == NULL)
- return DWFL_E_LIBELF;
+ .d_type = ELF_T_WORD,
+ .d_buf = crc,
+ .d_size = sizeof *crc,
+ .d_version = EV_CURRENT,
+ };
+ Elf_Data conv =
+ {
+ .d_type = ELF_T_WORD,
+ .d_buf = rawdata->d_buf + rawdata->d_size - sizeof *crc,
+ .d_size = sizeof *crc,
+ .d_version = EV_CURRENT,
+ };
+
+ GElf_Ehdr ehdr_mem;
+ GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+ if (ehdr == NULL)
+ return NULL;
- Elf_Data crcdata =
- {
- .d_type = ELF_T_WORD,
- .d_buf = &debuglink_crc,
- .d_size = sizeof debuglink_crc,
- .d_version = EV_CURRENT,
- };
- Elf_Data conv =
- {
- .d_type = ELF_T_WORD,
- .d_buf = rawdata->d_buf + rawdata->d_size - sizeof debuglink_crc,
- .d_size = sizeof debuglink_crc,
- .d_version = EV_CURRENT,
- };
-
- GElf_Ehdr ehdr_mem;
- GElf_Ehdr *ehdr = gelf_getehdr (mod->main.elf, &ehdr_mem);
- if (ehdr == NULL)
- return DWFL_E_LIBELF;
-
- Elf_Data *d = gelf_xlatetom (mod->main.elf, &crcdata, &conv,
- ehdr->e_ident[EI_DATA]);
- if (d == NULL)
- return DWFL_E_LIBELF;
- assert (d == &crcdata);
-
- debuglink_file = rawdata->d_buf;
- }
+ Elf_Data *d = gelf_xlatetom (elf, &crcdata, &conv, ehdr->e_ident[EI_DATA]);
+ if (d == NULL)
+ return NULL;
+ assert (d == &crcdata);
+
+ return rawdata->d_buf;
+}
+
+
+/* Find the separate debuginfo file for this module and open libelf on it.
+ When we return success, MOD->debug is set up. */
+static Dwfl_Error
+find_debuginfo (Dwfl_Module *mod)
+{
+ if (mod->debug.elf != NULL)
+ return DWFL_E_NOERROR;
+
+ GElf_Word debuglink_crc = 0;
+ const char *debuglink_file = find_debuglink (mod->main.elf, &debuglink_crc);
mod->debug.fd = (*mod->dwfl->callbacks->find_debuginfo) (MODCB_ARGS (mod),
mod->main.name,
diff --git a/libebl/ChangeLog b/libebl/ChangeLog
index 07f640ed..6465e720 100644
--- a/libebl/ChangeLog
+++ b/libebl/ChangeLog
@@ -1,3 +1,8 @@
+2007-03-10 Roland McGrath <roland@redhat.com>
+
+ * eblcorenote.c (ebl_core_note): For normally-zero types,
+ print in hex if not zero.
+
2007-01-11 Roland McGrath <roland@redhat.com>
* ebl-hooks.h (machine_section_flag_check): New hook.
diff --git a/libebl/eblcorenote.c b/libebl/eblcorenote.c
index d8223d7a..9eb355f8 100644
--- a/libebl/eblcorenote.c
+++ b/libebl/eblcorenote.c
@@ -1,5 +1,5 @@
/* Print contents of core note.
- Copyright (C) 2002, 2004, 2005 Red Hat, Inc.
+ Copyright (C) 2002, 2004, 2005, 2007 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -173,14 +173,7 @@ ebl_core_note (ebl, name, type, descsz, desc)
switch (atype)
{
- case AT_NULL:
- case AT_IGNORE:
- case AT_IGNOREPPC:
- case AT_NOTELF:
- default:
- printf (" %s\n", at);
- break;
-
+ /* Decimal. */
case AT_EXECFD:
case AT_PHENT:
case AT_PHNUM:
@@ -202,6 +195,20 @@ ebl_core_note (ebl, name, type, descsz, desc)
printf (" %s: %jd\n", at, val);
break;
+ /* Normally zero. */
+ case AT_NULL:
+ case AT_IGNORE:
+ case AT_IGNOREPPC:
+ case AT_NOTELF:
+ default:
+ if (val == 0)
+ {
+ printf (" %s\n", at);
+ break;
+ }
+ /* Fall through. */
+
+ /* Hex. */
case AT_PHDR:
case AT_BASE:
case AT_FLAGS: /* XXX Print flags? */
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 17985781..b634054b 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,18 @@
+2007-03-18 Roland McGrath <roland@redhat.com>
+
+ * elf_begin.c (get_shnum): Fix test for e_shoff being out of bounds.
+ Return zero when the section headers do not fit within MAXSIZE.
+
+2007-03-09 Roland McGrath <roland@redhat.com>
+
+ * libelfP.h (LIBELF_EV_IDX): New macro.
+ (__libelf_type_align): New macro.
+ [! ALLOW_UNALIGNED]: Declare __libc_type_aligns array.
+ * elf_getdata.c (shtype_map): Convert to just Elf_Type[][].
+ (convert_data, __libelf_set_rawdata): Use that, __libelf_type_align,
+ and __libelf_type_sizes, in place of old table.
+ (__libc_type_aligns): New const variable.
+
2007-02-04 Ulrich Drepper <drepper@redhat.com>
* Makefile (libelf.so): Build with -z relro.
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index 24bac42b..b68410be 100644
--- a/libelf/elf_begin.c
+++ b/libelf/elf_begin.c
@@ -155,9 +155,9 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset,
if (unlikely (result == 0) && ehdr.e32->e_shoff != 0)
{
- if (offset + ehdr.e32->e_shoff + sizeof (Elf32_Shdr) > maxsize)
+ if (ehdr.e32->e_shoff + sizeof (Elf32_Shdr) > maxsize)
/* Cannot read the first section header. */
- return (size_t) -1l;
+ return 0;
if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA
&& (ALLOW_UNALIGNED
@@ -190,6 +190,11 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset,
result = size;
}
}
+
+ /* If the section headers were truncated, pretend none were there. */
+ if (ehdr.e32->e_shoff > maxsize
+ || maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr) * result)
+ result = 0;
}
else
{
@@ -198,9 +203,9 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset,
if (unlikely (result == 0) && ehdr.e64->e_shoff != 0)
{
- if (offset + ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize)
+ if (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize)
/* Cannot read the first section header. */
- return (size_t) -1l;
+ return 0;
Elf64_Xword size;
if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA
@@ -236,6 +241,11 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset,
result = size;
}
+
+ /* If the section headers were truncated, pretend none were there. */
+ if (ehdr.e64->e_shoff > maxsize
+ || maxsize - ehdr.e64->e_shoff < sizeof (Elf64_Shdr) * result)
+ result = 0;
}
return result;
diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c
index 1fa4a17f..0a513edb 100644
--- a/libelf/elf_getdata.c
+++ b/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,74 @@
? 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,
+ [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_AUXV] = __alignof__ (ElfW2(Bits,auxv_t)), \
+ }
+ [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 +238,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_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 +316,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
diff --git a/libelf/libelfP.h b/libelf/libelfP.h
index 54158aeb..f06252d7 100644
--- a/libelf/libelfP.h
+++ b/libelf/libelfP.h
@@ -1,5 +1,5 @@
/* Internal interfaces for libelf.
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006 Red Hat, Inc.
+ Copyright (C) 1998,1999,2000,2001,2002,2003,2005,2006,2007 Red Hat, Inc.
This file is part of Red Hat elfutils.
Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
@@ -423,6 +423,22 @@ extern int __libelf_fill_byte attribute_hidden;
/* Nonzero if the version was set. */
extern int __libelf_version_initialized attribute_hidden;
+/* Index for __libelf_type_sizes et al. */
+#if EV_NUM == 2
+# define LIBELF_EV_IDX 0
+#else
+# define LIBELF_EV_IDX (__libelf_version - 1)
+#endif
+
+#if !ALLOW_UNALIGNED
+/* Array with alignment requirements of the internal types indexed by ELF
+ version, binary class, and type. */
+extern const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
+# define __libelf_type_align(class, type) \
+ (__libelf_type_aligns[LIBELF_EV_IDX][class][type] ?: 1)
+#else
+# define __libelf_type_align(class, type) 1
+#endif
/* The libelf API does not have such a function but it is still useful.
Get the memory size for the given type.