summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2016-10-28 16:06:32 +0200
committerMark Wielaard <mjw@redhat.com>2016-10-28 16:06:32 +0200
commitee4f72eb84147b6b62ebb7a2ea3d2d758f92b71e (patch)
tree4b89b6acdc8f8df31d247be6f5ebc6744c731a19
parentcc6c357c323bf20982d1d9ee1ed6cc62215d3c89 (diff)
downloadelfutils-mjw/DWARF5.tar.gz
libdw: Add DW_MACRO constants and DW_MACRO_GNU compatibility defines.mjw/DWARF5
Accept version 5 .debug_macro format, which is identical to the GNU version 4 format. No real support yet for the new supplementary object file (sup) and indirect string references (strx). GCC doesn't generate them yet. readelf does recognize them, but doesn't try to decode them. dwarf_getmacros currently rejects the new formats. Signed-off-by: Mark Wielaard <mjw@redhat.com>
-rw-r--r--libdw/ChangeLog7
-rw-r--r--libdw/dwarf.h38
-rw-r--r--libdw/dwarf_getmacros.c27
-rw-r--r--src/ChangeLog9
-rw-r--r--src/readelf.c95
-rw-r--r--tests/ChangeLog4
-rw-r--r--tests/dwarf-getmacros.c10
7 files changed, 146 insertions, 44 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 7c4d0a69..e82b7856 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,10 @@
+2016-10-28 Mark Wielaard <mjw@redhat.com>
+
+ * dwarf.h: Add DW_MACRO_* and compat defines for DW_MACRO_GNU_*.
+ * dwarf_getmacros.c (get_table_for_offset): Accept either version
+ 4 or 5. Use DW_MACRO names instead of DW_MACRO_GNU names.
+ (read_macros): Use table version for fake_cu.
+
2016-10-25 Mark Wielaard <mjw@redhat.com>
* dwarf.h: Add DW_TAG_coarray_type, DW_TAG_generic_subrange,
diff --git a/libdw/dwarf.h b/libdw/dwarf.h
index 924dd350..b53ce0dd 100644
--- a/libdw/dwarf.h
+++ b/libdw/dwarf.h
@@ -712,20 +712,38 @@ enum
};
-/* DWARF debug_macro type encodings. GNU/DWARF5 extension. */
+/* DWARF debug_macro type encodings. */
enum
{
- DW_MACRO_GNU_define = 0x01,
- DW_MACRO_GNU_undef = 0x02,
- DW_MACRO_GNU_start_file = 0x03,
- DW_MACRO_GNU_end_file = 0x04,
- DW_MACRO_GNU_define_indirect = 0x05,
- DW_MACRO_GNU_undef_indirect = 0x06,
- DW_MACRO_GNU_transparent_include = 0x07,
- DW_MACRO_GNU_lo_user = 0xe0,
- DW_MACRO_GNU_hi_user = 0xff
+ DW_MACRO_define = 0x01,
+ DW_MACRO_undef = 0x02,
+ DW_MACRO_start_file = 0x03,
+ DW_MACRO_end_file = 0x04,
+ DW_MACRO_define_strp = 0x05,
+ DW_MACRO_undef_strp = 0x06,
+ DW_MACRO_import = 0x07,
+ DW_MACRO_define_sup = 0x08,
+ DW_MACRO_undef_sup = 0x09,
+ DW_MACRO_import_sup = 0x0a,
+ DW_MACRO_define_strx = 0x0b,
+ DW_MACRO_undef_strx = 0x0c,
+ DW_MACRO_lo_user = 0xe0,
+ DW_MACRO_hi_user = 0xff
};
+/* Old GNU extension names for DWARF5 debug_macro type encodings.
+ There are no equivalents for the supplementary object file (sup)
+ and indirect string references (strx). */
+#define DW_MACRO_GNU_define DW_MACRO_define
+#define DW_MACRO_GNU_undef DW_MACRO_undef
+#define DW_MACRO_GNU_start_file DW_MACRO_start_file
+#define DW_MACRO_GNU_end_file DW_MACRO_end_file
+#define DW_MACRO_GNU_define_indirect DW_MACRO_define_strp
+#define DW_MACRO_GNU_undef_indirect DW_MACRO_undef_strp
+#define DW_MACRO_GNU_transparent_include DW_MACRO_import
+#define DW_MACRO_GNU_lo_user DW_MACRO_lo_user
+#define DW_MACRO_GNU_hi_user DW_MACRO_hi_user
+
/* DWARF call frame instruction encodings. */
enum
diff --git a/libdw/dwarf_getmacros.c b/libdw/dwarf_getmacros.c
index eb505085..db6582b6 100644
--- a/libdw/dwarf_getmacros.c
+++ b/libdw/dwarf_getmacros.c
@@ -158,7 +158,7 @@ get_table_for_offset (Dwarf *dbg, Dwarf_Word macoff,
}
uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
- if (version != 4)
+ if (version != 4 && version != 5)
{
__libdw_seterrno (DWARF_E_INVALID_VERSION);
return NULL;
@@ -198,15 +198,17 @@ get_table_for_offset (Dwarf *dbg, Dwarf_Word macoff,
Dwarf_Macro_Op_Proto op_protos[255] =
{
- [DW_MACRO_GNU_define - 1] = p_udata_str,
- [DW_MACRO_GNU_undef - 1] = p_udata_str,
- [DW_MACRO_GNU_define_indirect - 1] = p_udata_strp,
- [DW_MACRO_GNU_undef_indirect - 1] = p_udata_strp,
- [DW_MACRO_GNU_start_file - 1] = p_udata_udata,
- [DW_MACRO_GNU_end_file - 1] = p_none,
- [DW_MACRO_GNU_transparent_include - 1] = p_secoffset,
- /* N.B. DW_MACRO_undef_indirectx, DW_MACRO_define_indirectx
- should be added when 130313.1 is supported. */
+ [DW_MACRO_define - 1] = p_udata_str,
+ [DW_MACRO_undef - 1] = p_udata_str,
+ [DW_MACRO_define_strp - 1] = p_udata_strp,
+ [DW_MACRO_undef_strp - 1] = p_udata_strp,
+ [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. */
};
if ((flags & 0x4) != 0)
@@ -354,10 +356,11 @@ 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 arbitrarily pretend it's version 4. */
+ We pretend it is the same version as the actual table.
+ Version 4 for the old GNU extension, version 5 for DWARF5. */
Dwarf_CU fake_cu = {
.dbg = dbg,
- .version = 4,
+ .version = table->version,
.offset_size = table->is_64bit ? 8 : 4,
.startp = (void *) startp + offset,
.endp = (void *) endp,
diff --git a/src/ChangeLog b/src/ChangeLog
index 68baa2e7..4476b5ee 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,4 +1,11 @@
-2015-10-11 Akihiko Odaki <akihiko.odaki.4i@stu.hosei.ac.jp>
+2016-10-28 Mark Wielaard <mjw@redhat.com>
+
+ * readelf.c (print_debug_macro_section): Accept either version 4 or
+ version 5. Use DW_MACRO names instead of DW_MACRO_GNU names. Add
+ minimal support for DW_MACRO_define_sup, DW_MACRO_undef_sup,
+ DW_MACRO_import_sup, DW_MACRO_define_strx and DW_MACRO_undef_strx.
+
+2016-10-11 Akihiko Odaki <akihiko.odaki.4i@stu.hosei.ac.jp>
* arlib.c: Remove system.h include, add libeu.h include.
* arlib2.c: Remove sys/param.h include.
diff --git a/src/readelf.c b/src/readelf.c
index 204aeecb..885276c5 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -7361,7 +7361,7 @@ print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
// Version 4 is the GNU extension for DWARF4. DWARF5 will use version
// 5 when it gets standardized.
- if (vers != 4)
+ if (vers != 4 && vers != 5)
{
printf (gettext (" unknown version, cannot parse section\n"));
return;
@@ -7385,7 +7385,7 @@ print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
line_offset);
}
- const unsigned char *vendor[DW_MACRO_GNU_hi_user - DW_MACRO_GNU_lo_user];
+ const unsigned char *vendor[DW_MACRO_hi_user - DW_MACRO_lo_user];
memset (vendor, 0, sizeof vendor);
if (flag & 0x04)
{
@@ -7402,12 +7402,12 @@ print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
goto invalid_data;
unsigned int opcode = *readp++;
printf (gettext (" [%" PRIx8 "]"), opcode);
- if (opcode < DW_MACRO_GNU_lo_user
- || opcode > DW_MACRO_GNU_hi_user)
+ if (opcode < DW_MACRO_lo_user
+ || opcode > DW_MACRO_hi_user)
goto invalid_data;
// Record the start of description for this vendor opcode.
// uleb128 nr args, 1 byte per arg form.
- vendor[opcode - DW_MACRO_GNU_lo_user] = readp;
+ vendor[opcode - DW_MACRO_lo_user] = readp;
if (readp + 1 > readendp)
goto invalid_data;
unsigned int args = *readp++;
@@ -7460,7 +7460,7 @@ print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
switch (opcode)
{
- case DW_MACRO_GNU_start_file:
+ case DW_MACRO_start_file:
get_uleb128 (u128, readp, readendp);
if (readp >= readendp)
goto invalid_data;
@@ -7490,12 +7490,12 @@ print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
++level;
break;
- case DW_MACRO_GNU_end_file:
+ case DW_MACRO_end_file:
--level;
printf ("%*send_file\n", level, "");
break;
- case DW_MACRO_GNU_define:
+ case DW_MACRO_define:
get_uleb128 (u128, readp, readendp);
endp = memchr (readp, '\0', readendp - readp);
if (endp == NULL)
@@ -7505,7 +7505,7 @@ print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
readp = endp + 1;
break;
- case DW_MACRO_GNU_undef:
+ case DW_MACRO_undef:
get_uleb128 (u128, readp, readendp);
endp = memchr (readp, '\0', readendp - readp);
if (endp == NULL)
@@ -7515,7 +7515,7 @@ print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
readp = endp + 1;
break;
- case DW_MACRO_GNU_define_indirect:
+ case DW_MACRO_define_strp:
get_uleb128 (u128, readp, readendp);
if (readp + offset_len > readendp)
goto invalid_data;
@@ -7527,7 +7527,7 @@ print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
level, "", dwarf_getstring (dbg, off, NULL), u128);
break;
- case DW_MACRO_GNU_undef_indirect:
+ case DW_MACRO_undef_strp:
get_uleb128 (u128, readp, readendp);
if (readp + offset_len > readendp)
goto invalid_data;
@@ -7539,7 +7539,7 @@ print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
level, "", dwarf_getstring (dbg, off, NULL), u128);
break;
- case DW_MACRO_GNU_transparent_include:
+ case DW_MACRO_import:
if (readp + offset_len > readendp)
goto invalid_data;
if (offset_len == 8)
@@ -7550,15 +7550,78 @@ print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
level, "", off);
break;
+ case DW_MACRO_define_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#define <str-at-0x%" PRIx64 ">, line %u (sup)\n",
+ level, "", off, 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);
+ break;
+
+ case DW_MACRO_import_sup:
+ 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);
+ printf ("%*s#include offset 0x%" PRIx64 " (sup)\n",
+ level, "", off);
+ break;
+
+ case DW_MACRO_define_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#define <str-at-0x%" PRIx64 ">, line %u (strx)\n",
+ level, "", off, 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);
+ break;
+
default:
printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
- if (opcode < DW_MACRO_GNU_lo_user
- || opcode > DW_MACRO_GNU_lo_user
- || vendor[opcode - DW_MACRO_GNU_lo_user] == NULL)
+ if (opcode < DW_MACRO_lo_user
+ || opcode > DW_MACRO_lo_user
+ || vendor[opcode - DW_MACRO_lo_user] == NULL)
goto invalid_data;
const unsigned char *op_desc;
- op_desc = vendor[opcode - DW_MACRO_GNU_lo_user];
+ op_desc = vendor[opcode - DW_MACRO_lo_user];
// Just skip the arguments, we cannot really interpret them,
// but print as much as we can.
diff --git a/tests/ChangeLog b/tests/ChangeLog
index bf5f7a4d..e96e51d2 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,5 +1,9 @@
2016-10-27 Mark Wielaard <mjw@redhat.com>
+ * dwarf-getmacros.c (mac): Use DW_MACRO names instead of DW_MACRO_GNU.
+
+2016-10-27 Mark Wielaard <mjw@redhat.com>
+
* dwarf_default_lower_bound.c: New test.
* Makefile.am (check_PROGRAMS): Add dwarf_default_lower_bound.
(TESTS): Likewise.
diff --git a/tests/dwarf-getmacros.c b/tests/dwarf-getmacros.c
index 92e093ca..ac70248d 100644
--- a/tests/dwarf-getmacros.c
+++ b/tests/dwarf-getmacros.c
@@ -38,7 +38,7 @@ mac (Dwarf_Macro *macro, void *dbg)
dwarf_macro_opcode (macro, &opcode);
switch (opcode)
{
- case DW_MACRO_GNU_transparent_include:
+ case DW_MACRO_import:
{
Dwarf_Attribute at;
int r = dwarf_macro_param (macro, 0, &at);
@@ -56,7 +56,7 @@ mac (Dwarf_Macro *macro, void *dbg)
break;
}
- case DW_MACRO_GNU_start_file:
+ case DW_MACRO_start_file:
{
Dwarf_Files *files;
size_t nfiles;
@@ -73,7 +73,7 @@ mac (Dwarf_Macro *macro, void *dbg)
break;
}
- case DW_MACRO_GNU_end_file:
+ case DW_MACRO_end_file:
{
--level;
printf ("%*s/file\n", level, "");
@@ -81,7 +81,7 @@ mac (Dwarf_Macro *macro, void *dbg)
}
case DW_MACINFO_define:
- case DW_MACRO_GNU_define_indirect:
+ case DW_MACRO_define_strp:
{
const char *value;
dwarf_macro_param2 (macro, NULL, &value);
@@ -90,7 +90,7 @@ mac (Dwarf_Macro *macro, void *dbg)
}
case DW_MACINFO_undef:
- case DW_MACRO_GNU_undef_indirect:
+ case DW_MACRO_undef_strp:
break;
default: