]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
propagate from branch 'com.redhat.elfutils.roland.pending' (head b584b7056d679db0fc27...
authorUlrich Drepper <drepper@redhat.com>
Fri, 30 Mar 2007 19:14:59 +0000 (19:14 +0000)
committerUlrich Drepper <drepper@redhat.com>
Fri, 30 Mar 2007 19:14:59 +0000 (19:14 +0000)
            to branch 'com.redhat.elfutils' (head 5f150a0b2f07e8c60913d4e6ad833ef026ccd26e)

12 files changed:
NEWS
libdw/ChangeLog
libdw/dwarf_begin_elf.c
libdwfl/ChangeLog
libdwfl/dwfl_module.c
libdwfl/dwfl_module_getdwarf.c
libebl/ChangeLog
libebl/eblcorenote.c
libelf/ChangeLog
libelf/elf_begin.c
libelf/elf_getdata.c
libelf/libelfP.h

diff --git a/NEWS b/NEWS
index a7a5e32993c44dcea6daf0838770da7dc0811475..af232bcf432717c30507ef265681f90a9b9fcb24 100644 (file)
--- 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:
 
index 76f04bb9f259d6bb98a0f9f642efbb8e529af008..c5a7f8f979ea9c0036c043a92af2cc8376921435 100644 (file)
@@ -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.
index 312164ca86620e90a20cc8beb56ac61f67e1b9aa..e6ead61416b6addb465884927b10c570cd7eee77 100644 (file)
@@ -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);
index 02829e30f2c4e09b3c0746c3bb941efb035eaa77..6f8ff4bcd04f25e2cc127acb1f7a83e8db68f803 100644 (file)
@@ -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 ...
index 08730ec64a1139f358161d5ad0b7656d41517baa..e3bce544c354602870dcd1f3fd1a4ebe73f5d10c 100644 (file)
@@ -103,6 +103,7 @@ __libdwfl_module_free (Dwfl_Module *mod)
   free_file (&mod->main);
 
   free (mod->name);
+  free (mod);
 }
 
 void
index 3a22c3bebf6cbafb0b3c5958db48eceaac8b36a1..c0aeadd17344fe3fe90c7cd0e16efe77988e9531 100644 (file)
@@ -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,
index 07f640edb05d670534c0a86af56e0420d9637c8e..6465e720a3849281f0bd737fe4695f124a6c6979 100644 (file)
@@ -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.
index d8223d7a93bd677b156a658a660e6e41f8e10f6b..9eb355f841ff33e730614216c7bd67cb94e062e1 100644 (file)
@@ -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?  */
index 17985781b57852cb8b2137aa921fdcbeb5f07036..b634054b6ef88aaa008f0437b2b6900f0afb1819 100644 (file)
@@ -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.
index 24bac42b28e334f4ed4fe0a28aadaa60616aace3..b68410be2417a469a0499a9ff12532c9db266a6b 100644 (file)
@@ -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;
index 1fa4a17fce1c5465b36561cb5cf85fd14e9e9e33..0a513edb1ca979084dea557cd4e9325a5fc363d4 100644 (file)
@@ -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.
 
 #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                                                                 \
       ? 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
index 54158aeb8d4bdfaf64ffe552be243514e84e6d42..f06252d71f00edf91500cea9e571396b31fb5988 100644 (file)
@@ -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.