diff options
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | libdw/ChangeLog | 8 | ||||
-rw-r--r-- | libdw/dwarf_begin_elf.c | 22 | ||||
-rw-r--r-- | libdwfl/ChangeLog | 10 | ||||
-rw-r--r-- | libdwfl/dwfl_module.c | 1 | ||||
-rw-r--r-- | libdwfl/dwfl_module_getdwarf.c | 111 | ||||
-rw-r--r-- | libebl/ChangeLog | 5 | ||||
-rw-r--r-- | libebl/eblcorenote.c | 25 | ||||
-rw-r--r-- | libelf/ChangeLog | 15 | ||||
-rw-r--r-- | libelf/elf_begin.c | 18 | ||||
-rw-r--r-- | libelf/elf_getdata.c | 161 | ||||
-rw-r--r-- | libelf/libelfP.h | 18 |
12 files changed, 221 insertions, 175 deletions
@@ -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. |