diff options
-rw-r--r-- | libdw/ChangeLog | 7 | ||||
-rw-r--r-- | libdw/dwarf.h | 38 | ||||
-rw-r--r-- | libdw/dwarf_getmacros.c | 27 | ||||
-rw-r--r-- | src/ChangeLog | 9 | ||||
-rw-r--r-- | src/readelf.c | 95 | ||||
-rw-r--r-- | tests/ChangeLog | 4 | ||||
-rw-r--r-- | tests/dwarf-getmacros.c | 10 |
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: |