Strip on mips
by Kurt Roeckx
Hi,
I'm trying to debug why strip on mips isn't working properly.
What I see is that for the debug sections, sh_type is not set to
SHT_PROGBITS but to SHT_MIPS_DWARF.
The stripped file still ends up with the debug information it it,
and the file that is supposed to have the debug symbols in it
has it set to SHT_NOBITS, and is rather small.
I'm assuming this is because of the SHT_MIPS_DWARF. I'm not sure
how to find where it's going wrong.
Kurt
10 years, 11 months
libdw patch for .debug_types iteration
by Tom Tromey
Tom
>From 1b85426f7a1fa39cfb9ff83b864e825072115847 Mon Sep 17 00:00:00 2001
From: Tom Tromey <tromey(a)redhat.com>
Date: Mon, 19 Mar 2012 11:46:45 -0600
Subject: [PATCH] Fix bug using dwarf_next_unit to iterate over .debug_types
* libdw_findcu.c (findcu_cb): Move earlier.
(__libdw_intern_next_unit): Add new CU to search tree here...
(__libdw_findcu): ... not here.
If you call dwarf_next_unit to iterate over .debug_types, then call
dwarf_offdie_types, you can see a failure if some earlier call
happened to call __libdw_intern_next_unit via dwarf_formref_die.
What happens is that __libdw_intern_next_unit updates the Dwarf's
next_tu_offset, but does not add the TU to the TU search tree. So,
the call to dwarf_offdie_types does not find the TU in the tree, and
will not search any more, causing a failure.
This fix changes __libdw_intern_next_unit to add the TU to the search
tree, rather than relying on __libdw_findcu to do it.
---
libdw/ChangeLog | 6 ++++
libdw/libdw_findcu.c | 68 ++++++++++++++++++++++++-------------------------
2 files changed, 39 insertions(+), 35 deletions(-)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 98b67f4..f96c0d1 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,9 @@
+2012-03-19 Tom Tromey <tromey(a)redhat.com>
+
+ * libdw_findcu.c (findcu_cb): Move earlier.
+ (__libdw_intern_next_unit): Add new CU to search tree here...
+ (__libdw_findcu): ... not here.
+
2012-01-31 Mark Wielaard <mjw(a)redhat.com>
* dwarf_formudata.c (dwarf_formudata): Handle DW_FORM_sec_offset.
diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c
index 8e5f9e9..83c96ba 100644
--- a/libdw/libdw_findcu.c
+++ b/libdw/libdw_findcu.c
@@ -56,6 +56,31 @@
#include <search.h>
#include "libdwP.h"
+static int
+findcu_cb (const void *arg1, const void *arg2)
+{
+ struct Dwarf_CU *cu1 = (struct Dwarf_CU *) arg1;
+ struct Dwarf_CU *cu2 = (struct Dwarf_CU *) arg2;
+
+ /* Find out which of the two arguments is the search value. It has
+ end offset 0. */
+ if (cu1->end == 0)
+ {
+ if (cu1->start < cu2->start)
+ return -1;
+ if (cu1->start >= cu2->end)
+ return 1;
+ }
+ else
+ {
+ if (cu2->start < cu1->start)
+ return 1;
+ if (cu2->start >= cu1->end)
+ return -1;
+ }
+
+ return 0;
+}
struct Dwarf_CU *
internal_function
@@ -65,6 +90,7 @@ __libdw_intern_next_unit (dbg, debug_types)
{
Dwarf_Off *const offsetp
= debug_types ? &dbg->next_tu_offset : &dbg->next_cu_offset;
+ void **tree = debug_types ? &dbg->tu_tree : &dbg->cu_tree;
Dwarf_Off oldoff = *offsetp;
uint16_t version;
@@ -105,34 +131,16 @@ __libdw_intern_next_unit (dbg, debug_types)
newp->lines = NULL;
newp->locs = NULL;
- return newp;
-}
-
-
-static int
-findcu_cb (const void *arg1, const void *arg2)
-{
- struct Dwarf_CU *cu1 = (struct Dwarf_CU *) arg1;
- struct Dwarf_CU *cu2 = (struct Dwarf_CU *) arg2;
-
- /* Find out which of the two arguments is the search value. It has
- end offset 0. */
- if (cu1->end == 0)
+ /* Add the new entry to the search tree. */
+ if (tsearch (newp, tree, findcu_cb) == NULL)
{
- if (cu1->start < cu2->start)
- return -1;
- if (cu1->start >= cu2->end)
- return 1;
- }
- else
- {
- if (cu2->start < cu1->start)
- return 1;
- if (cu2->start >= cu1->end)
- return -1;
+ /* Something went wrong. Undo the operation. */
+ *offsetp = oldoff;
+ __libdw_seterrno (DWARF_E_NOMEM);
+ return NULL;
}
- return 0;
+ return newp;
}
struct Dwarf_CU *
@@ -160,20 +168,10 @@ __libdw_findcu (dbg, start, debug_types)
/* No. Then read more CUs. */
while (1)
{
- Dwarf_Off oldoff = *next_offset;
struct Dwarf_CU *newp = __libdw_intern_next_unit (dbg, debug_types);
if (newp == NULL)
return NULL;
- /* Add the new entry to the search tree. */
- if (tsearch (newp, tree, findcu_cb) == NULL)
- {
- /* Something went wrong. Undo the operation. */
- *next_offset = oldoff;
- __libdw_seterrno (DWARF_E_NOMEM);
- return NULL;
- }
-
/* Is this the one we are looking for? */
if (start < *next_offset)
// XXX Match exact offset.
--
1.7.7.6
11 years, 5 months
[Patch] Don't relocate compressed sections
by Mark Wielaard
Hi,
As pointed out in https://bugzilla.redhat.com/show_bug.cgi?id=807053
relocating a compressed section will corrupt it. To more properly
support compressed sections we should finish the roland/relocate branch
for lazy relocations work. The best we can do for now is to not corrupt
the contents of the compressed sections and not crash when we don't have
all Dwarf debug section data. The attached two patches do that.
Cheers,
Mark
11 years, 6 months
FYI: readelf.c (print_gdb_index_section): Accept version 6.
by Mark Wielaard
Hi,
Just applied the following to accept a newer version number
for .gdb_index in readelf. No real change in the format, the updated
version is just a marker that there are more symbols in the index
available.
Cheers,
Mark
11 years, 6 months
Re: [PATCH 2/5] Make IDX_debug_types come last. In a subsequent patch we will put all .debug_types sections at the end the of the section array. This change arranges for them to appear sequentially.
by Roland McGrath
I see no reason to think that the multiple-sections issue in an ET_REL file
would be limited to .debug_types. A producer doing proper CUs for COMDAT
cases would have multiple .debug_info sections by the same token. For
these two flavors, it can make sense just to iterate over all the sections.
(The same is true of aranges, line, frame--all the "independent" or "root"
sections that are examined on their own rather than pointed to by DIEs.)
But such a producer could very well produce multiple .debug_{abbrev,str} et
al sections, each in the COMDAT group with the .debug_info or .debug_types
that points at it. And for those, the only way to figure out the right
section to be looking at is by following the relocation records for the
.debug_{info,types} section data. We could in theory handle this after we
merge the roland/relocate branch, but the reorganization of struct libdwP
would have to be more substantial than what you've done here.
All in all, this looks to me like a half-measure to handle just one
particular case you've encountered. That case is part of a large class of
general ET_REL cases that we decided long ago libdw had no reason to try to
handle. Either we should handle the full generality of ET_REL files
thoroughly--a lot of work that I'm quite doubtful is worthwhile--or we
should stick to the existing decision that we handle ET_REL files only for
the very special case of Linux .ko files (in which the DWARF info looks
much more like the output of a final link for most purposes).
Thanks,
Roland
11 years, 6 months
[0/5] handle multiple .debug_types sections
by Tom Tromey
I added support for multiple .debug_types sections to libdw.
I consider this a WIP patch. There is one definitely bad patch (#4) and
of course the usual stylistic things; in particular the new CU-iterating
function (in patch #5) is pretty ugly.
I'd appreciate feedback on this.
Tom
11 years, 6 months
[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.
by Tom Tromey
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(a)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(a)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(a)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(a)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(a)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(a)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(a)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@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@12VALU0fJpZ!XOM_wS=9X7Ve0s^{3!!or6Wr>Jx&8NP=Y
zIMGJMEH4yi1R8@mLZTo{8j8(IDY4f&>X>XMK1(rSII<o?zZEg)&h;-xk9`uIMf8E+
znE`_c3lxL_+_^|133b_uA|e8X1P}v5GPMgz?<vx&3JeNo@_Xl2$)PCg84yDTB0xzP
z11oKdvy%yy=GNeKmGdd=k)R-Ah9sgi#*l0;w}tmv;GV)wcBN>0?;5Sr{3BSx3lyS2
z2uX4fOo&MVV!%P6X(%+Y?J1fCBMYX0N@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@G_6>^
zEJxojIEbm3HVOg?`VashR>1*i&=T0oqp+h1rI`T*7$!%*5}7*;MJXDjwrT<=)~U)c
zWcGlbqzlR9YXoQHnjv&FD77@fNp$K1kW39HvmjX@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@2y9(OF!$~d*)BZNK$r<N>{@GL
zn=2p+z@bIOR}@N;Qofw~q@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@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@pmLsg$V{AHSuuonq@2i
literal 0
HcmV?d00001
--
1.7.7.6
11 years, 6 months
[PATCH 4/5] remove section-group code from check_section
by Tom Tromey
libdw/ChangeLog | 5 +++++
libdw/dwarf_begin_elf.c | 16 +++-------------
2 files changed, 8 insertions(+), 13 deletions(-)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index c3dbda9..60f9ae0 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,5 +1,10 @@
2012-03-20 Tom Tromey <tromey(a)redhat.com>
+ * dwarf_begin_elf.c (check_section): Remove 'inscngrp' argument.
+ (global_read, scngrp_read): Update.
+
+2012-03-20 Tom Tromey <tromey(a)redhat.com>
+
* libdwP.h (struct Dwarf) [n_sections]: New field.
[sectiondata]: Change type.
* dwarf_end.c (__libdw_free_zdata): Use n_sections.
diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c
index def8ed6..4a726ce 100644
--- a/libdw/dwarf_begin_elf.c
+++ b/libdw/dwarf_begin_elf.c
@@ -88,7 +88,7 @@ static const char dwarf_scnnames[IDX_last][17] =
static Dwarf *
-check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp)
+check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn)
{
GElf_Shdr shdr_mem;
GElf_Shdr *shdr;
@@ -106,16 +106,6 @@ check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp)
if (unlikely (shdr->sh_type == SHT_NOBITS))
return result;
- /* Make sure the section is part of a section group only iff we
- really need it. If we are looking for the global (= non-section
- group debug info) we have to ignore all the info in section
- groups. If we are looking into a section group we cannot look at
- a section which isn't part of the section group. */
- if (! inscngrp && (shdr->sh_flags & SHF_GROUP) != 0)
- /* Ignore the section. */
- return result;
-
-
/* We recognize the DWARF section by their names. This is not very
safe and stable but the best we can do. */
const char *scnname = elf_strptr (result->elf, ehdr->e_shstrndx,
@@ -255,7 +245,7 @@ global_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr)
Elf_Scn *scn = NULL;
while (result != NULL && (scn = elf_nextscn (elf, scn)) != NULL)
- result = check_section (result, ehdr, scn, false);
+ result = check_section (result, ehdr, scn);
return valid_p (result);
}
@@ -294,7 +284,7 @@ scngrp_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr, Elf_Scn *scngrp)
return NULL;
}
- result = check_section (result, ehdr, scn, true);
+ result = check_section (result, ehdr, scn);
if (result == NULL)
break;
}
--
1.7.7.6
11 years, 6 months
[PATCH 3/5] Change sectiondata to be dynamically allocated. This allows us to later add multiple .debug_types sections to the section data vector.
by Tom Tromey
libdw/ChangeLog | 10 ++++++++++
libdw/dwarf_begin_elf.c | 13 +++++++++++++
libdw/dwarf_end.c | 4 +++-
libdw/libdwP.h | 5 ++++-
4 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 6fb5d8d..c3dbda9 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,5 +1,15 @@
2012-03-20 Tom Tromey <tromey(a)redhat.com>
+ * libdwP.h (struct Dwarf) [n_sections]: New field.
+ [sectiondata]: Change type.
+ * dwarf_end.c (__libdw_free_zdata): Use n_sections.
+ (dwarf_end): Free the section data.
+ * dwarf_begin_elf.c (check_section, valid_p, scngrp_read): Free
+ the section data.
+ (dwarf_begin_elf): Allocate the section data.
+
+2012-03-20 Tom Tromey <tromey(a)redhat.com>
+
* libdwP.h (IDX_debug_types): Move just before IDX_last.
* dwarf_begin_elf.c (dwarf_scnnames): Move .debug_types to the
end.
diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c
index e62ef07..def8ed6 100644
--- a/libdw/dwarf_begin_elf.c
+++ b/libdw/dwarf_begin_elf.c
@@ -126,6 +126,7 @@ check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp)
invalid. */
__libdw_free_zdata (result);
__libdw_seterrno (DWARF_E_INVALID_ELF);
+ free (result->sectiondata);
free (result);
return NULL;
}
@@ -239,6 +240,7 @@ valid_p (Dwarf *result)
{
__libdw_free_zdata (result);
__libdw_seterrno (DWARF_E_NO_DWARF);
+ free (result->sectiondata);
free (result);
result = NULL;
}
@@ -269,6 +271,7 @@ scngrp_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr, Elf_Scn *scngrp)
{
/* We cannot read the section content. Fail! */
__libdw_free_zdata (result);
+ free (result->sectiondata);
free (result);
return NULL;
}
@@ -286,6 +289,7 @@ scngrp_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr, Elf_Scn *scngrp)
never happen. */
__libdw_free_zdata (result);
__libdw_seterrno (DWARF_E_INVALID_ELF);
+ free (result->sectiondata);
free (result);
return NULL;
}
@@ -351,6 +355,15 @@ dwarf_begin_elf (elf, cmd, scngrp)
result->mem_tail->remaining = result->mem_tail->size;
result->mem_tail->prev = NULL;
+ result->n_sections = IDX_last;
+ result->sectiondata = calloc (result->n_sections, sizeof (Dwarf_Section));
+ if (unlikely (result->sectiondata == NULL))
+ {
+ free (result);
+ __libdw_seterrno (DWARF_E_NOMEM);
+ return NULL;
+ }
+
if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR)
{
/* If the caller provides a section group we get the DWARF
diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c
index 2636c69..a2ee8d6 100644
--- a/libdw/dwarf_end.c
+++ b/libdw/dwarf_end.c
@@ -85,7 +85,7 @@ __libdw_free_zdata (Dwarf *dwarf)
{
size_t i;
- for (i = 0; i < IDX_last; ++i)
+ for (i = 0; i < dwarf->n_sections; ++i)
{
if (dwarf->sectiondata[i].gzipped)
free (dwarf->sectiondata[i].data);
@@ -125,6 +125,8 @@ dwarf_end (dwarf)
__libdw_free_zdata (dwarf);
+ free (dwarf->sectiondata);
+
/* Free the ELF descriptor if necessary. */
if (dwarf->free_elf)
elf_end (dwarf->elf);
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index b24ac0b..fee0bac 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -161,8 +161,11 @@ struct Dwarf
/* The underlying ELF file. */
Elf *elf;
+ /* The number of sections in SECTIONDATA. */
+ size_t n_sections;
+
/* The section data. */
- struct Dwarf_Section sectiondata[IDX_last];
+ struct Dwarf_Section *sectiondata;
/* True if the file has a byte order different from the host. */
bool other_byte_order;
--
1.7.7.6
11 years, 6 months
[PATCH 2/5] Make IDX_debug_types come last. In a subsequent patch we will put all .debug_types sections at the end the of the section array. This change arranges for them to appear sequentially.
by Tom Tromey
libdw/ChangeLog | 6 ++++++
libdw/dwarf_begin_elf.c | 6 +++---
libdw/libdwP.h | 2 +-
3 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 8a556ec..6fb5d8d 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,5 +1,11 @@
2012-03-20 Tom Tromey <tromey(a)redhat.com>
+ * libdwP.h (IDX_debug_types): Move just before IDX_last.
+ * dwarf_begin_elf.c (dwarf_scnnames): Move .debug_types to the
+ end.
+
+2012-03-20 Tom Tromey <tromey(a)redhat.com>
+
* libdwP.h (struct Dwarf_Section): New.
(Dwarf_Section): New typedef.
(struct Dwarf) [sectiondata]: Change type.
diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c
index f7ae8ab..e62ef07 100644
--- a/libdw/dwarf_begin_elf.c
+++ b/libdw/dwarf_begin_elf.c
@@ -1,5 +1,5 @@
/* Create descriptor from ELF descriptor for processing file.
- Copyright (C) 2002-2011 Red Hat, Inc.
+ Copyright (C) 2002-2012 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper(a)redhat.com>, 2002.
@@ -73,7 +73,6 @@
static const char dwarf_scnnames[IDX_last][17] =
{
[IDX_debug_info] = ".debug_info",
- [IDX_debug_types] = ".debug_types",
[IDX_debug_abbrev] = ".debug_abbrev",
[IDX_debug_aranges] = ".debug_aranges",
[IDX_debug_line] = ".debug_line",
@@ -82,7 +81,8 @@ static const char dwarf_scnnames[IDX_last][17] =
[IDX_debug_pubnames] = ".debug_pubnames",
[IDX_debug_str] = ".debug_str",
[IDX_debug_macinfo] = ".debug_macinfo",
- [IDX_debug_ranges] = ".debug_ranges"
+ [IDX_debug_ranges] = ".debug_ranges",
+ [IDX_debug_types] = ".debug_types"
};
#define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0]))
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 1505512..b24ac0b 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -83,7 +83,6 @@ struct loc_block_s
enum
{
IDX_debug_info = 0,
- IDX_debug_types,
IDX_debug_abbrev,
IDX_debug_aranges,
IDX_debug_line,
@@ -93,6 +92,7 @@ enum
IDX_debug_str,
IDX_debug_macinfo,
IDX_debug_ranges,
+ IDX_debug_types, /* Must be just before IDX_last */
IDX_last
};
--
1.7.7.6
11 years, 6 months