This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 5/5] Make it possible to read multiple .debug_types sections. Each new .debug_types section is added to the end of the section vector. Various internal APIs were updated to understand multiple .debug_types sections. A new function, dwarf_next_unit_or_section, was added to allow iteration over multiple type sections.


 libdw/ChangeLog                            |   29 +++++++++++
 libdw/dwarf_begin_elf.c                    |   53 ++++++++++++++++----
 libdw/dwarf_formref_die.c                  |    4 +-
 libdw/dwarf_getlocation_implicit_pointer.c |    4 +-
 libdw/dwarf_nextcu.c                       |   67 +++++++++++++++++++++++---
 libdw/dwarf_offdie.c                       |   19 +++++---
 libdw/libdw.h                              |   21 ++++++++-
 libdw/libdw.map                            |    5 ++
 libdw/libdwP.h                             |    9 +++-
 libdw/libdw_findcu.c                       |   34 ++++++++-----
 tests/ChangeLog                            |   10 ++++
 tests/Makefile.am                          |   10 ++--
 tests/debugtypes.c                         |   72 ++++++++++++++++++++++++++++
 tests/run-debugtypes.sh                    |   35 +++++++++++++
 tests/testfile59.bz2                       |  Bin 0 -> 1424 bytes
 15 files changed, 325 insertions(+), 47 deletions(-)
 create mode 100644 tests/debugtypes.c
 create mode 100755 tests/run-debugtypes.sh
 create mode 100644 tests/testfile59.bz2

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 60f9ae0..c9e78a9 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,5 +1,34 @@
 2012-03-20  Tom Tromey  <tromey@redhat.com>
 
+	* libdw_findcu.c (__libdw_intern_next_unit): Use
+	dwarf_next_unit_or_section.  Initialize CU's section index.
+	(findcu_cb): Compare section indices.
+	(__libdw_findcu): Remove 'debug_type' argument, add 'sec_index'
+	argument.  Update.
+	* libdwP.h (struct Dwarf) [next_tu_cu]: New field.
+	(struct Dwarf_CU) [sec_index]: New field.
+	(__libdw_findcu, __libdw_offdie): Update.
+	(dwarf_next_unit_or_section): Add INTDECL.
+	* libdw.map: Add dwarf_next_unit_or_section.
+	* libdw.h (dwarf_next_unit_or_section): Declare.
+	* dwarf_offdie.c (__libdw_offdie): Remove 'debug_types' argument,
+	add 'sec_index' argument.  Validate section index.
+	(dwarf_offdie): Update.
+	(dwarf_offdie_types): Update.
+	* dwarf_nextcu.c (dwarf_next_unit_or_section): New function.
+	(dwarf_next_unit): Rewrite to use dwarf_next_unit_or_section.
+	(dwarf_nextcu): Likewise.
+	* dwarf_getlocation_implicit_pointer.c
+	(dwarf_getlocation_implicit_pointer): Pass CU's section index to
+	__libdw_offdie.
+	* dwarf_formref_die.c (dwarf_formref_die): Use CU's section
+	index.
+	* dwarf_begin_elf.c (add_section): New function.
+	(check_section): Use it.
+	(dwarf_begin_elf): Initialize next_tu_cu.
+
+2012-03-20  Tom Tromey  <tromey@redhat.com>
+
 	* dwarf_begin_elf.c (check_section): Remove 'inscngrp' argument.
 	(global_read, scngrp_read): Update.
 
diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c
index 4a726ce..ad253ec 100644
--- a/libdw/dwarf_begin_elf.c
+++ b/libdw/dwarf_begin_elf.c
@@ -87,6 +87,36 @@ static const char dwarf_scnnames[IDX_last][17] =
 #define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0]))
 
 
+static bool
+add_section (Dwarf *result, size_t cnt, Elf_Data *data, bool gzipped)
+{
+  if (unlikely (result->sectiondata[cnt].data != NULL))
+    {
+      /* Allocate a new entry for .debug_types.  */
+      ++result->n_sections;
+      result->sectiondata = realloc (result->sectiondata,
+				     result->n_sections
+				     * sizeof (struct Dwarf_Section));
+      if (result->sectiondata == NULL)
+	{
+	  __libdw_free_zdata (result);
+	  __libdw_seterrno (DWARF_E_NOMEM);
+	  free (result->sectiondata);
+	  free (result);
+	  return false;
+	}
+
+      cnt = result->n_sections - 1;
+    }
+
+  result->sectiondata[cnt].data = data;
+#if USE_ZLIB
+  result->sectiondata[cnt].gzipped = gzipped;
+#endif
+
+  return true;
+}
+
 static Dwarf *
 check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn)
 {
@@ -128,15 +158,18 @@ check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn)
     if (strcmp (scnname, dwarf_scnnames[cnt]) == 0)
       {
 	/* Found it.  Remember where the data is.  */
-	if (unlikely (result->sectiondata[cnt].data != NULL))
-	  /* A section appears twice.  That's bad.  We ignore the section.  */
+	if (unlikely (result->sectiondata[cnt].data != NULL
+		      && cnt != IDX_debug_types))
+	  /* A section appears twice.  That's bad.  We ignore the
+	     section, unless it is a .debug_types section.  */
 	  break;
 
 	/* Get the section data.  */
 	Elf_Data *data = elf_getdata (scn, NULL);
 	if (data != NULL && data->d_size != 0)
 	  /* Yep, there is actually data available.  */
-	  result->sectiondata[cnt].data = data;
+	  if (!add_section (result, cnt, data, false))
+	    return NULL;
 
 	break;
       }
@@ -146,8 +179,10 @@ check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn)
       {
 	/* A compressed section.  */
 
-	if (unlikely (result->sectiondata[cnt].data != NULL))
-	  /* A section appears twice.  That's bad.  We ignore the section.  */
+	if (unlikely (result->sectiondata[cnt].data != NULL
+		      && cnt != IDX_debug_types))
+	  /* A section appears twice.  That's bad.  We ignore the
+	     section, unless it is a .debug_types section.  */
 	  break;
 
 	/* Get the section data.  */
@@ -200,11 +235,8 @@ check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn)
 
 	    if (unlikely (zrc != Z_OK) || unlikely (z.avail_out != 0))
 	      free (zdata);
-	    else
-	      {
-		result->sectiondata[cnt].data = zdata;
-		result->sectiondata[cnt].gzipped = 1;
-	      }
+	    else if (!add_section (result, cnt, data, true))
+	      return NULL;
 	  }
 
 	break;
@@ -345,6 +377,7 @@ dwarf_begin_elf (elf, cmd, scngrp)
   result->mem_tail->remaining = result->mem_tail->size;
   result->mem_tail->prev = NULL;
 
+  result->next_tu_cu = IDX_debug_types;
   result->n_sections = IDX_last;
   result->sectiondata = calloc (result->n_sections, sizeof (Dwarf_Section));
   if (unlikely (result->sectiondata == NULL))
diff --git a/libdw/dwarf_formref_die.c b/libdw/dwarf_formref_die.c
index 88dc065..f2cfa10 100644
--- a/libdw/dwarf_formref_die.c
+++ b/libdw/dwarf_formref_die.c
@@ -1,5 +1,5 @@
 /* Look up the DIE in a reference-form attribute.
-   Copyright (C) 2005-2010 Red Hat, Inc.
+   Copyright (C) 2005-2010, 2012 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -105,7 +105,7 @@ dwarf_formref_die (attr, result)
 	  }
 	while (cu->type_sig8 != sig);
 
-      data = cu->dbg->sectiondata[IDX_debug_types].data;
+      data = cu->dbg->sectiondata[cu->sec_index].data;
       offset = cu->type_offset;
     }
   else
diff --git a/libdw/dwarf_getlocation_implicit_pointer.c b/libdw/dwarf_getlocation_implicit_pointer.c
index 4d9f6b9..9385038 100644
--- a/libdw/dwarf_getlocation_implicit_pointer.c
+++ b/libdw/dwarf_getlocation_implicit_pointer.c
@@ -1,5 +1,5 @@
 /* Return associated attribute for DW_OP_GNU_implicit_pointer.
-   Copyright (C) 2010 Red Hat, Inc.
+   Copyright (C) 2010, 2012 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -72,7 +72,7 @@ dwarf_getlocation_implicit_pointer (attr, op, result)
 
   Dwarf_Die die;
   if (__libdw_offdie (attr->cu->dbg, op->number, &die,
-		      attr->cu->type_offset != 0) == NULL)
+		      attr->cu->sec_index) == NULL)
     return -1;
 
   if (INTUSE(dwarf_attr) (&die, DW_AT_location, result) == NULL
diff --git a/libdw/dwarf_nextcu.c b/libdw/dwarf_nextcu.c
index 66dd191..a765a29 100644
--- a/libdw/dwarf_nextcu.c
+++ b/libdw/dwarf_nextcu.c
@@ -1,5 +1,5 @@
 /* Advance to next CU header.
-   Copyright (C) 2002-2010 Red Hat, Inc.
+   Copyright (C) 2002-2010, 2012 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -57,10 +57,14 @@
 
 
 int
-dwarf_next_unit (dwarf, off, next_off, header_sizep, versionp, abbrev_offsetp,
-		 address_sizep, offset_sizep, type_signaturep, type_offsetp)
+dwarf_next_unit_or_section (dwarf, off, real_off, next_off, header_sizep,
+			    versionp, abbrev_offsetp,
+			    address_sizep, offset_sizep,
+			    type_signaturep, type_offsetp,
+			    type_sectionp)
      Dwarf *dwarf;
      Dwarf_Off off;
+     Dwarf_Off *real_off;
      Dwarf_Off *next_off;
      size_t *header_sizep;
      Dwarf_Half *versionp;
@@ -69,16 +73,37 @@ dwarf_next_unit (dwarf, off, next_off, header_sizep, versionp, abbrev_offsetp,
      uint8_t *offset_sizep;
      uint64_t *type_signaturep;
      Dwarf_Off *type_offsetp;
+     size_t *type_sectionp;
 {
   const bool debug_types = type_signaturep != NULL;
-  const size_t sec_idx = debug_types ? IDX_debug_types : IDX_debug_info;
+  size_t sec_idx = (type_sectionp != NULL ? *type_sectionp
+		    : debug_types ? IDX_debug_types : IDX_debug_info);
 
   /* Maybe there has been an error before.  */
   if (dwarf == NULL)
     return -1;
 
+  /* Initialize the section if needed.  */
+  if (type_sectionp != NULL && sec_idx == 0)
+    {
+      *type_sectionp = IDX_debug_types;
+      sec_idx = IDX_debug_types;
+    }
+
+  /* If we are looking at all type sections, and we went off the end,
+     move to the next one.  */
+  if (debug_types && type_sectionp != NULL
+      && dwarf->sectiondata[sec_idx].data != NULL
+      && unlikely (off + 4 >= dwarf->sectiondata[sec_idx].data->d_size))
+    {
+      off = 0;
+      ++*type_sectionp;
+      ++sec_idx;
+    }
+
   /* If we reached the end before don't do anything.  */
   if (off == (Dwarf_Off) -1l
+      || unlikely (sec_idx >= dwarf->n_sections)
       || unlikely (dwarf->sectiondata[sec_idx].data == NULL)
       /* Make sure there is enough space in the .debug_info section
 	 for at least the initial word.  We cannot test the rest since
@@ -89,6 +114,9 @@ dwarf_next_unit (dwarf, off, next_off, header_sizep, versionp, abbrev_offsetp,
       return 1;
     }
 
+  if (real_off)
+    *real_off = off;
+
   /* This points into the .debug_info section to the beginning of the
      CU entry.  */
   const unsigned char *data = dwarf->sectiondata[sec_idx].data->d_buf;
@@ -200,6 +228,29 @@ dwarf_next_unit (dwarf, off, next_off, header_sizep, versionp, abbrev_offsetp,
 
   return 0;
 }
+INTDEF(dwarf_next_unit_or_section)
+
+int
+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;
+     Dwarf_Half *versionp;
+     Dwarf_Off *abbrev_offsetp;
+     uint8_t *address_sizep;
+     uint8_t *offset_sizep;
+     uint64_t *type_signaturep;
+     Dwarf_Off *type_offsetp;
+{
+  return INTUSE(dwarf_next_unit_or_section) (dwarf, off, NULL, next_off,
+					     header_sizep, versionp,
+					     abbrev_offsetp, address_sizep,
+					     offset_sizep,
+					     type_signaturep,
+					     type_offsetp, NULL);
+}
 INTDEF(dwarf_next_unit)
 
 int
@@ -213,8 +264,10 @@ dwarf_nextcu (dwarf, off, next_off, header_sizep, 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);
+  return INTUSE(dwarf_next_unit_or_section) (dwarf, off, NULL, next_off,
+					     header_sizep, NULL,
+					     abbrev_offsetp, address_sizep,
+					     offset_sizep,
+					     NULL, NULL, NULL);
 }
 INTDEF(dwarf_nextcu)
diff --git a/libdw/dwarf_offdie.c b/libdw/dwarf_offdie.c
index 90ada60..f426723 100644
--- a/libdw/dwarf_offdie.c
+++ b/libdw/dwarf_offdie.c
@@ -1,5 +1,5 @@
 /* Return DIE at given offset.
-   Copyright (C) 2002-2010 Red Hat, Inc.
+   Copyright (C) 2002-2010, 2012 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -59,13 +59,18 @@
 Dwarf_Die *
 internal_function
 __libdw_offdie (Dwarf *dbg, Dwarf_Off offset, Dwarf_Die *result,
-		bool debug_types)
+		size_t sec_index)
 {
   if (dbg == NULL)
     return NULL;
 
-  Elf_Data *const data = dbg->sectiondata[debug_types ? IDX_debug_types
-					  : IDX_debug_info].data;
+  if (sec_index >= dbg->n_sections)
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return NULL;
+    }
+
+  Elf_Data *const data = dbg->sectiondata[sec_index].data;
   if (offset >= data->d_size)
     {
       __libdw_seterrno (DWARF_E_INVALID_DWARF);
@@ -79,7 +84,7 @@ __libdw_offdie (Dwarf *dbg, Dwarf_Off offset, Dwarf_Die *result,
   result->addr = (char *) data->d_buf + offset;
 
   /* Get the CU.  */
-  result->cu = __libdw_findcu (dbg, offset, debug_types);
+  result->cu = __libdw_findcu (dbg, offset, sec_index);
   if (result->cu == NULL)
     {
       /* This should never happen.  The input file is malformed.  */
@@ -97,7 +102,7 @@ dwarf_offdie (dbg, offset, result)
      Dwarf_Off offset;
      Dwarf_Die *result;
 {
-  return __libdw_offdie (dbg, offset, result, false);
+  return __libdw_offdie (dbg, offset, result, IDX_debug_info);
 }
 INTDEF(dwarf_offdie)
 
@@ -107,5 +112,5 @@ dwarf_offdie_types (dbg, offset, result)
      Dwarf_Off offset;
      Dwarf_Die *result;
 {
-  return __libdw_offdie (dbg, offset, result, true);
+  return __libdw_offdie (dbg, offset, result, IDX_debug_types);
 }
diff --git a/libdw/libdw.h b/libdw/libdw.h
index e001b7a..ef82636 100644
--- a/libdw/libdw.h
+++ b/libdw/libdw.h
@@ -1,5 +1,5 @@
 /* Interfaces for libdw.
-   Copyright (C) 2002-2010 Red Hat, Inc.
+   Copyright (C) 2002-2010, 2012 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -304,6 +304,25 @@ extern int dwarf_next_unit (Dwarf *dwarf, Dwarf_Off off, Dwarf_Off *next_off,
 			    uint64_t *type_signaturep, Dwarf_Off *type_offsetp)
      __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.  If
+   iterating over .debug_types sections, *TYPE_SECTIONP should be
+   initialized to zero before the first call.  *REAL_OFF is set to the
+   real offset of the returned unit; when iterating, the previous
+   offset used in the loop may not point anywhere useful.  */
+extern int dwarf_next_unit_or_section (Dwarf *dwarf, Dwarf_Off off,
+				       Dwarf_Off *real_off, Dwarf_Off *next_off,
+				       size_t *header_sizep,
+				       Dwarf_Half *versionp,
+				       Dwarf_Off *abbrev_offsetp,
+				       uint8_t *address_sizep,
+				       uint8_t *offset_sizep,
+				       uint64_t *type_signaturep,
+				       Dwarf_Off *type_offsetp,
+				       size_t *type_sectionp)
+     __nonnull_attribute__ (4);
+
 
 /* Decode one DWARF CFI entry (CIE or FDE) from the raw section data.
    The E_IDENT from the originating ELF file indicates the address
diff --git a/libdw/libdw.map b/libdw/libdw.map
index 1f71d03..4217f29 100644
--- a/libdw/libdw.map
+++ b/libdw/libdw.map
@@ -254,3 +254,8 @@ ELFUTILS_0.149 {
 
     dwfl_dwarf_line;
 } ELFUTILS_0.148;
+
+ELFUTILS_0.153 {
+  global:
+    dwarf_next_unit_or_section;
+} ELFUTILS_0.149;
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index fee0bac..de60399 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -191,6 +191,7 @@ struct Dwarf
   /* Search tree and sig8 hash table for .debug_types type units.  */
   void *tu_tree;
   Dwarf_Off next_tu_offset;
+  size_t next_tu_cu;
   Dwarf_Sig8_Hash sig8_hash;
 
   /* Address ranges.  */
@@ -303,6 +304,8 @@ struct Dwarf_CU
   uint8_t offset_size;
   uint16_t version;
 
+  size_t sec_index;
+
   /* Zero if this is a normal CU.  Nonzero if it is a type unit.  */
   size_t type_offset;
   uint64_t type_sig8;
@@ -413,7 +416,8 @@ 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, bool tu)
+extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset,
+					size_t sec_idx)
      __nonnull_attribute__ (1) internal_function;
 
 /* Return tag of given DIE.  */
@@ -480,7 +484,7 @@ extern int __libdw_intern_expression (Dwarf *dbg,
   __nonnull_attribute__ (5, 6, 9, 10) internal_function;
 
 extern Dwarf_Die *__libdw_offdie (Dwarf *dbg, Dwarf_Off offset,
-				  Dwarf_Die *result, bool debug_types)
+				  Dwarf_Die *result, size_t sec_index)
   internal_function;
 
 
@@ -680,6 +684,7 @@ INTDECL (dwarf_highpc)
 INTDECL (dwarf_lowpc)
 INTDECL (dwarf_nextcu)
 INTDECL (dwarf_next_unit)
+INTDECL (dwarf_next_unit_or_section)
 INTDECL (dwarf_offdie)
 INTDECL (dwarf_ranges)
 INTDECL (dwarf_siblingof)
diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c
index 8e5f9e9..2b8a005 100644
--- a/libdw/libdw_findcu.c
+++ b/libdw/libdw_findcu.c
@@ -1,5 +1,5 @@
 /* Find CU for given offset.
-   Copyright (C) 2003-2010 Red Hat, Inc.
+   Copyright (C) 2003-2010, 2012 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -67,6 +67,7 @@ __libdw_intern_next_unit (dbg, debug_types)
     = debug_types ? &dbg->next_tu_offset : &dbg->next_cu_offset;
 
   Dwarf_Off oldoff = *offsetp;
+  Dwarf_Off real_off;
   uint16_t version;
   uint8_t address_size;
   uint8_t offset_size;
@@ -74,11 +75,13 @@ __libdw_intern_next_unit (dbg, debug_types)
   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)
+  if (INTUSE(dwarf_next_unit_or_section) (dbg, oldoff, &real_off, offsetp, NULL,
+					  &version, &abbrev_offset,
+					  &address_size, &offset_size,
+					  debug_types ? &type_sig8 : NULL,
+					  debug_types ? &type_offset : NULL,
+					  debug_types ? &dbg->next_tu_cu : NULL)
+      != 0)
     /* No more entries.  */
     return NULL;
 
@@ -93,11 +96,12 @@ __libdw_intern_next_unit (dbg, debug_types)
   struct Dwarf_CU *newp = libdw_typed_alloc (dbg, struct Dwarf_CU);
 
   newp->dbg = dbg;
-  newp->start = oldoff;
+  newp->start = real_off;
   newp->end = *offsetp;
   newp->address_size = address_size;
   newp->offset_size = offset_size;
   newp->version = version;
+  newp->sec_index = debug_types ? dbg->next_tu_cu : IDX_debug_info;
   newp->type_sig8 = type_sig8;
   newp->type_offset = type_offset;
   Dwarf_Abbrev_Hash_init (&newp->abbrev_hash, 41);
@@ -115,6 +119,11 @@ findcu_cb (const void *arg1, const void *arg2)
   struct Dwarf_CU *cu1 = (struct Dwarf_CU *) arg1;
   struct Dwarf_CU *cu2 = (struct Dwarf_CU *) arg2;
 
+  if (cu1->sec_index < cu2->sec_index)
+    return -1;
+  if (cu1->sec_index > cu2->sec_index)
+    return 1;
+
   /* Find out which of the two arguments is the search value.  It has
      end offset 0.  */
   if (cu1->end == 0)
@@ -136,22 +145,23 @@ findcu_cb (const void *arg1, const void *arg2)
 }
 
 struct Dwarf_CU *
-__libdw_findcu (dbg, start, debug_types)
+__libdw_findcu (dbg, start, sec_index)
      Dwarf *dbg;
      Dwarf_Off start;
-     bool debug_types;
+     size_t sec_index;
 {
+  const bool debug_types = sec_index != IDX_debug_info;
   void **tree = debug_types ? &dbg->tu_tree : &dbg->cu_tree;
   Dwarf_Off *next_offset
     = debug_types ? &dbg->next_tu_offset : &dbg->next_cu_offset;
 
   /* Maybe we already know that CU.  */
-  struct Dwarf_CU fake = { .start = start, .end = 0 };
+  struct Dwarf_CU fake = { .start = start, .end = 0, .sec_index = sec_index };
   struct Dwarf_CU **found = tfind (&fake, tree, findcu_cb);
   if (found != NULL)
     return *found;
 
-  if (start < *next_offset)
+  if (!debug_types && start < *next_offset)
     {
       __libdw_seterrno (DWARF_E_INVALID_DWARF);
       return NULL;
@@ -175,7 +185,7 @@ __libdw_findcu (dbg, start, debug_types)
 	}
 
       /* Is this the one we are looking for?  */
-      if (start < *next_offset)
+      if (!debug_types && start < *next_offset)
 	// XXX Match exact offset.
 	return newp;
     }
diff --git a/tests/ChangeLog b/tests/ChangeLog
index a782591..17523b3 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,13 @@
+2012-03-20  Tom Tromey  <tromey@redhat.com>
+
+	* debugtypes.c: New file.
+	* run-debugtypes.sh: New file.
+	* testfile59.bz2: New file.
+	* Makefile.am (noinst_PROGRAMS): Add debugtypes.
+	(TESTS): Add run-debugtypes.sh.
+	(EXTRA_DIST): Add run-debugtypes.sh, testfile59.bz2.
+	(debugtypes_LDADD): New variable.
+
 2012-02-21  Kurt Roeckx  <kurt@roeckx.be>
 
 	* run-alldts.sh: testrun ./alldts.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3074c89..1b5ebf3 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,6 +1,6 @@
 ## Process this file with automake to create Makefile.in
 ##
-## Copyright (C) 1996-2011 Red Hat, Inc.
+## Copyright (C) 1996-2012 Red Hat, Inc.
 ## This file is part of Red Hat elfutils.
 ##
 ## Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -58,7 +58,7 @@ noinst_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \
 		  dwfl-addr-sect dwfl-bug-report early-offscn \
 		  dwfl-bug-getmodules dwarf-getmacros addrcfi \
 		  test-flag-nobits dwarf-getstring rerequest_tag \
-		  alldts md5-sha1-test
+		  alldts md5-sha1-test debugtypes
 asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \
 	    asm-tst6 asm-tst7 asm-tst8 asm-tst9
 
@@ -86,7 +86,7 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \
 	run-disasm-x86.sh run-disasm-x86-64.sh \
 	run-early-offscn.sh run-dwarf-getmacros.sh \
 	run-test-flag-nobits.sh run-prelink-addr-test.sh \
-	run-dwarf-getstring.sh run-rerequest_tag.sh
+	run-dwarf-getstring.sh run-rerequest_tag.sh run-debugtypes.sh
 # run-show-ciefde.sh
 
 if !STANDALONE
@@ -161,7 +161,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
 	     testfile55-32.bz2 testfile55-32.debug.bz2 \
 	     testfile55-32.prelink.bz2 testfile55-64.bz2 \
 	     testfile55-64.debug.bz2 testfile55-64.prelink.bz2 \
-	     testfile56.bz2 testfile57.bz2 testfile58.bz2
+	     testfile56.bz2 testfile57.bz2 testfile58.bz2 \
+	     run-debugtypes.sh testfile59.bz2
 
 installed_TESTS_ENVIRONMENT = libdir=$(DESTDIR)$(libdir) \
 			      bindir=$(DESTDIR)$(bindir) \
@@ -258,6 +259,7 @@ test_flag_nobits_LDADD = $(libelf) $(libmudflap)
 rerequest_tag_LDADD = $(libdw) $(libmudflap)
 alldts_LDADD = $(libebl) $(libelf) $(libmudflap)
 md5_sha1_test_LDADD = $(libeu)
+debugtypes_LDADD = $(libdw) $(libelf) $(libmudflap)
 
 if GCOV
 check: check-am coverage
diff --git a/tests/debugtypes.c b/tests/debugtypes.c
new file mode 100644
index 0000000..3022a9a
--- /dev/null
+++ b/tests/debugtypes.c
@@ -0,0 +1,72 @@
+/* Copyright (C) 2012 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.
+
+   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
+
+#include <fcntl.h>
+#include ELFUTILS_HEADER(dw)
+#include <stdio.h>
+#include <unistd.h>
+
+int
+main (int argc, char *argv[])
+{
+  for (int i = 1; i < argc; ++i)
+    {
+      int fd = open (argv[i], O_RDONLY);
+
+      Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
+      if (dbg != NULL)
+	{
+	  Dwarf_Off off = 0;
+	  Dwarf_Off real_off;
+	  size_t cuhl;
+	  Dwarf_Off noff;
+	  size_t section = 0;
+	  uint64_t signature;
+	  Dwarf_Off type_off;
+
+	  while (dwarf_next_unit_or_section (dbg, off, &real_off, &noff, &cuhl,
+					     NULL, NULL, NULL, NULL,
+					     &signature, &type_off, &section)
+		 == 0)
+	    {
+	      Dwarf_Die die_mem;
+	      Dwarf_Die *die = dwarf_offdie (dbg, real_off + cuhl, &die_mem);
+
+	      printf ("section %d, off %ld, type off %ld, ok = %d\n",
+		      (int) section, (long) real_off, (long) type_off,
+		      die != NULL);
+
+	      off = noff;
+	    }
+
+	  dwarf_end (dbg);
+	}
+
+      close (fd);
+    }
+}
diff --git a/tests/run-debugtypes.sh b/tests/run-debugtypes.sh
new file mode 100755
index 0000000..7c98515
--- /dev/null
+++ b/tests/run-debugtypes.sh
@@ -0,0 +1,35 @@
+#! /bin/sh
+# Copyright (C) 2012 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.
+#
+# 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>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile59
+
+testrun_compare ./debugtypes testfile59 <<\EOF
+section 10, off 0, type off 29, ok = 1
+section 11, off 0, type off 29, ok = 1
+EOF
+
+exit 0
diff --git a/tests/testfile59.bz2 b/tests/testfile59.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..aa1616d24d1e10bb3f82f97d2d8f9fc47247bf9a
GIT binary patch
literal 1424
zcmV;B1#kL7T4*^jL0KkKSz-fU7XSsPfB*mg|L=b1|Nr~#+GfB1|MI<W)$eb~6I=)Z
zKmZCMa0$=^lxgh^n60kq-G&Vinom)xHc7B)BRwQE$>}_!Ks3;3dWVz%$a*26lTTAj
zfMfvlo}sixCdxD#0BI8(a)L84^SO&Ug%$`4RzXlMr1dWL`iWB>pF0000001SXKCX-2u
zpQ=4Zng^+)L6bqD>H{DHKzcxWfChoJ00w{qKmY(54^u=K6GoaEX{IJ7hMH(#BLIvb
zGGHc}Fc1a+6C(hcWCI`uA*Mi)MNbtp@}85$GgBs-00Tg113{nw4FCXWG&BG`KmalT
z&;SK3pfI;ilcebwjN3jAxfPZylWgGQ4aLe85zeYdSTk=a4JBz4EZKc)f#1q{-T=lH
z6ZR4S+E)wPN!a<j9Gwn~u6#`Sy{dLte$CbdxcM2wX2Vc2F9XtLn^|aWKHOwdwQl4o
zX2#o=8(NhE6KmevKYoV(a)12VALU0fJpZ!XOM_wS=9X7Ve0s^{3!!or6Wr>Jx&8NP=Y
zIMGJMEH4yi1R8(a)mLZTo{8j8(IDY4f&>X>XMK1(rSII<o?zZEg)&h;-xk9`uIMf8E+
znE`_c3lxL_+_^|133b_uA|e8X1P}v5GPMgz?<vx&3JeNo(a)_Xl2$)PCg84yDTB0xzP
z11oKdvy%yy=GNeKmGdd=k)R-Ah9sgi#*l0;w}tmv;GV)wcBN>0?;5Sr{3BSx3lyS2
z2uX4fOo&MVV!%P6X(%+Y?J1fCBMYX0N(a)j!7(2R3NorghzX=MWQBYkaqA$rS!TvdtX
zX%rYGu3-isq1=EZh_I^AL6&SssW6KW4T5YCRV`qEh{V_lum;m%(r|W7bs1c7OtU0F
zqreEAAg?Ee8%PnJ^dzuxV5By;HF8=f&)ZBUkU+k>ose*p{OxY7#US-3D6jxIfK^bn
z5U4}M-YJU7RVyK;h2;t0A(aLcB-|xEwpYU1P}8Pa9FhI-eOsr3B8^H<(d&i(a)G_6>^
zEJxojIEbm3HVOg?`VashR>1*i&=T0oqp+h1rI`T*7$!%*5}7*;MJXDjwrT<=)~U)c
zWcGlbqzlR9YXoQHnjv&FD77(a)fNp$K1kW39HvmjX(a)ihv^)n%@0|{1n6jAS7u6rvh|p
zUDhOB>I#u5u!BV_(1Zr%P(>CM=VynN_EB-5(Md8#?i!c=l;uSREJrXw1^~;`z13+v
zvWq0xEGBtG3yq-QOVFW0pDGR!GY5SF0UIq<aDowR3?LZ;4Isj<68w1D(F$9N7S`Hf
znIZDVxv{0r7o5qU_47p2VFwWm_MsQ~ifMc&Hd1Q(a)2y9(OF!$~d*)BZNK$r<N>{@GL
zn=2p+z(a)bIOR}@N;Qofw~q(a)k@Z?qrqRg+fyPP8+u$rm!w!p?bm?0_w7iKd~r$(_c``
z;~aUFFK-2$6ab}qA4TDXL)yQzlSX8N;yiV_8TL*my^f9qkbv;LpaWDM`LK?je1X|n
zku>A-Ri&$_kiR(a)EPzrW;q$$8p(7h06bn9J>9mMx1cQG5B<w>^$4mpfk_^eY)GYzI$
zf>@qwj(XnAM_q6#7$I+zAh!%;Abrj|Mgb4PcQhIoV|7*AYGNb)no<hu2lypDAoMed
zpwkubkx!glu>6H~s7P0SX3}c&MOzyVDr^KAqz7qrS|k`g%5k9i3f5<0t1WISIEYPw
z6pA>EgvX;|l7-x<5f}{cnyc-;iP2QmO4*8mPm%{cGea8Z>x@*AnFOU9u>umFjV!%r
z42`4bphL~XR5tdHM^fUbey)1d-y%q2+6fj`FLt%=z-Xgb8C?cTR*k{T<W2HIydAF*
e`50Fcb?c8Pe5Q5(V2kQM(a)pmLsg$V{AHSuuonq(a)2i

literal 0
HcmV?d00001

-- 
1.7.7.6


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]