* [PATCH] readelf, libdw: Handle DWARF5 .debug_macro.
@ 2018-05-11 13:38 Mark Wielaard
2018-05-15 9:29 ` Mark Wielaard
0 siblings, 1 reply; 2+ messages in thread
From: Mark Wielaard @ 2018-05-11 13:38 UTC (permalink / raw)
To: elfutils-devel; +Cc: Mark Wielaard
Almost identical to GNU .debug_macro extension. Just accept and use
DW_AT_macros where we accept or use DW_AT_GNU_macros. And be a little
stricter in which FORMs we accept (this could have caused problems
with the GNU variant too). Deals with DW_FORM_strx[1234], but not yet
with imported macros through DW_MACRO_import_sup.
Signed-off-by: Mark Wielaard <mark@klomp.org>
---
libdw/ChangeLog | 8 ++++++
libdw/dwarf_formudata.c | 1 +
libdw/dwarf_getmacros.c | 42 +++++++++++++++++++++--------
src/ChangeLog | 5 ++++
src/readelf.c | 70 ++++++++++++++++++-------------------------------
5 files changed, 70 insertions(+), 56 deletions(-)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index efdd927..e66a1ec 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,11 @@
+2018-05-11 Mark Wielaard <mark@klomp.org>
+
+ * dwarf_formudata.c (dwarf_formudata): Handle DW_AT_macros as macptr.
+ * dwarf_getmacros.c (get_table_for_offset): Add DW_MACRO_define_sup,
+ DW_MACRO_undef_sup, DW_MACRO_import_sup, DW_MACRO_define_strx and
+ DW_MACRO_undef_strx. Add str_offsets_base_off to fake CU. Deal with
+ DW_AT_macros. Use libdw_valid_user_form.
+
2018-05-09 Mark Wielaard <mark@klomp.org>
* dwarf_formstring.c (__libdw_cu_str_off_base): Moved to...
diff --git a/libdw/dwarf_formudata.c b/libdw/dwarf_formudata.c
index 02c1694..62352ee 100644
--- a/libdw/dwarf_formudata.c
+++ b/libdw/dwarf_formudata.c
@@ -158,6 +158,7 @@ dwarf_formudata (Dwarf_Attribute *attr, Dwarf_Word *return_uval)
break;
case DW_AT_GNU_macros:
+ case DW_AT_macros:
/* macptr into .debug_macro */
if (__libdw_formptr (attr, IDX_debug_macro,
DWARF_E_NO_ENTRY, NULL,
diff --git a/libdw/dwarf_getmacros.c b/libdw/dwarf_getmacros.c
index c456051..fd92966 100644
--- a/libdw/dwarf_getmacros.c
+++ b/libdw/dwarf_getmacros.c
@@ -1,7 +1,6 @@
/* Get macro information.
- Copyright (C) 2002-2009, 2014 Red Hat, Inc.
+ Copyright (C) 2002-2009, 2014, 2017, 2018 Red Hat, Inc.
This file is part of elfutils.
- Written by Ulrich Drepper <drepper@redhat.com>, 2002.
This file is free software; you can redistribute it and/or modify
it under the terms of either
@@ -192,6 +191,8 @@ get_table_for_offset (Dwarf *dbg, Dwarf_Word macoff,
MACRO_PROTO (p_udata_str, DW_FORM_udata, DW_FORM_string);
MACRO_PROTO (p_udata_strp, DW_FORM_udata, DW_FORM_strp);
+ MACRO_PROTO (p_udata_strsup, DW_FORM_udata, DW_FORM_strp_sup);
+ MACRO_PROTO (p_udata_strx, DW_FORM_udata, DW_FORM_strx);
MACRO_PROTO (p_udata_udata, DW_FORM_udata, DW_FORM_udata);
MACRO_PROTO (p_secoffset, DW_FORM_sec_offset);
MACRO_PROTO (p_none);
@@ -205,10 +206,11 @@ get_table_for_offset (Dwarf *dbg, Dwarf_Word macoff,
[DW_MACRO_start_file - 1] = p_udata_udata,
[DW_MACRO_end_file - 1] = p_none,
[DW_MACRO_import - 1] = p_secoffset,
- /* When adding support for DWARF5 supplementary object files and
- indirect string tables also add support for DW_MACRO_define_sup,
- DW_MACRO_undef_sup, DW_MACRO_import_sup, DW_MACRO_define_strx
- and DW_MACRO_undef_strx. */
+ [DW_MACRO_define_sup - 1] = p_udata_strsup,
+ [DW_MACRO_undef_sup - 1] = p_udata_strsup,
+ [DW_MACRO_import_sup - 1] = p_secoffset, /* XXX - but in sup!. */
+ [DW_MACRO_define_strx - 1] = p_udata_strx,
+ [DW_MACRO_undef_strx - 1] = p_udata_strx,
};
if ((flags & 0x4) != 0)
@@ -357,12 +359,18 @@ read_macros (Dwarf *dbg, int sec_index,
/* A fake CU with bare minimum data to fool dwarf_formX into
doing the right thing with the attributes that we put out.
We pretend it is the same version as the actual table.
- Version 4 for the old GNU extension, version 5 for DWARF5. */
+ Version 4 for the old GNU extension, version 5 for DWARF5.
+ To handle DW_FORM_strx[1234] we set the .str_offsets_base
+ from the given CU.
+ XXX We will need to deal with DW_MACRO_import_sup and change
+ out the dbg somehow for the DW_FORM_sec_offset to make sense. */
Dwarf_CU fake_cu = {
.dbg = dbg,
.sec_idx = sec_index,
.version = table->version,
.offset_size = table->is_64bit ? 8 : 4,
+ .str_off_base = str_offsets_base_off (dbg, (cudie != NULL
+ ? cudie->cu: NULL)),
.startp = (void *) startp + offset,
.endp = (void *) endp,
};
@@ -385,14 +393,25 @@ read_macros (Dwarf *dbg, int sec_index,
for (Dwarf_Word i = 0; i < proto->nforms; ++i)
{
- /* We pretend this is a DW_AT_GNU_macros attribute so that
+ /* We pretend this is a DW_AT[_GNU]_macros attribute so that
DW_FORM_sec_offset forms get correctly interpreted as
- offset into .debug_macro. */
- attributes[i].code = DW_AT_GNU_macros;
+ offset into .debug_macro. XXX Deal with DW_MACRO_import_sup
+ (swap .dbg) for DW_FORM_sec_offset? */
+ attributes[i].code = (fake_cu.version == 4 ? DW_AT_GNU_macros
+ : DW_AT_macros);
attributes[i].form = proto->forms[i];
attributes[i].valp = (void *) readp;
attributes[i].cu = &fake_cu;
+ /* We don't want forms that aren't allowed because they could
+ read from the "abbrev" like DW_FORM_implicit_const. */
+ if (! libdw_valid_user_form (attributes[i].form))
+ {
+ __libdw_seterrno (DWARF_E_INVALID_DWARF);
+ free (attributesp);
+ return -1;
+ }
+
size_t len = __libdw_form_val_len (&fake_cu, proto->forms[i], readp);
if (unlikely (len == (size_t) -1))
{
@@ -562,7 +581,8 @@ dwarf_getmacros (Dwarf_Die *cudie, int (*callback) (Dwarf_Macro *, void *),
{
/* DW_AT_GNU_macros, DW_AT_macros */
Dwarf_Word macoff;
- if (get_offset_from (cudie, DW_AT_GNU_macros, &macoff) != 0)
+ if (get_offset_from (cudie, DW_AT_GNU_macros, &macoff) != 0
+ && get_offset_from (cudie, DW_AT_macros, &macoff) != 0)
return -1;
offset = gnu_macros_getmacros_off (cudie->cu->dbg, macoff,
callback, arg, offset, accept_0xff,
diff --git a/src/ChangeLog b/src/ChangeLog
index 4208b52..2a6210e 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2018-05-11 Mark Wielaard <mark@klomp.org>
+
+ * readelf.c (print_debug_macro_section): Use libdw_valid_user_form.
+ Use print_form_data for strx and sup strings.
+
2018-05-09 Mark Wielaard <mark@klomp.org>
* readelf.c (dwarf_line_content_description_string): New function.
diff --git a/src/readelf.c b/src/readelf.c
index ba4c1d7..967a813 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -8199,20 +8199,7 @@ print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
goto invalid_data;
unsigned int form = *readp++;
printf (" %s", dwarf_form_name (form));
- if (form != DW_FORM_data1
- && form != DW_FORM_data2
- && form != DW_FORM_data4
- && form != DW_FORM_data8
- && form != DW_FORM_sdata
- && form != DW_FORM_udata
- && form != DW_FORM_block
- && form != DW_FORM_block1
- && form != DW_FORM_block2
- && form != DW_FORM_block4
- && form != DW_FORM_flag
- && form != DW_FORM_string
- && form != DW_FORM_strp
- && form != DW_FORM_sec_offset)
+ if (! libdw_valid_user_form (form))
goto invalid_data;
args--;
if (args > 0)
@@ -8327,26 +8314,22 @@ print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
get_uleb128 (u128, readp, readendp);
if (readp + offset_len > readendp)
goto invalid_data;
- if (offset_len == 8)
- off = read_8ubyte_unaligned_inc (dbg, readp);
- else
- off = read_4ubyte_unaligned_inc (dbg, readp);
- // Needs support for reading from supplementary object file.
- printf ("%*s#define <str-at-0x%" PRIx64 ">, line %u (sup)\n",
- level, "", off, u128);
+ printf ("%*s#define ", level, "");
+ readp = print_form_data (dbg, DW_FORM_strp_sup,
+ readp, readendp, offset_len,
+ str_offsets_base);
+ printf (", line %u (sup)\n", u128);
break;
case DW_MACRO_undef_sup:
get_uleb128 (u128, readp, readendp);
if (readp + offset_len > readendp)
goto invalid_data;
- if (offset_len == 8)
- off = read_8ubyte_unaligned_inc (dbg, readp);
- else
- off = read_4ubyte_unaligned_inc (dbg, readp);
- // Needs support for reading from supplementary object file.
- printf ("%*s#undef <str-at-0x%" PRIx64 ">, line %u (sup)\n",
- level, "", off, u128);
+ printf ("%*s#undef ", level, "");
+ readp = print_form_data (dbg, DW_FORM_strp_sup,
+ readp, readendp, offset_len,
+ str_offsets_base);
+ printf (", line %u (sup)\n", u128);
break;
case DW_MACRO_import_sup:
@@ -8356,6 +8339,7 @@ print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
off = read_8ubyte_unaligned_inc (dbg, readp);
else
off = read_4ubyte_unaligned_inc (dbg, readp);
+ // XXX Needs support for reading from supplementary object file.
printf ("%*s#include offset 0x%" PRIx64 " (sup)\n",
level, "", off);
break;
@@ -8364,26 +8348,22 @@ print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
get_uleb128 (u128, readp, readendp);
if (readp + offset_len > readendp)
goto invalid_data;
- if (offset_len == 8)
- off = read_8ubyte_unaligned_inc (dbg, readp);
- else
- off = read_4ubyte_unaligned_inc (dbg, readp);
- // Needs support for reading indirect string offset table
- printf ("%*s#define <str-at-0x%" PRIx64 ">, line %u (strx)\n",
- level, "", off, u128);
+ printf ("%*s#define ", level, "");
+ readp = print_form_data (dbg, DW_FORM_strx,
+ readp, readendp, offset_len,
+ str_offsets_base);
+ printf (", line %u (strx)\n", u128);
break;
case DW_MACRO_undef_strx:
get_uleb128 (u128, readp, readendp);
if (readp + offset_len > readendp)
goto invalid_data;
- if (offset_len == 8)
- off = read_8ubyte_unaligned_inc (dbg, readp);
- else
- off = read_4ubyte_unaligned_inc (dbg, readp);
- // Needs support for reading indirect string offset table.
- printf ("%*s#undef <str-at-0x%" PRIx64 ">, line %u (strx)\n",
- level, "", off, u128);
+ printf ("%*s#undef ", level, "");
+ readp = print_form_data (dbg, DW_FORM_strx,
+ readp, readendp, offset_len,
+ str_offsets_base);
+ printf (", line %u (strx)\n", u128);
break;
default:
@@ -8399,11 +8379,11 @@ print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
// Just skip the arguments, we cannot really interpret them,
// but print as much as we can.
unsigned int args = *op_desc++;
- while (args > 0)
+ while (args > 0 && readp < readendp)
{
unsigned int form = *op_desc++;
- print_form_data (dbg, form, readp, readendp, offset_len,
- str_offsets_base);
+ readp = print_form_data (dbg, form, readp, readendp,
+ offset_len, str_offsets_base);
args--;
if (args > 0)
printf (", ");
--
1.8.3.1
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2018-05-15 9:29 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-11 13:38 [PATCH] readelf, libdw: Handle DWARF5 .debug_macro Mark Wielaard
2018-05-15 9:29 ` Mark Wielaard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).