This is the mail archive of the
elfutils-devel@sourceware.org
mailing list for the elfutils project.
[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.
- From: Tom Tromey <tromey at redhat dot com>
- To: elfutils-devel at lists dot fedorahosted dot org
- Date: Tue, 20 Mar 2012 13:45:06 -0600
- Subject: [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, §ion)
+ == 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