]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Handle reading .debug_types section.
authorRoland McGrath <roland@redhat.com>
Wed, 16 Jun 2010 06:10:35 +0000 (23:10 -0700)
committerRoland McGrath <roland@redhat.com>
Wed, 16 Jun 2010 19:11:03 +0000 (12:11 -0700)
25 files changed:
lib/ChangeLog
lib/dynamicsizehash.c
lib/dynamicsizehash.h
libdw/ChangeLog
libdw/Makefile.am
libdw/dwarf_abbrev_hash.c
libdw/dwarf_begin_elf.c
libdw/dwarf_cuoffset.c
libdw/dwarf_diecu.c
libdw/dwarf_end.c
libdw/dwarf_formref_die.c
libdw/dwarf_formstring.c
libdw/dwarf_formudata.c
libdw/dwarf_getaranges.c
libdw/dwarf_getlocation.c
libdw/dwarf_nextcu.c
libdw/dwarf_siblingof.c
libdw/dwarf_sig8_hash.c [new file with mode: 0644]
libdw/dwarf_sig8_hash.h [new file with mode: 0644]
libdw/libdw.h
libdw/libdw.map
libdw/libdwP.h
libdw/libdw_findcu.c
libdwfl/ChangeLog
libdwfl/cu.c

index 089747aa00e12aa5713b913408ad747f84e1f06b..1b8b42bc8ac06e41c131d77d24a8187dcb6be08b 100644 (file)
@@ -1,3 +1,9 @@
+2010-06-16  Roland McGrath  <roland@redhat.com>
+
+       * dynamicsizehash.h (HASHTYPE): New macro.
+       (struct): Use size_t for table sizes.
+       * dynamicsizehash.c: Likewise.  Use HASHTYPE for hash values.
+
 2010-02-15  Roland McGrath  <roland@redhat.com>
 
        * Makefile.am: Use config/eu.am for common stuff.
index b645da6aa6f120d415815092ec62b97a695d337d..24335d426364dec4636e33e3d49230b55dee9fb4 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
+/* Copyright (C) 2000-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
 
@@ -67,7 +67,7 @@
 static size_t
 lookup (htab, hval, val)
      NAME *htab;
-     unsigned long int hval;
+     HASHTYPE hval;
      TYPE val __attribute__ ((unused));
 {
   /* First hash function: simply take the modul but prevent zero.  */
@@ -75,7 +75,7 @@ lookup (htab, hval, val)
 
   if (htab->table[idx].hashval != 0)
     {
-      unsigned long int hash;
+      HASHTYPE hash;
 
       if (htab->table[idx].hashval == hval
          && COMPARE (htab->table[idx].data, val) == 0)
@@ -103,7 +103,7 @@ lookup (htab, hval, val)
 
 
 static void
-insert_entry_2 (NAME *htab, unsigned long int hval, size_t idx, TYPE data)
+insert_entry_2 (NAME *htab, HASHTYPE hval, size_t idx, TYPE data)
 {
 #ifdef ITERATE
   if (htab->table[idx].hashval == 0)
@@ -137,7 +137,7 @@ insert_entry_2 (NAME *htab, unsigned long int hval, size_t idx, TYPE data)
       __typeof__ (htab->first) runp;
 # endif
 #else
-      unsigned long int old_size = htab->size;
+      size_t old_size = htab->size;
 #endif
 #define _TABLE(name) \
       name##_ent *table = htab->table
@@ -198,7 +198,7 @@ int
   name##_init
 INIT(NAME) (htab, init_size)
      NAME *htab;
-     unsigned long int init_size;
+     size_t init_size;
 {
   /* We need the size to be a prime.  */
   init_size = next_prime (init_size);
@@ -235,7 +235,7 @@ int
   name##_insert
 INSERT(NAME) (htab, hval, data)
      NAME *htab;
-     unsigned long int hval;
+     HASHTYPE hval;
      TYPE data;
 {
   size_t idx;
@@ -262,7 +262,7 @@ int
   name##_overwrite
 INSERT(NAME) (htab, hval, data)
      NAME *htab;
-     unsigned long int hval;
+     HASHTYPE hval;
      TYPE data;
 {
   size_t idx;
@@ -285,7 +285,7 @@ TYPE
   name##_find
 FIND(NAME) (htab, hval, val)
      NAME *htab;
-     unsigned long int hval;
+     HASHTYPE hval;
      TYPE val;
 {
   size_t idx;
index 7cbb169d6eb009d8f6a6daa6a8e304ae82780830..f169d5e7471247da385e5bc377990961bb48fde2 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+/* Copyright (C) 2000-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
 
@@ -57,6 +57,7 @@
    The following macros if present select features:
 
    ITERATE   iterating over the table entries is possible
+   HASHTYPE  integer type for hash values, default unsigned long int
  */
 
 
 # define NEXT(name)
 #endif
 
+#ifndef HASHTYPE
+# define HASHTYPE unsigned long int
+#endif
+
 
 /* Defined separately.  */
 extern size_t next_prime (size_t seed);
@@ -78,7 +83,7 @@ extern size_t next_prime (size_t seed);
 #define _DYNHASHENTTYPE(name) \
   typedef struct name##_ent                                                  \
   {                                                                          \
-    unsigned long int hashval;                                               \
+    HASHTYPE hashval;                                                        \
     TYPE data;                                                               \
     NEXT (name)                                                                      \
   } name##_ent
@@ -90,8 +95,8 @@ DYNHASHENTTYPE (NAME);
 #define _DYNHASHTYPE(name) \
 typedef struct                                                               \
 {                                                                            \
-  unsigned long int size;                                                    \
-  unsigned long int filled;                                                  \
+  size_t size;                                                               \
+  size_t filled;                                                             \
   name##_ent *table;                                                         \
   FIRST        (name)                                                                \
 } name
@@ -102,19 +107,19 @@ DYNHASHTYPE (NAME);
 
 #define _FUNCTIONS(name) \
 /* Initialize the hash table.  */                                            \
-extern int name##_init (name *htab, unsigned long int init_size);            \
+extern int name##_init (name *htab, size_t init_size);                       \
                                                                              \
 /* Free resources allocated for hash table.  */                                      \
 extern int name##_free (name *htab);                                         \
                                                                              \
 /* Insert new entry.  */                                                     \
-extern int name##_insert (name *htab, unsigned long int hval, TYPE data);     \
+extern int name##_insert (name *htab, HASHTYPE hval, TYPE data);             \
                                                                              \
 /* Insert new entry, possibly overwrite old entry.  */                       \
-extern int name##_overwrite (name *htab, unsigned long int hval, TYPE data);  \
+extern int name##_overwrite (name *htab, HASHTYPE hval, TYPE data);          \
                                                                              \
 /* Find entry in hash table.  */                                             \
-extern TYPE name##_find (name *htab, unsigned long int hval, TYPE val);
+extern TYPE name##_find (name *htab, HASHTYPE hval, TYPE val);
 #define FUNCTIONS(name) _FUNCTIONS (name)
 FUNCTIONS (NAME)
 
index 7a1078904582390b909bb5eeab46ad3f715819eb..d4d1353898e6f22b55bb165d9f7ed7f215dd1d97 100644 (file)
@@ -1,5 +1,49 @@
 2010-06-16  Roland McGrath  <roland@redhat.com>
 
+       * dwarf_formref_die.c: Use dwarf_offdie only for DW_FORM_ref_addr, so
+       we don't repeat a CU lookup we've already done.  Handle
+       DW_FORM_ref_sig8 using sig8_hash table and __libdw_intern_next_unit.
+
+       * libdw_findcu.c (__libdw_intern_next_unit): New function,
+       broken out of ...
+       (__libdw_findcu): ... here.  Call it.
+       * libdwP.h: Declare it.
+       (struct Dwarf): New member next_tu_offset.
+
+       * dwarf_sig8_hash.c: New file.
+       * dwarf_sig8_hash.h: New file.
+       * Makefile.am (libdw_a_SOURCES, noinst_HEADERS): Add them.
+       * dwarf_abbrev_hash.c: Include dwarf_sig8_hash.h before
+       defining NO_UNDEF.
+       * libdwP.h (struct Dwarf): New member sig8_hash.
+       * dwarf_begin_elf.c: Call Dwarf_Sig8_Hash_init on it.
+       * dwarf_end.c: Call Dwarf_Sig8_Hash_free on it.
+
+       * dwarf_nextcu.c (dwarf_next_unit): New function, broken out of ...
+       (dwarf_nextcu): ... here.  Call it.
+       * libdw.h: Declare it.
+       * libdwP.h: Add INTDECL.
+       * libdw_findcu.c (__libdw_findcu): Use it instead of dwarf_nextcu.
+       * libdw.map (ELFUTILS_0.148): New set, add dwarf_next_unit.
+
+       * libdwP.h (cu_sec_idx, cu_data): New functions.
+       Use .debug_types when CU is a TU.
+       * dwarf_cuoffset.c: Use that instead of assuming IDX_debug_info.
+       * dwarf_siblingof.c: Likewise.
+       * dwarf_formstring.c: Likewise.
+       * dwarf_formudata.c (__libdw_formptr, dwarf_formudata): Likewise.
+       * dwarf_getlocation.c (dwarf_getlocation): Likewise.
+       (dwarf_getlocation_addr): Likewise.
+
+       * libdwP.h (struct Dwarf_CU): Add new members type_offset, type_sig8.
+       (DIE_OFFSET_FROM_CU_OFFSET): Take flag argument; if true, compute
+       .debug_types header size instead of .debug_info header size.
+       (CUDIE): Use it.
+       * dwarf_diecu.c: Update caller.
+       * dwarf_getaranges.c: Likewise.
+       * dwarf_nextcu.c: Likewise.
+       * libdw_findcu.c (__libdw_findcu): Initialize new members.
+
        * fde.c (fde_by_offset): Renamed to ...
        (__libdw_fde_by_offset): ... this, made global and internal_function.
        Don't take ADDRESS argument.
index 4bd0f2a8d117e6070126630fcbf6de11f7e6fdbc..b1f2ec146a66fa07e0f12e05c78c98ce0bf2cbef 100644 (file)
@@ -44,7 +44,8 @@ pkginclude_HEADERS = libdw.h
 libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \
                  dwarf_getpubnames.c dwarf_getabbrev.c dwarf_tag.c \
                  dwarf_error.c dwarf_nextcu.c dwarf_diename.c dwarf_offdie.c \
-                 dwarf_attr.c dwarf_formstring.c dwarf_abbrev_hash.c \
+                 dwarf_attr.c dwarf_formstring.c \
+                 dwarf_abbrev_hash.c dwarf_sig8_hash.c \
                  dwarf_attr_integrate.c dwarf_hasattr_integrate.c \
                  dwarf_child.c dwarf_haschildren.c dwarf_formaddr.c \
                  dwarf_formudata.c dwarf_formsdata.c dwarf_lowpc.c \
@@ -125,7 +126,7 @@ endif
 libdw_a_LIBADD = $(addprefix ../libdwfl/,$(shell $(AR) t ../libdwfl/libdwfl.a))
 
 noinst_HEADERS = libdwP.h memory-access.h dwarf_abbrev_hash.h \
-                cfi.h encoded-value.h
+                dwarf_sig8_hash.h cfi.h encoded-value.h
 
 EXTRA_DIST = libdw.map
 
index 5c5d6cb1e9b7ec19dd4056fba3b4a9970e0531e5..bec1ceb2118c6b6a4d126ba5e4022779f2b14809 100644 (file)
@@ -1,5 +1,5 @@
 /* Implementation of hash table for DWARF .debug_abbrev section content.
-   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+   Copyright (C) 2000-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
 
@@ -52,6 +52,7 @@
 # include <config.h>
 #endif
 
+#include "dwarf_sig8_hash.h"
 #define NO_UNDEF
 #include "libdwP.h"
 
index c3a49654e75441a2e131c6fd4cb6ae60e8bf6af9..b5fb7c91f58ff7cf78241bb7b7f36fc5fe306727 100644 (file)
@@ -246,8 +246,10 @@ dwarf_begin_elf (elf, cmd, scngrp)
 
   /* Allocate the data structure.  */
   Dwarf *result = (Dwarf *) calloc (1, sizeof (Dwarf) + mem_default_size);
-  if (result == NULL)
+  if (unlikely (result == NULL)
+      || unlikely (Dwarf_Sig8_Hash_init (&result->sig8_hash, 11) < 0))
     {
+      free (result);
       __libdw_seterrno (DWARF_E_NOMEM);
       return NULL;
     }
@@ -268,7 +270,6 @@ dwarf_begin_elf (elf, cmd, scngrp)
   result->mem_tail->remaining = result->mem_tail->size;
   result->mem_tail->prev = NULL;
 
-
   if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR)
     {
       /* If the caller provides a section group we get the DWARF
index 10238b430d39bde018dc010e04dda1824b5410fd..47653200cd3eed8ad877b3d4aeb62ccde35f8716 100644 (file)
@@ -1,5 +1,5 @@
 /* Return offset of DIE in CU.
-   Copyright (C) 2003 Red Hat, Inc.
+   Copyright (C) 2003-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -62,7 +62,5 @@ dwarf_cuoffset (die)
 {
   return (die == NULL
          ? (Dwarf_Off) -1l
-         : (die->addr
-            - die->cu->dbg->sectiondata[IDX_debug_info]->d_buf
-            - die->cu->start));
+         : (die->addr - cu_data (die->cu)->d_buf - die->cu->start));
 }
index a62b82229c4060b7b66861d9926b6e8ea73e76d9..e3e5252121bd531028c586902076d88a35a2ac03 100644 (file)
@@ -1,5 +1,5 @@
 /* Return CU DIE containing given DIE.
-   Copyright (C) 2005, 2008 Red Hat, Inc.
+   Copyright (C) 2005-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -71,7 +71,8 @@ dwarf_diecu (die, result, address_sizep, offset_sizep)
 
   result->addr = ((char *) die->cu->dbg->sectiondata[IDX_debug_info]->d_buf
                  + DIE_OFFSET_FROM_CU_OFFSET (die->cu->start,
-                                              die->cu->offset_size));
+                                              die->cu->offset_size,
+                                              die->cu->type_offset != 0));
   result->cu = die->cu;
 
   if (address_sizep != NULL)
index fda37fc1bb8b60039fd84b581435d2b73eed8fd6..80dac7b7952ca39a2a7ac305c0a09ec0fce09851 100644 (file)
@@ -1,5 +1,5 @@
 /* Release debugging handling context.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2009 Red Hat, Inc.
+   Copyright (C) 2002-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -86,6 +86,8 @@ dwarf_end (dwarf)
        /* Clean up the CFI cache.  */
        __libdw_destroy_frame_cache (dwarf->cfi);
 
+      Dwarf_Sig8_Hash_free (&dwarf->sig8_hash);
+
       /* The search tree for the CUs.  NB: the CU data itself is
         allocated separately, but the abbreviation hash tables need
         to be handled.  */
index 3ab2cb384a0736b1cf35e0154c9bd13623c1fed7..a684317ceb193ce59722e55ae4775cd9dc2830ab 100644 (file)
 # include <config.h>
 #endif
 
+#include <string.h>
 #include "libdwP.h"
 #include <dwarf.h>
 
 
 Dwarf_Die *
-dwarf_formref_die (attr, die_mem)
+dwarf_formref_die (attr, result)
      Dwarf_Attribute *attr;
-     Dwarf_Die *die_mem;
+     Dwarf_Die *result;
 {
   if (attr == NULL)
     return NULL;
 
+  struct Dwarf_CU *cu = attr->cu;
+
   Dwarf_Off offset;
   if (attr->form == DW_FORM_ref_addr)
     {
       /* This has an absolute offset.  */
 
-      uint8_t ref_size = (attr->cu->version == 2
-                         ? attr->cu->address_size
-                         : attr->cu->offset_size);
+      uint8_t ref_size = (cu->version == 2
+                         ? cu->address_size
+                         : cu->offset_size);
 
-      if (__libdw_read_offset (attr->cu->dbg, IDX_debug_info, attr->valp,
+      if (__libdw_read_offset (cu->dbg, IDX_debug_info, attr->valp,
                               ref_size, &offset, IDX_debug_info, 0))
        return NULL;
+
+      return INTUSE(dwarf_offdie) (cu->dbg, offset, result);
     }
-  else if (attr->form == DW_FORM_ref_sig8)
+
+  Elf_Data *data;
+  if (attr->form == DW_FORM_ref_sig8)
     {
       /* This doesn't have an offset, but instead a value we
         have to match in the .debug_types type unit headers.  */
 
-      uint64_t sig = read_8ubyte_unaligned (attr->cu->dbg, attr->valp);
+      uint64_t sig = read_8ubyte_unaligned (cu->dbg, attr->valp);
+      cu = Dwarf_Sig8_Hash_find (&cu->dbg->sig8_hash, sig, NULL);
+      if (cu == NULL)
+       /* Not seen before.  We have to scan through the type units.  */
+       do
+         {
+           cu = __libdw_intern_next_unit (attr->cu->dbg, true);
+           if (cu == NULL)
+             {
+               __libdw_seterrno (INTUSE(dwarf_errno) ()
+                                 ?: DWARF_E_INVALID_REFERENCE);
+               return NULL;
+             }
+           Dwarf_Sig8_Hash_insert (&cu->dbg->sig8_hash, sig, cu);
+         }
+       while (cu->type_sig8 != sig);
 
-      /* XXX We don't actually support this yet.  We need to parse
-        .debug_types and keep a table keyed on signature.  */
-#if 0
-      return INTUSE(dwarf_typeunit) (attr->cu->dbg, sig, die_mem);
-#else
-      sig = sig;
-      __libdw_seterrno (DWARF_E_INVALID_REFERENCE);
-#endif
-      return NULL;
+      data = cu->dbg->sectiondata[IDX_debug_types];
+      offset = cu->type_offset;
     }
   else
     {
       /* Other forms produce an offset from the CU.  */
       if (unlikely (__libdw_formref (attr, &offset) != 0))
        return NULL;
-      offset += attr->cu->start;
+
+      data = cu->dbg->sectiondata[IDX_debug_info];
+    }
+
+  if (unlikely (data->d_size - cu->start <= offset))
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return NULL;
     }
 
-  return INTUSE(dwarf_offdie) (attr->cu->dbg, offset, die_mem);
+  memset (result, '\0', sizeof (Dwarf_Die));
+  result->addr = (char *) data->d_buf + cu->start + offset;
+  result->cu = cu;
+  return result;
 }
 INTDEF (dwarf_formref_die)
index f95d31b827fe8262c8222c279ab27b8048fd2cb0..1dee9b2d0ccde53205cd7193952cbdffec781f70 100644 (file)
@@ -1,5 +1,5 @@
 /* Return string associated with given attribute.
-   Copyright (C) 2003, 2004, 2005 Red Hat, Inc.
+   Copyright (C) 2003-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -79,7 +79,7 @@ dwarf_formstring (attrp)
     }
 
   uint64_t off;
-  if (__libdw_read_offset (dbg, IDX_debug_info, attrp->valp,
+  if (__libdw_read_offset (dbg, cu_sec_idx (attrp->cu), attrp->valp,
                           attrp->cu->offset_size, &off, IDX_debug_str, 1))
     return NULL;
 
index 63c9bcd7b3eee68c9b5b900322eabc230375dcf1..573a5783a9c5362061e74e6281e1c5162129d567 100644 (file)
@@ -73,7 +73,7 @@ __libdw_formptr (Dwarf_Attribute *attr, int sec_index,
   Dwarf_Word offset;
   if (attr->form == DW_FORM_sec_offset)
     {
-      if (__libdw_read_offset (attr->cu->dbg, IDX_debug_info, attr->valp,
+      if (__libdw_read_offset (attr->cu->dbg, cu_sec_idx (attr->cu), attr->valp,
                               attr->cu->offset_size, &offset, sec_index, 0))
        return NULL;
     }
@@ -84,7 +84,8 @@ __libdw_formptr (Dwarf_Attribute *attr, int sec_index,
       {
       case DW_FORM_data4:
       case DW_FORM_data8:
-       if (__libdw_read_offset (attr->cu->dbg, IDX_debug_info, attr->valp,
+       if (__libdw_read_offset (attr->cu->dbg, cu_sec_idx (attr->cu),
+                                attr->valp,
                                 attr->form == DW_FORM_data4 ? 4 : 8,
                                 &offset, sec_index, 0))
          return NULL;
@@ -133,7 +134,8 @@ dwarf_formudata (attr, return_uval)
 
     case DW_FORM_data4:
     case DW_FORM_data8:
-      if (__libdw_read_address (attr->cu->dbg, IDX_debug_info, attr->valp,
+      if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu),
+                               attr->valp,
                                attr->form == DW_FORM_data4 ? 4 : 8,
                                return_uval))
        return -1;
index 72334f5f618ea893b5fb690e29ae7a81da2973f5..cced9bf8dfef8385219123e3f02e815abd543a59 100644 (file)
@@ -1,5 +1,5 @@
 /* Return list address ranges.
-   Copyright (C) 2000-2009 Red Hat, Inc.
+   Copyright (C) 2000-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
 
@@ -199,7 +199,8 @@ dwarf_getaranges (dbg, aranges, naranges)
          else
            offset_size = 4;
          new_arange->arange.offset = DIE_OFFSET_FROM_CU_OFFSET (offset,
-                                                                offset_size);
+                                                                offset_size,
+                                                                false);
 
          /* Sanity-check the data.  */
          if (new_arange->arange.offset
index c89488b305b91f977eb3db0b417a46ec19c7d8df..56091cd9cd5c0eb31579fa3473196689aa720af2 100644 (file)
@@ -553,7 +553,7 @@ dwarf_getlocation (attr, llbuf, listlen)
   if (INTUSE(dwarf_formblock) (attr, &block) != 0)
     return -1;
 
-  return getlocation (attr->cu, &block, llbuf, listlen, IDX_debug_info);
+  return getlocation (attr->cu, &block, llbuf, listlen, cu_sec_idx (attr->cu));
 }
 
 int
@@ -578,7 +578,7 @@ dwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs)
        return 0;
       if (llbufs != NULL &&
          getlocation (attr->cu, &block, &llbufs[0], &listlens[0],
-                      IDX_debug_info) != 0)
+                      cu_sec_idx (attr->cu)) != 0)
        return -1;
       return listlens[0] == 0 ? 0 : 1;
     }
index e436e11584ac3cbfaae650f52586f73895c3bbc6..288ee95e25c9f775029f875d67110334523198df 100644 (file)
@@ -1,5 +1,5 @@
 /* Advance to next CU header.
-   Copyright (C) 2002-2009 Red Hat, Inc.
+   Copyright (C) 2002-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2002.
 
 
 
 int
-dwarf_nextcu (dwarf, off, next_off, header_sizep, abbrev_offsetp,
-             address_sizep, offset_sizep)
+dwarf_next_unit (dwarf, off, next_off, header_sizep, versionp, abbrev_offsetp,
+                address_sizep, offset_sizep, type_signaturep, type_offsetp)
      Dwarf *dwarf;
      Dwarf_Off off;
      Dwarf_Off *next_off;
      size_t *header_sizep;
+     uint16_t *versionp;
      Dwarf_Off *abbrev_offsetp;
      uint8_t *address_sizep;
      uint8_t *offset_sizep;
+     uint64_t *type_signaturep;
+     Dwarf_Off *type_offsetp;
 {
+  const bool debug_types = type_signaturep != NULL;
+  const size_t sec_idx = debug_types ? IDX_debug_types : IDX_debug_info;
+
   /* Maybe there has been an error before.  */
   if (dwarf == NULL)
     return -1;
 
   /* If we reached the end before don't do anything.  */
   if (off == (Dwarf_Off) -1l
+      || unlikely (dwarf->sectiondata[sec_idx] == NULL)
       /* Make sure there is enough space in the .debug_info section
         for at least the initial word.  We cannot test the rest since
         we don't know yet whether this is a 64-bit object or not.  */
-      || unlikely (off + 4 >= dwarf->sectiondata[IDX_debug_info]->d_size))
+      || unlikely (off + 4 >= dwarf->sectiondata[sec_idx]->d_size))
     {
       *next_off = (Dwarf_Off) -1l;
       return 1;
@@ -84,7 +91,7 @@ dwarf_nextcu (dwarf, off, next_off, header_sizep, abbrev_offsetp,
 
   /* This points into the .debug_info section to the beginning of the
      CU entry.  */
-  const unsigned char *data = dwarf->sectiondata[IDX_debug_info]->d_buf;
+  const unsigned char *data = dwarf->sectiondata[sec_idx]->d_buf;
   const unsigned char *bytes = data + off;
 
   /* The format of the CU header is described in dwarf2p1 7.5.1:
@@ -122,13 +129,14 @@ dwarf_nextcu (dwarf, off, next_off, header_sizep, abbrev_offsetp,
   else if (unlikely (length >= DWARF3_LENGTH_MIN_ESCAPE_CODE
                     && length <= DWARF3_LENGTH_MAX_ESCAPE_CODE))
     {
+    invalid:
       __libdw_seterrno (DWARF_E_INVALID_DWARF);
       return -1;
     }
 
   /* Now we know how large the header is.  */
-  if (unlikely (DIE_OFFSET_FROM_CU_OFFSET (off, offset_size)
-               >= dwarf->sectiondata[IDX_debug_info]->d_size))
+  if (unlikely (DIE_OFFSET_FROM_CU_OFFSET (off, offset_size, debug_types)
+               >= dwarf->sectiondata[sec_idx]->d_size))
     {
       *next_off = -1;
       return 1;
@@ -138,22 +146,47 @@ dwarf_nextcu (dwarf, off, next_off, header_sizep, abbrev_offsetp,
     /* This is a 64-bit DWARF format.  */
     length = read_8ubyte_unaligned_inc (dwarf, bytes);
 
-  /* Read the version stamp.  Always a 16-bit value.
-     XXX Do we need the value?  */
-  read_2ubyte_unaligned_inc (dwarf, bytes);
+  /* Read the version stamp.  Always a 16-bit value.  */
+  uint_fast16_t version = read_2ubyte_unaligned_inc (dwarf, bytes);
 
   /* Get offset in .debug_abbrev.  Note that the size of the entry
      depends on whether this is a 32-bit or 64-bit DWARF definition.  */
   uint64_t abbrev_offset;
-  if (__libdw_read_offset_inc (dwarf, IDX_debug_info, &bytes, offset_size,
+  if (__libdw_read_offset_inc (dwarf, sec_idx, &bytes, offset_size,
                               &abbrev_offset, IDX_debug_abbrev, 0))
     return -1;
 
+  /* The address size.  Always an 8-bit value.  */
+  uint8_t address_size = *bytes++;
+
+  if (debug_types)
+    {
+      uint64_t type_sig8 = read_8ubyte_unaligned_inc (dwarf, bytes);
+
+      Dwarf_Off type_offset;
+      if (__libdw_read_offset_inc (dwarf, sec_idx, &bytes, offset_size,
+                                  &type_offset, sec_idx, 0))
+       return -1;
+
+      /* Validate that the TYPE_OFFSET points past the header.  */
+      if (unlikely (type_offset < (size_t) (bytes - (data + off))))
+       goto invalid;
+
+      *type_signaturep = type_sig8;
+      if (type_offsetp != NULL)
+       *type_offsetp = type_offset;
+    }
+
+  /* Store the header length.  */
+  if (header_sizep != NULL)
+    *header_sizep = bytes - (data + off);
+
+  if (versionp != NULL)
+    *versionp = version;
+
   if (abbrev_offsetp != NULL)
     *abbrev_offsetp = abbrev_offset;
 
-  /* The address size.  Always an 8-bit value.  */
-  uint8_t address_size = *bytes++;
   if (address_sizep != NULL)
     *address_sizep = address_size;
 
@@ -161,14 +194,27 @@ dwarf_nextcu (dwarf, off, next_off, header_sizep, abbrev_offsetp,
   if (offset_sizep != NULL)
     *offset_sizep = offset_size;
 
-  /* Store the header length.  */
-  if (header_sizep != NULL)
-    *header_sizep = bytes - (data + off);
-
   /* See definition of DIE_OFFSET_FROM_CU_OFFSET macro
      for an explanation of the trick in this expression.  */
   *next_off = off + 2 * offset_size - 4 + length;
 
   return 0;
 }
+INTDEF(dwarf_next_unit)
+
+int
+dwarf_nextcu (dwarf, off, next_off, header_sizep, abbrev_offsetp,
+             address_sizep, offset_sizep)
+     Dwarf *dwarf;
+     Dwarf_Off off;
+     Dwarf_Off *next_off;
+     size_t *header_sizep;
+     Dwarf_Off *abbrev_offsetp;
+     uint8_t *address_sizep;
+     uint8_t *offset_sizep;
+{
+  return INTUSE(dwarf_next_unit) (dwarf, off, next_off, header_sizep, NULL,
+                                 abbrev_offsetp, address_sizep, offset_sizep,
+                                 NULL, NULL);
+}
 INTDEF(dwarf_nextcu)
index 0d42717514cab8851a7c9216a2b661d82ccc73ce..f8e54c18ab0bcd5ca1ed3e56e15c5d9bb56fe37a 100644 (file)
@@ -1,5 +1,5 @@
 /* Return sibling of given DIE.
-   Copyright (C) 2003, 2004, 2005, 2007, 2008 Red Hat, Inc.
+   Copyright (C) 2003-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -84,8 +84,7 @@ dwarf_siblingof (die, result)
   unsigned char *addr = this_die.addr;
   /* End of the buffer.  */
   unsigned char *endp
-    = ((unsigned char *) sibattr.cu->dbg->sectiondata[IDX_debug_info]->d_buf
-       + sibattr.cu->end);
+    = ((unsigned char *) cu_data (sibattr.cu)->d_buf + sibattr.cu->end);
 
   /* Search for the beginning of the next die on this level.  We
      must not return the dies for children of the given die.  */
@@ -103,8 +102,7 @@ dwarf_siblingof (die, result)
            return -1;
 
          /* Compute the next address.  */
-         addr = ((unsigned char *)
-                 sibattr.cu->dbg->sectiondata[IDX_debug_info]->d_buf
+         addr = ((unsigned char *) cu_data (sibattr.cu)->d_buf
                  + sibattr.cu->start + offset);
        }
       else if (unlikely (addr == NULL)
diff --git a/libdw/dwarf_sig8_hash.c b/libdw/dwarf_sig8_hash.c
new file mode 100644 (file)
index 0000000..53c07ea
--- /dev/null
@@ -0,0 +1,62 @@
+/* Implementation of hash table for DWARF .debug_types section content.
+   Copyright (C) 2010 Red Hat, Inc.
+   This file is part of Red Hat elfutils.
+
+   Red Hat elfutils is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by the
+   Free Software Foundation; version 2 of the License.
+
+   Red Hat elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with Red Hat elfutils; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+   In addition, as a special exception, Red Hat, Inc. gives You the
+   additional right to link the code of Red Hat elfutils with code licensed
+   under any Open Source Initiative certified open source license
+   (http://www.opensource.org/licenses/index.php) which requires the
+   distribution of source code with any binary distribution and to
+   distribute linked combinations of the two.  Non-GPL Code permitted under
+   this exception must only link to the code of Red Hat elfutils through
+   those well defined interfaces identified in the file named EXCEPTION
+   found in the source code files (the "Approved Interfaces").  The files
+   of Non-GPL Code may instantiate templates or use macros or inline
+   functions from the Approved Interfaces without causing the resulting
+   work to be covered by the GNU General Public License.  Only Red Hat,
+   Inc. may make changes or additions to the list of Approved Interfaces.
+   Red Hat's grant of this exception is conditioned upon your not adding
+   any new exceptions.  If you wish to add a new Approved Interface or
+   exception, please contact Red Hat.  You must obey the GNU General Public
+   License in all respects for all of the Red Hat elfutils code and other
+   code used in conjunction with Red Hat elfutils except the Non-GPL Code
+   covered by this exception.  If you modify this file, you may extend this
+   exception to your version of the file, but you are not obligated to do
+   so.  If you do not wish to provide this exception without modification,
+   you must delete this exception statement from your version and license
+   this file solely under the GPL without exception.
+
+   Red Hat elfutils is an included package of the Open Invention Network.
+   An included package of the Open Invention Network is a package for which
+   Open Invention Network licensees cross-license their patents.  No patent
+   license is granted, either expressly or impliedly, by designation as an
+   included package.  Should you wish to participate in the Open Invention
+   Network licensing program, please visit www.openinventionnetwork.com
+   <http://www.openinventionnetwork.com>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define NO_UNDEF
+#include "dwarf_sig8_hash.h"
+#undef NO_UNDEF
+
+/* This is defined in dwarf_abbrev_hash.c, we can just use it here.  */
+#define next_prime __libdwarf_next_prime
+extern size_t next_prime (size_t) attribute_hidden;
+
+#include <dynamicsizehash.c>
diff --git a/libdw/dwarf_sig8_hash.h b/libdw/dwarf_sig8_hash.h
new file mode 100644 (file)
index 0000000..0d8932b
--- /dev/null
@@ -0,0 +1,59 @@
+/* Hash table for DWARF .debug_types section content.
+   Copyright (C) 2010 Red Hat, Inc.
+   This file is part of Red Hat elfutils.
+
+   Red Hat elfutils is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by the
+   Free Software Foundation; version 2 of the License.
+
+   Red Hat elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with Red Hat elfutils; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+   In addition, as a special exception, Red Hat, Inc. gives You the
+   additional right to link the code of Red Hat elfutils with code licensed
+   under any Open Source Initiative certified open source license
+   (http://www.opensource.org/licenses/index.php) which requires the
+   distribution of source code with any binary distribution and to
+   distribute linked combinations of the two.  Non-GPL Code permitted under
+   this exception must only link to the code of Red Hat elfutils through
+   those well defined interfaces identified in the file named EXCEPTION
+   found in the source code files (the "Approved Interfaces").  The files
+   of Non-GPL Code may instantiate templates or use macros or inline
+   functions from the Approved Interfaces without causing the resulting
+   work to be covered by the GNU General Public License.  Only Red Hat,
+   Inc. may make changes or additions to the list of Approved Interfaces.
+   Red Hat's grant of this exception is conditioned upon your not adding
+   any new exceptions.  If you wish to add a new Approved Interface or
+   exception, please contact Red Hat.  You must obey the GNU General Public
+   License in all respects for all of the Red Hat elfutils code and other
+   code used in conjunction with Red Hat elfutils except the Non-GPL Code
+   covered by this exception.  If you modify this file, you may extend this
+   exception to your version of the file, but you are not obligated to do
+   so.  If you do not wish to provide this exception without modification,
+   you must delete this exception statement from your version and license
+   this file solely under the GPL without exception.
+
+   Red Hat elfutils is an included package of the Open Invention Network.
+   An included package of the Open Invention Network is a package for which
+   Open Invention Network licensees cross-license their patents.  No patent
+   license is granted, either expressly or impliedly, by designation as an
+   included package.  Should you wish to participate in the Open Invention
+   Network licensing program, please visit www.openinventionnetwork.com
+   <http://www.openinventionnetwork.com>.  */
+
+#ifndef _DWARF_SIG8_HASH_H
+#define _DWARF_SIG8_HASH_H     1
+
+#define NAME Dwarf_Sig8_Hash
+#define TYPE struct Dwarf_CU *
+#define COMPARE(a, b) (0)
+
+#include <dynamicsizehash.h>
+
+#endif /* dwarf_sig8_hash.h */
index 75998e1a037992dd5c041d6a6cff9ae9b49b43b5..bd764a3a23505cfd78ef19c9ee8f08ce96f57537 100644 (file)
@@ -288,12 +288,22 @@ extern int dwarf_end (Dwarf *dwarf);
 /* Get the data block for the .debug_info section.  */
 extern Elf_Data *dwarf_getscn_info (Dwarf *dwarf);
 
-/* Read the header for the DWARF CU header.  */
+/* Read the header for the DWARF CU.  */
 extern int dwarf_nextcu (Dwarf *dwarf, Dwarf_Off off, Dwarf_Off *next_off,
                         size_t *header_sizep, Dwarf_Off *abbrev_offsetp,
                         uint8_t *address_sizep, uint8_t *offset_sizep)
      __nonnull_attribute__ (3);
 
+/* Read the header of a DWARF CU or type unit.  If TYPE_SIGNATUREP is not
+   null, this reads a type unit from the .debug_types section; otherwise
+   this reads a CU from the .debug_info section.  */
+extern int dwarf_next_unit (Dwarf *dwarf, Dwarf_Off off, Dwarf_Off *next_off,
+                           size_t *header_sizep, uint16_t *versionp,
+                           Dwarf_Off *abbrev_offsetp,
+                           uint8_t *address_sizep, uint8_t *offset_sizep,
+                           uint64_t *type_signaturep, Dwarf_Off *type_offsetp)
+     __nonnull_attribute__ (3);
+
 
 /* Decode one DWARF CFI entry (CIE or FDE) from the raw section data.
    The E_IDENT from the originating ELF file indicates the address
index 89897acdc1ebc56c0880d85b31a3bdd0e2400f3f..9b60824aa912ceb12cebb6eb6c139381c8749e35 100644 (file)
@@ -241,4 +241,5 @@ ELFUTILS_0.146 {
 ELFUTILS_0.148 {
   global:
     dwarf_cfi_validate_fde;
+    dwarf_next_unit;
 } ELFUTILS_0.146;
index bfa8a4265307d7772c2230640f20fc502af2b686..ea74a5ae0796109331e67296a19351d31d07c0ce 100644 (file)
@@ -139,6 +139,8 @@ enum
 };
 
 
+#include "dwarf_sig8_hash.h"
+
 /* This is the structure representing the debugging state.  */
 struct Dwarf
 {
@@ -169,6 +171,10 @@ struct Dwarf
   void *cu_tree;
   Dwarf_Off next_cu_offset;
 
+  /* Hash table for .debug_types type units.  */
+  Dwarf_Sig8_Hash sig8_hash;
+  Dwarf_Off next_tu_offset;
+
   /* Address ranges.  */
   Dwarf_Aranges *aranges;
 
@@ -273,6 +279,10 @@ struct Dwarf_CU
   uint8_t offset_size;
   uint16_t version;
 
+  /* Zero if this is a normal CU.  Nonzero if it is a type unit.  */
+  size_t type_offset;
+  uint64_t type_sig8;
+
   /* Hash table for the abbreviations.  */
   Dwarf_Abbrev_Hash abbrev_hash;
   /* Offset of the first abbreviation.  */
@@ -295,21 +305,27 @@ struct Dwarf_CU
         LEN       VER     OFFSET    ADDR
       4-bytes + 2-bytes + 4-bytes + 1-byte  for 32-bit dwarf
      12-bytes + 2-bytes + 8-bytes + 1-byte  for 64-bit dwarf
+   or in .debug_types,                              SIGNATURE TYPE-OFFSET
+      4-bytes + 2-bytes + 4-bytes + 1-byte + 8-bytes + 4-bytes  for 32-bit
+     12-bytes + 2-bytes + 8-bytes + 1-byte + 8-bytes + 8-bytes  for 64-bit
 
    Note the trick in the computation.  If the offset_size is 4
    the '- 4' term changes the '3 *' into a '2 *'.  If the
    offset_size is 8 it accounts for the 4-byte escape value
    used at the start of the length.  */
-#define DIE_OFFSET_FROM_CU_OFFSET(cu_offset, offset_size) \
-  ((cu_offset) + 3 * (offset_size) - 4 + 3)
+#define DIE_OFFSET_FROM_CU_OFFSET(cu_offset, offset_size, type_unit)   \
+  ((type_unit) ? ((cu_offset) + 4 * (offset_size) - 4 + 3 + 8)         \
+   : ((cu_offset) + 3 * (offset_size) - 4 + 3))
 
-#define CUDIE(fromcu) \
+#define CUDIE(fromcu)                                                        \
   ((Dwarf_Die)                                                               \
    {                                                                         \
      .cu = (fromcu),                                                         \
      .addr = ((char *) (fromcu)->dbg->sectiondata[IDX_debug_info]->d_buf      \
-             + (fromcu)->start + 3 * (fromcu)->offset_size - 4 + 3),         \
-   })
+             + DIE_OFFSET_FROM_CU_OFFSET ((fromcu)->start,                   \
+                                          (fromcu)->offset_size,             \
+                                          (fromcu)->type_offset != 0))       \
+   })                                                                        \
 
 
 /* Macro information.  */
@@ -362,6 +378,10 @@ extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align)
 /* Default OOM handler.  */
 extern void __libdw_oom (void) __attribute ((noreturn, visibility ("hidden")));
 
+/* Allocate the internal data for a unit not seen before.  */
+extern struct Dwarf_CU *__libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
+     __nonnull_attribute__ (1) internal_function;
+
 /* Find CU for given offset.  */
 extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset)
      __nonnull_attribute__ (1) internal_function;
@@ -567,6 +587,18 @@ __libdw_read_offset (Dwarf *dbg,
   return __libdw_offset_in_section (dbg, sec_ret, *ret, size);
 }
 
+static inline size_t
+cu_sec_idx (struct Dwarf_CU *cu)
+{
+  return cu->type_offset == 0 ? IDX_debug_info : IDX_debug_types;
+}
+
+static inline Elf_Data *
+cu_data (struct Dwarf_CU *cu)
+{
+  return cu->dbg->sectiondata[cu_sec_idx (cu)];
+}
+
 /* Read up begin/end pair and increment read pointer.
     - If it's normal range record, set up *BEGINP and *ENDP and return 0.
     - If it's base address selection record, set up *BASEP and return 1.
@@ -613,6 +645,7 @@ INTDECL (dwarf_haspc)
 INTDECL (dwarf_highpc)
 INTDECL (dwarf_lowpc)
 INTDECL (dwarf_nextcu)
+INTDECL (dwarf_next_unit)
 INTDECL (dwarf_offdie)
 INTDECL (dwarf_ranges)
 INTDECL (dwarf_siblingof)
index cf79c639a6dc644337d6a0617ea671cfd146f373..7e0b35685ed71e5b401bcf0c354f7cf9b5341a0d 100644 (file)
 #include "libdwP.h"
 
 
+struct Dwarf_CU *
+internal_function
+__libdw_intern_next_unit (dbg, debug_types)
+     Dwarf *dbg;
+     bool debug_types;
+{
+  Dwarf_Off *const offsetp
+    = debug_types ? &dbg->next_tu_offset : &dbg->next_cu_offset;
+
+  Dwarf_Off oldoff = *offsetp;
+  uint16_t version;
+  uint8_t address_size;
+  uint8_t offset_size;
+  Dwarf_Off abbrev_offset;
+  uint64_t type_sig8 = 0;
+  Dwarf_Off type_offset = 0;
+
+  if (INTUSE(dwarf_next_unit) (dbg, oldoff, offsetp, NULL,
+                              &version, &abbrev_offset,
+                              &address_size, &offset_size,
+                              debug_types ? &type_sig8 : NULL,
+                              debug_types ? &type_offset : NULL) != 0)
+    /* No more entries.  */
+    return NULL;
+
+  /* We only know how to handle the DWARF version 2 through 4 formats.  */
+  if (unlikely (version < 2) || unlikely (version > 4))
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return NULL;
+    }
+
+  /* Create an entry for this CU.  */
+  struct Dwarf_CU *newp = libdw_typed_alloc (dbg, struct Dwarf_CU);
+
+  newp->dbg = dbg;
+  newp->start = oldoff;
+  newp->end = *offsetp;
+  newp->address_size = address_size;
+  newp->offset_size = offset_size;
+  newp->version = version;
+  newp->type_sig8 = type_sig8;
+  newp->type_offset = type_offset;
+  Dwarf_Abbrev_Hash_init (&newp->abbrev_hash, 41);
+  newp->orig_abbrev_offset = newp->last_abbrev_offset = abbrev_offset;
+  newp->lines = NULL;
+  newp->locs = NULL;
+
+  return newp;
+}
+
+
 static int
 findcu_cb (const void *arg1, const void *arg2)
 {
@@ -83,7 +135,6 @@ findcu_cb (const void *arg1, const void *arg2)
   return 0;
 }
 
-
 struct Dwarf_CU *
 __libdw_findcu (dbg, start)
      Dwarf *dbg;
@@ -97,7 +148,6 @@ __libdw_findcu (dbg, start)
 
   if (start < dbg->next_cu_offset)
     {
-    invalid:
       __libdw_seterrno (DWARF_E_INVALID_DWARF);
       return NULL;
     }
@@ -106,43 +156,14 @@ __libdw_findcu (dbg, start)
   while (1)
     {
       Dwarf_Off oldoff = dbg->next_cu_offset;
-      uint8_t address_size;
-      uint8_t offset_size;
-      Dwarf_Off abbrev_offset;
-
-      if (INTUSE(dwarf_nextcu) (dbg, oldoff, &dbg->next_cu_offset, NULL,
-                               &abbrev_offset, &address_size, &offset_size)
-         != 0)
-       /* No more entries.  */
+      struct Dwarf_CU *newp = __libdw_intern_next_unit (dbg, false);
+      if (newp == NULL)
        return NULL;
 
-      /* XXX We need the version number but dwarf_nextcu swallows it.  */
-      const char *bytes = (dbg->sectiondata[IDX_debug_info]->d_buf + oldoff
-                          + (2 * offset_size - 4));
-      uint16_t version = read_2ubyte_unaligned (dbg, bytes);
-
-      /* We only know how to handle the DWARF version 2 through 4 formats.  */
-      if (unlikely (version < 2) || unlikely (version > 4))
-       goto invalid;
-
-      /* Create an entry for this CU.  */
-      struct Dwarf_CU *newp = libdw_typed_alloc (dbg, struct Dwarf_CU);
-
-      newp->dbg = dbg;
-      newp->start = oldoff;
-      newp->end = dbg->next_cu_offset;
-      newp->address_size = address_size;
-      newp->offset_size = offset_size;
-      newp->version = version;
-      Dwarf_Abbrev_Hash_init (&newp->abbrev_hash, 41);
-      newp->orig_abbrev_offset = newp->last_abbrev_offset = abbrev_offset;
-      newp->lines = NULL;
-      newp->locs = NULL;
-
       /* Add the new entry to the search tree.  */
       if (tsearch (newp, &dbg->cu_tree, findcu_cb) == NULL)
        {
-         /* Something went wrong.  Unfo the operation.  */
+         /* Something went wrong.  Undo the operation.  */
          dbg->next_cu_offset = oldoff;
          __libdw_seterrno (DWARF_E_NOMEM);
          return NULL;
index d9b216d5d6d6683ffba2e7513ead1ccae77e33b9..ff850ebff26c20f0dff1f3c774bbc6607415944b 100644 (file)
@@ -1,3 +1,7 @@
+2010-06-16  Roland McGrath  <roland@redhat.com>
+
+       * cu.c (cudie_offset): Use DIE_OFFSET_FROM_CU_OFFSET macro.
+
 2010-06-14  Roland McGrath  <roland@redhat.com>
 
        * find-debuginfo.c (try_open): Take new arg MAIN_STAT.  Compare
index 8f01ea6bd2d0cb086d999aaac0e2c6be23d50573..5f73d2a36da31b794c4ca10a4d32948497ff9456 100644 (file)
@@ -1,5 +1,5 @@
 /* Keeping track of DWARF compilation units in libdwfl.
-   Copyright (C) 2005, 2006 Red Hat, Inc.
+   Copyright (C) 2005-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -172,7 +172,8 @@ less_lazy (Dwfl_Module *mod)
 static inline Dwarf_Off
 cudie_offset (const struct dwfl_cu *cu)
 {
-  return cu->die.cu->start + 3 * cu->die.cu->offset_size - 4 + 3;
+  return DIE_OFFSET_FROM_CU_OFFSET (cu->die.cu->start, cu->die.cu->offset_size,
+                                   cu->die.cu->type_sig8 != 0);
 }
 
 static int
@@ -273,7 +274,7 @@ __libdwfl_nextcu (Dwfl_Module *mod, struct dwfl_cu *lastcu,
       size_t cuhdrsz;
       Dwarf_Off nextoff;
       int end = INTUSE(dwarf_nextcu) (mod->dw, cuoff, &nextoff, &cuhdrsz,
-                                       NULL, NULL, NULL);
+                                     NULL, NULL, NULL);
       if (end < 0)
        return DWFL_E_LIBDW;
       if (end > 0)