From: Alexandre Oliva Date: Fri, 18 Aug 2017 11:37:29 +0000 (-0300) Subject: LVU: dump loclists with locviews X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0f54511373d5fd90d65a142413f2870de2a9fe3e;p=thirdparty%2Fbinutils-gdb.git LVU: dump loclists with locviews --- diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 297f426ed56..1e215d17a03 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -77,6 +77,10 @@ unsigned long dwarf_start_die; int dwarf_check = 0; +/* Convenient constant, to avoid having to cast -1 to dwarf_vma when + testing whether e.g. a locview list is present. */ +static const dwarf_vma vm1 = -1; + /* Collection of CU/TU section sets from .debug_cu_index and .debug_tu_index sections. For version 1 package files, each set is stored in SHNDX_POOL as a zero-terminated list of section indexes comprising one set of debug @@ -239,6 +243,26 @@ print_dwarf_vma (dwarf_vma value, unsigned num_bytes) printf ("%s ", dwarf_vmatoa_1 (NULL, value, num_bytes)); } +/* Print a view number in hexadecimal value, with the same width + print_dwarf_vma would have printed it with the same num_bytes. + Print blanks for zero view, unless force is nonzero. */ + +static void +print_dwarf_view (dwarf_vma value, unsigned num_bytes, int force) +{ + int len; + if (!num_bytes) + len = 4; + else + len = num_bytes * 2; + + assert (value == (unsigned long)value); + if (value || force) + printf ("v%0*lx ", len - 1, (unsigned long)value); + else + printf ("%*s", len + 1, ""); +} + /* Format a 64-bit value, given as two 32-bit values, in hex. For reentrancy, this uses a buffer provided by the caller. */ @@ -2012,6 +2036,7 @@ read_and_display_attr_value (unsigned long attribute, have_frame_base = 1; /* Fall through. */ case DW_AT_location: + case DW_AT_GNU_locviews: case DW_AT_string_length: case DW_AT_return_addr: case DW_AT_data_member_location: @@ -2041,6 +2066,9 @@ read_and_display_attr_value (unsigned long attribute, debug_info_p->loc_offsets = (dwarf_vma *) xcrealloc (debug_info_p->loc_offsets, lmax, sizeof (*debug_info_p->loc_offsets)); + debug_info_p->loc_views = (dwarf_vma *) + xcrealloc (debug_info_p->loc_views, + lmax, sizeof (*debug_info_p->loc_views)); debug_info_p->have_frame_base = (int *) xcrealloc (debug_info_p->have_frame_base, lmax, sizeof (*debug_info_p->have_frame_base)); @@ -2048,9 +2076,23 @@ read_and_display_attr_value (unsigned long attribute, } if (this_set != NULL) uvalue += this_set->section_offsets [DW_SECT_LOC]; - debug_info_p->loc_offsets [num] = uvalue; debug_info_p->have_frame_base [num] = have_frame_base; - debug_info_p->num_loc_offsets++; + if (attribute != DW_AT_GNU_locviews) + { + debug_info_p->loc_offsets [num] = uvalue; + debug_info_p->num_loc_offsets++; + assert (debug_info_p->num_loc_offsets + - debug_info_p->num_loc_views <= 1); + } + else + { + assert (debug_info_p->num_loc_views <= num); + num = debug_info_p->num_loc_views; + debug_info_p->loc_views [num] = uvalue; + debug_info_p->num_loc_views++; + assert (debug_info_p->num_loc_views + - debug_info_p->num_loc_offsets <= 1); + } } break; @@ -2858,21 +2900,22 @@ process_debug_info (struct dwarf_section *section, break; } + debug_info *debug_info_p = + (debug_information && unit < alloc_num_debug_info_entries) + ? debug_information + unit : NULL; + + assert (!debug_info_p + || (debug_info_p->num_loc_offsets + == debug_info_p->num_loc_views)); + for (attr = entry->first_attr; attr && attr->attribute; attr = attr->next) { - debug_info *arg; - if (! do_loc && do_printing) /* Show the offset from where the tag was extracted. */ printf (" <%lx>", (unsigned long)(tags - section_begin)); - if (debug_information && unit < alloc_num_debug_info_entries) - arg = debug_information + unit; - else - arg = NULL; - tags = read_and_display_attr (attr->attribute, attr->form, attr->implicit_const, @@ -2882,12 +2925,37 @@ process_debug_info (struct dwarf_section *section, compunit.cu_pointer_size, offset_size, compunit.cu_version, - arg, + debug_info_p, do_loc || ! do_printing, section, this_set); } + /* If a locview attribute appears before a location one, + make sure we don't associate it with an earlier + loclist. */ + if (debug_info_p) + switch (debug_info_p->num_loc_offsets - debug_info_p->num_loc_views) + { + case 1: + debug_info_p->loc_views [debug_info_p->num_loc_views] = vm1; + debug_info_p->num_loc_views++; + assert (debug_info_p->num_loc_views + == debug_info_p->num_loc_offsets); + break; + + case 0: + break; + + case -1: + warn(_("DIE has locviews without loclist\n")); + debug_info_p->num_loc_views--; + break; + + default: + assert (0); + } + if (entry->children) ++level; } @@ -5028,6 +5096,52 @@ is_max_address (dwarf_vma addr, unsigned int pointer_size) return ((addr & mask) == mask); } +/* Display a view pair list starting at *VSTART_PTR and ending at + VLISTEND within SECTION. */ + +static void +display_view_pair_list (struct dwarf_section *section, + unsigned char **vstart_ptr, + unsigned int debug_info_entry, + unsigned char *vlistend) +{ + unsigned char *vstart = *vstart_ptr; + unsigned char *section_end = section->start + section->size; + unsigned int pointer_size = debug_information [debug_info_entry].pointer_size; + + if (vlistend < section_end) + section_end = vlistend; + + putchar ('\n'); + + while (vstart < section_end) + { + dwarf_vma off = vstart - section->start; + dwarf_vma vbegin, vend; + + unsigned int bytes_read; + vbegin = read_uleb128 (vstart, &bytes_read, section_end); + vstart += bytes_read; + if (vstart == section_end) + { + vstart -= bytes_read; + break; + } + + vend = read_uleb128 (vstart, &bytes_read, section_end); + vstart += bytes_read; + + printf (" %8.8lx ", (unsigned long) off); + + print_dwarf_view (vbegin, pointer_size, 1); + print_dwarf_view (vend, pointer_size, 1); + printf (_("location view pair\n")); + } + + putchar ('\n'); + *vstart_ptr = vstart; +} + /* Display a location list from a normal (ie, non-dwo) .debug_loc section. */ static void @@ -5036,9 +5150,10 @@ display_loc_list (struct dwarf_section *section, unsigned int debug_info_entry, dwarf_vma offset, dwarf_vma base_address, + unsigned char **vstart_ptr, int has_frame_base) { - unsigned char *start = *start_ptr; + unsigned char *start = *start_ptr, *vstart = *vstart_ptr; unsigned char *section_end = section->start + section->size; unsigned long cu_offset; unsigned int pointer_size; @@ -5072,6 +5187,7 @@ display_loc_list (struct dwarf_section *section, while (1) { dwarf_vma off = offset + (start - *start_ptr); + dwarf_vma vbegin = vm1, vend = vm1; if (start + 2 * pointer_size > section_end) { @@ -5112,6 +5228,24 @@ display_loc_list (struct dwarf_section *section, continue; } + if (vstart) + { + unsigned int bytes_read; + + off = offset + (vstart - *start_ptr); + + vbegin = read_uleb128 (vstart, &bytes_read, section_end); + vstart += bytes_read; + print_dwarf_view (vbegin, pointer_size, 1); + + vend = read_uleb128 (vstart, &bytes_read, section_end); + vstart += bytes_read; + print_dwarf_view (vend, pointer_size, 1); + + printf (_("views at %8.8lx for:\n %*s "), + (unsigned long) off, 8, ""); + } + if (start + 2 > section_end) { warn (_("Location list starting at offset 0x%lx is not terminated.\n"), @@ -5143,9 +5277,9 @@ display_loc_list (struct dwarf_section *section, if (need_frame_base && !has_frame_base) printf (_(" [without DW_AT_frame_base]")); - if (begin == end) + if (begin == end && vbegin == vend) fputs (_(" (start == end)"), stdout); - else if (begin > end) + else if (begin > end || (begin == end && vbegin > vend)) fputs (_(" (start > end)"), stdout); putchar ('\n'); @@ -5154,6 +5288,7 @@ display_loc_list (struct dwarf_section *section, } *start_ptr = start; + *vstart_ptr = vstart; } /* Display a location list from a normal (ie, non-dwo) .debug_loclists section. */ @@ -5164,9 +5299,10 @@ display_loclists_list (struct dwarf_section *section, unsigned int debug_info_entry, dwarf_vma offset, dwarf_vma base_address, + unsigned char **vstart_ptr, int has_frame_base) { - unsigned char *start = *start_ptr; + unsigned char *start = *start_ptr, *vstart = *vstart_ptr; unsigned char *section_end = section->start + section->size; unsigned long cu_offset; unsigned int pointer_size; @@ -5175,8 +5311,8 @@ display_loclists_list (struct dwarf_section *section, unsigned int bytes_read; /* Initialize it due to a false compiler warning. */ - dwarf_vma begin = -1; - dwarf_vma end = -1; + dwarf_vma begin = -1, vbegin = -1; + dwarf_vma end = -1, vend = -1; dwarf_vma length; int need_frame_base; @@ -5216,6 +5352,22 @@ display_loclists_list (struct dwarf_section *section, SAFE_BYTE_GET_AND_INC (llet, start, 1, section_end); + if (vstart && llet == DW_LLE_offset_pair) + { + off = offset + (vstart - *start_ptr); + + vbegin = read_uleb128 (vstart, &bytes_read, section_end); + vstart += bytes_read; + print_dwarf_view (vbegin, pointer_size, 1); + + vend = read_uleb128 (vstart, &bytes_read, section_end); + vstart += bytes_read; + print_dwarf_view (vend, pointer_size, 1); + + printf (_("views at %8.8lx for:\n %*s "), + (unsigned long) off, 8, ""); + } + switch (llet) { case DW_LLE_end_of_list: @@ -5233,6 +5385,21 @@ display_loclists_list (struct dwarf_section *section, print_dwarf_vma (base_address, pointer_size); printf (_("(base address)\n")); break; +#ifdef DW_LLE_view_pair + case DW_LLE_view_pair: + if (vstart) + printf (_("View pair entry in loclist with locviews attribute\n")); + vbegin = read_uleb128 (start, &bytes_read, section_end); + start += bytes_read; + print_dwarf_view (vbegin, pointer_size, 1); + + vend = read_uleb128 (start, &bytes_read, section_end); + start += bytes_read; + print_dwarf_view (vend, pointer_size, 1); + + printf (_("views for:\n")); + continue; +#endif default: error (_("Invalid location list entry type %d\n"), llet); return; @@ -5267,17 +5434,22 @@ display_loclists_list (struct dwarf_section *section, if (need_frame_base && !has_frame_base) printf (_(" [without DW_AT_frame_base]")); - if (begin == end) + if (begin == end && vbegin == vend) fputs (_(" (start == end)"), stdout); - else if (begin > end) + else if (begin > end || (begin == end && vbegin > vend)) fputs (_(" (start > end)"), stdout); putchar ('\n'); start += length; + vbegin = vend = -1; } + if (vbegin != vm1 || vend != vm1) + printf (_("Trailing view pair not used in a range")); + *start_ptr = start; + *vstart_ptr = vstart; } /* Print a .debug_addr table index in decimal, surrounded by square brackets, @@ -5300,9 +5472,10 @@ display_loc_list_dwo (struct dwarf_section *section, unsigned char **start_ptr, unsigned int debug_info_entry, dwarf_vma offset, + unsigned char **vstart_ptr, int has_frame_base) { - unsigned char *start = *start_ptr; + unsigned char *start = *start_ptr, *vstart = *vstart_ptr; unsigned char *section_end = section->start + section->size; unsigned long cu_offset; unsigned int pointer_size; @@ -5345,17 +5518,47 @@ display_loc_list_dwo (struct dwarf_section *section, } SAFE_BYTE_GET_AND_INC (entry_type, start, 1, section_end); + + if (vstart) + switch (entry_type) + { + default: + break; + + case 2: + case 3: + case 4: + { + dwarf_vma view; + dwarf_vma off = offset + (vstart - *start_ptr); + + view = read_uleb128 (vstart, &bytes_read, section_end); + vstart += bytes_read; + print_dwarf_view (view, 8, 1); + + view = read_uleb128 (vstart, &bytes_read, section_end); + vstart += bytes_read; + print_dwarf_view (view, 8, 1); + + printf (_("views at %8.8lx for:\n %*s "), + (unsigned long) off, 8, ""); + + } + break; + } + switch (entry_type) { case 0: /* A terminating entry. */ *start_ptr = start; + *vstart_ptr = vstart; printf (_("\n")); return; case 1: /* A base-address entry. */ idx = read_uleb128 (start, &bytes_read, section_end); start += bytes_read; print_addr_index (idx, 8); - printf (" "); + printf ("%*s", 9 + (vstart ? 2 * 6 : 0), ""); printf (_("(base address selection entry)\n")); continue; case 2: /* A start/end entry. */ @@ -5382,6 +5585,7 @@ display_loc_list_dwo (struct dwarf_section *section, default: warn (_("Unknown location list entry type 0x%x.\n"), entry_type); *start_ptr = start; + *vstart_ptr = vstart; return; } @@ -5418,11 +5622,13 @@ display_loc_list_dwo (struct dwarf_section *section, } *start_ptr = start; + *vstart_ptr = vstart; } -/* Sort array of indexes in ascending order of loc_offsets[idx]. */ +/* Sort array of indexes in ascending order of loc_offsets[idx] and + loc_views. */ -static dwarf_vma *loc_offsets; +static dwarf_vma *loc_offsets, *loc_views; static int loc_offsets_compar (const void *ap, const void *bp) @@ -5430,23 +5636,33 @@ loc_offsets_compar (const void *ap, const void *bp) dwarf_vma a = loc_offsets[*(const unsigned int *) ap]; dwarf_vma b = loc_offsets[*(const unsigned int *) bp]; - return (a > b) - (b > a); + int ret = (a > b) - (b > a); + if (ret) + return ret; + + a = loc_views[*(const unsigned int *) ap]; + b = loc_views[*(const unsigned int *) bp]; + + ret = (a > b) - (b > a); + + return ret; } static int display_debug_loc (struct dwarf_section *section, void *file) { - unsigned char *start = section->start; + unsigned char *start = section->start, *vstart = NULL; unsigned long bytes; unsigned char *section_begin = start; unsigned int num_loc_list = 0; unsigned long last_offset = 0; + unsigned long last_view = 0; unsigned int first = 0; unsigned int i; unsigned int j; int seen_first_offset = 0; int locs_sorted = 1; - unsigned char *next; + unsigned char *next = start, *vnext = vstart; unsigned int *array = NULL; const char *suffix = strrchr (section->name, '.'); int is_dwo = 0; @@ -5534,6 +5750,7 @@ display_debug_loc (struct dwarf_section *section, void *file) { /* This is the first location list. */ last_offset = debug_information [i].loc_offsets [0]; + last_view = debug_information [i].loc_views [0]; first = i; seen_first_offset = 1; j = 1; @@ -5544,12 +5761,16 @@ display_debug_loc (struct dwarf_section *section, void *file) for (; j < num; j++) { if (last_offset > - debug_information [i].loc_offsets [j]) + debug_information [i].loc_offsets [j] + || (last_offset == + debug_information [i].loc_offsets [j] + && last_view > debug_information [i].loc_views [j])) { locs_sorted = 0; break; } last_offset = debug_information [i].loc_offsets [j]; + last_view = debug_information [i].loc_views [j]; } } } @@ -5558,7 +5779,8 @@ display_debug_loc (struct dwarf_section *section, void *file) error (_("No location lists in .debug_info section!\n")); if (debug_information [first].num_loc_offsets > 0 - && debug_information [first].loc_offsets [0] != expected_start) + && debug_information [first].loc_offsets [0] != expected_start + && debug_information [first].loc_views [0] != expected_start) warn (_("Location lists in %s section start at 0x%s\n"), section->name, dwarf_vmatoa ("x", debug_information [first].loc_offsets [0])); @@ -5573,7 +5795,7 @@ display_debug_loc (struct dwarf_section *section, void *file) seen_first_offset = 0; for (i = first; i < num_debug_info_entries; i++) { - dwarf_vma offset; + dwarf_vma offset, voffset; dwarf_vma base_address; unsigned int k; int has_frame_base; @@ -5583,24 +5805,42 @@ display_debug_loc (struct dwarf_section *section, void *file) for (k = 0; k < debug_information [i].num_loc_offsets; k++) array[k] = k; loc_offsets = debug_information [i].loc_offsets; + loc_views = debug_information [i].loc_views; qsort (array, debug_information [i].num_loc_offsets, sizeof (*array), loc_offsets_compar); } + int adjacent_view_loclists = 1; for (k = 0; k < debug_information [i].num_loc_offsets; k++) { j = locs_sorted ? k : array[k]; if (k - && debug_information [i].loc_offsets [locs_sorted + && (debug_information [i].loc_offsets [locs_sorted ? k - 1 : array [k - 1]] - == debug_information [i].loc_offsets [j]) + == debug_information [i].loc_offsets [j]) + && (debug_information [i].loc_views [locs_sorted + ? k - 1 : array [k - 1]] + == debug_information [i].loc_views [j])) continue; has_frame_base = debug_information [i].have_frame_base [j]; offset = debug_information [i].loc_offsets [j]; next = section_begin + offset; + voffset = debug_information [i].loc_views [j]; + if (voffset != vm1) + vnext = section_begin + voffset; + else + vnext = NULL; base_address = debug_information [i].base_address; - if (!seen_first_offset) + if (vnext && vnext < next) + { + vstart = vnext; + display_view_pair_list (section, &vstart, i, next); + if (start == vnext) + start = vstart; + } + + if (!seen_first_offset || !adjacent_view_loclists) seen_first_offset = 1; else { @@ -5614,6 +5854,7 @@ display_debug_loc (struct dwarf_section *section, void *file) (unsigned long) offset); } start = next; + vstart = vnext; if (offset >= bytes) { @@ -5622,14 +5863,21 @@ display_debug_loc (struct dwarf_section *section, void *file) continue; } + if (vnext && voffset >= bytes) + { + warn (_("View Offset 0x%lx is bigger than .debug_loc section size.\n"), + (unsigned long) voffset); + continue; + } + if (!is_loclists) { if (is_dwo) display_loc_list_dwo (section, &start, i, offset, - has_frame_base); + &vstart, has_frame_base); else display_loc_list (section, &start, i, offset, base_address, - has_frame_base); + &vstart, has_frame_base); } else { @@ -5637,8 +5885,25 @@ display_debug_loc (struct dwarf_section *section, void *file) warn (_("DWO is not yet supported.\n")); else display_loclists_list (section, &start, i, offset, base_address, - has_frame_base); + &vstart, has_frame_base); + } + + /* FIXME: this arrangement is quite simplistic. Nothing + requires locview lists to be adjacent to corresponding + loclists, and a single loclist could be augmented by + different locview lists, and vice-versa, unlikely as it + is that it would make sense to do so. Hopefully we'll + have view pair support built into loclists before we ever + need to address all these possibilities. */ + if (adjacent_view_loclists && vnext + && vnext != start && vstart != next) + { + adjacent_view_loclists = 0; + warn (_("Hole and overlap detection requires adjacent view lists and loclists.\n")); } + + if (vnext && vnext == start) + display_view_pair_list (section, &start, i, vstart); } } diff --git a/binutils/dwarf.h b/binutils/dwarf.h index 4d3330c2b9e..15719eef85c 100644 --- a/binutils/dwarf.h +++ b/binutils/dwarf.h @@ -170,9 +170,12 @@ typedef struct dwarf_vma ranges_base; /* This is an array of offsets to the location list table. */ dwarf_vma * loc_offsets; + /* This is an array of offsets to the location view table. */ + dwarf_vma * loc_views; int * have_frame_base; unsigned int num_loc_offsets; unsigned int max_loc_offsets; + unsigned int num_loc_views; /* List of .debug_ranges offsets seen in this .debug_info. */ dwarf_vma * range_lists; unsigned int num_range_lists; diff --git a/binutils/testsuite/binutils-all/locview-1.s b/binutils/testsuite/binutils-all/locview-1.s new file mode 100644 index 00000000000..dffda42f954 --- /dev/null +++ b/binutils/testsuite/binutils-all/locview-1.s @@ -0,0 +1,270 @@ + .text +.Ltext0: +.LFB0: + # locview.c:1 +.LM1: + # view -0 + # locview.c:2 +.LM2: + # view 1 +.LVL0: + # DEBUG i => 0 + # locview.c:3 +.LM3: + # view 2 + # DEBUG j => 0x1 + # locview.c:4 +.LM4: + # view 3 + # DEBUG i => 0x2 + # locview.c:5 +.LM5: + # view 4 + # DEBUG j => 0x3 + # locview.c:6 +.LM6: + # view 5 + # DEBUG k => 0x4 + # DEBUG l => 0x4 + # locview.c:7 +.LM7: + # view 6 + # DEBUG k => 0x5 + # DEBUG l => 0x5 + # locview.c:8 +.LM8: + # view 7 + # DEBUG k => 0x6 + # DEBUG l => 0x6 + # locview.c:9 +.LM9: + # view 8 + .byte 0 +.LFE0: +.Letext0: + + .section .debug_info,"",@progbits +.Ldebug_info0: +.LIbase: + .4byte .LIend - .LIstart # Length of Compilation Unit Info +.LIstart: + .2byte 0x4 # DWARF version number + .4byte .Ldebug_abbrev0 # Offset Into Abbrev. Section + .byte 0x4 # Pointer Size (in bytes) +.LIcu: + .uleb128 0x1 # (DIE (cu) DW_TAG_compile_unit) + .ascii "hand-crafted based on GCC output\0" + .byte 0xc # DW_AT_language + .ascii "locview.c\0" + .ascii "/tmp\0" + .4byte 0 # DW_AT_low_pc +.LIsubf: + .uleb128 0x2 # (DIE (subf) DW_TAG_subprogram) + .ascii "f\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (locview.c) + .byte 0x1 # DW_AT_decl_line + .4byte .LIint-.LIbase # DW_AT_type + .4byte .LFB0 # DW_AT_low_pc + .4byte .LFE0-.LFB0 # DW_AT_high_pc + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + # DW_AT_GNU_all_call_sites + .4byte .LIint - .LIbase # DW_AT_sibling +.LIvari: + .uleb128 0x3 # (DIE (vari) DW_TAG_variable) + .ascii "i\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (locview.c) + .byte 0x2 # DW_AT_decl_line + .4byte .LIint-.LIbase # DW_AT_type + .4byte .LLST0 # DW_AT_location + .4byte .LVUS0 # DW_AT_GNU_locviews +.LIvarj: + .uleb128 0x3 # (DIE (varf) DW_TAG_variable) + .ascii "j\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (locview.c) + .byte 0x3 # DW_AT_decl_line + .4byte .LIint - .LIbase # DW_AT_type + .4byte .LLST1 # DW_AT_location + .4byte .LVUS1 # DW_AT_GNU_locviews +.LIvark: + .uleb128 0x5 # (DIE (vark) DW_TAG_variable) + .ascii "k\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (locview.c) + .byte 0x6 # DW_AT_decl_line + .4byte .LIint - .LIbase # DW_AT_type + .4byte .LVUS2 # DW_AT_GNU_locviews + .4byte .LLST2 # DW_AT_location + .byte 0 # end of children of subf +.LIvarl: + .uleb128 0x5 # (DIE (varl) DW_TAG_variable) + .ascii "l\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (locview.c) + .byte 0x6 # DW_AT_decl_line + .4byte .LIint - .LIbase # DW_AT_type + .4byte .LVUS2 # DW_AT_GNU_locviews + .4byte .LLST2 # DW_AT_location + .byte 0 # end of children of subf + +.LIint: + .uleb128 0x4 # (DIE (int) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .ascii "int\0" # DW_AT_name + .byte 0 # end of children of cu +.LIend: + + .section .debug_abbrev,"",@progbits +.Ldebug_abbrev0: +.LAbrv1: + .uleb128 0x1 # (abbrev code) + .uleb128 0x11 # (TAG: DW_TAG_compile_unit) + .byte 0x1 # DW_children_yes + .uleb128 0x25 # (DW_AT_producer) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x13 # (DW_AT_language) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x1b # (DW_AT_comp_dir) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .byte 0 + .byte 0 +.LAbrv2: + .uleb128 0x2 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x6 # (DW_FORM_data4) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0x18 # (DW_FORM_exprloc) + .uleb128 0x2117 # (DW_AT_GNU_all_call_sites) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x1 # (DW_AT_sibling) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 +.LAbrv3: + .uleb128 0x3 # (abbrev code) + .uleb128 0x34 # (TAG: DW_TAG_variable) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x17 # (DW_FORM_sec_offset) + .uleb128 0x2137 # (DW_AT_GNU_locviews) + .uleb128 0x17 # (DW_FORM_sec_offset) + .byte 0 + .byte 0 +.LAbrv4: + .uleb128 0x4 # (abbrev code) + .uleb128 0x24 # (TAG: DW_TAG_base_type) + .byte 0 # DW_children_no + .uleb128 0xb # (DW_AT_byte_size) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3e # (DW_AT_encoding) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .byte 0 + .byte 0 +.LAbrv5: + .uleb128 0x5 # (abbrev code) + .uleb128 0x34 # (TAG: DW_TAG_variable) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2137 # (DW_AT_GNU_locviews) + .uleb128 0x17 # (DW_FORM_sec_offset) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x17 # (DW_FORM_sec_offset) + .byte 0 + .byte 0 + .byte 0 + + .section .debug_loc,"",@progbits +.Ldebug_loc0: +.LVUS0: + .uleb128 0x2 # View list begin (*.LVUS0) + .uleb128 0x4 # View list end (*.LVUS0) + .uleb128 0x4 # View list begin (*.LVUS0) + .uleb128 0 # View list end (*.LVUS0) +.LLST0: + .4byte .LVL0 # Location list begin address (*.LLST0) + .4byte .LVL0 # Location list end address (*.LLST0) + .2byte 0x2 # Location expression size + .byte 0x30 # DW_OP_lit0 + .byte 0x9f # DW_OP_stack_value + .4byte .LVL0 # Location list begin address (*.LLST0) + .4byte .LFE0 # Location list end address (*.LLST0) + .2byte 0x2 # Location expression size + .byte 0x32 # DW_OP_lit2 + .byte 0x9f # DW_OP_stack_value + .4byte 0 # Location list terminator begin (*.LLST0) + .4byte 0 # Location list terminator end (*.LLST0) +.LLST1: + .4byte .LVL0 # Location list begin address (*.LLST1) + .4byte .LVL0 # Location list end address (*.LLST1) + .2byte 0x2 # Location expression size + .byte 0x31 # DW_OP_lit1 + .byte 0x9f # DW_OP_stack_value + .4byte .LVL0 # Location list begin address (*.LLST1) + .4byte .LFE0 # Location list end address (*.LLST1) + .2byte 0x2 # Location expression size + .byte 0x33 # DW_OP_lit3 + .byte 0x9f # DW_OP_stack_value + .4byte 0 # Location list terminator begin (*.LLST1) + .4byte 0 # Location list terminator end (*.LLST1) +.LVUS1: + .uleb128 0x3 # View list begin (*.LVUS1) + .uleb128 0x5 # View list end (*.LVUS1) + .uleb128 0x5 # View list begin (*.LVUS1) + .uleb128 0 # View list end (*.LVUS1) +.LVUS2: + .uleb128 0x6 # View list begin (*.LVUS2) + .uleb128 0x7 # View list end (*.LVUS2) + .uleb128 0x7 # View list begin (*.LVUS2) + .uleb128 0x8 # View list end (*.LVUS2) + .uleb128 0x8 # View list begin (*.LVUS2) + .uleb128 0 # View list end (*.LVUS2) +.LLST2: + .4byte .LVL0 # Location list begin address (*.LLST2) + .4byte .LVL0 # Location list end address (*.LLST2) + .2byte 0x2 # Location expression size + .byte 0x34 # DW_OP_lit4 + .byte 0x9f # DW_OP_stack_value + .4byte .LVL0 # Location list begin address (*.LLST2) + .4byte .LVL0 # Location list end address (*.LLST2) + .2byte 0x2 # Location expression size + .byte 0x35 # DW_OP_lit5 + .byte 0x9f # DW_OP_stack_value + .4byte .LVL0 # Location list begin address (*.LLST2) + .4byte .LFE0 # Location list end address (*.LLST2) + .2byte 0x2 # Location expression size + .byte 0x36 # DW_OP_lit6 + .byte 0x9f # DW_OP_stack_value + .4byte 0 # Location list terminator begin (*.LLST2) + .4byte 0 # Location list terminator end (*.LLST2) diff --git a/binutils/testsuite/binutils-all/locview-2.s b/binutils/testsuite/binutils-all/locview-2.s new file mode 100644 index 00000000000..13ac21bbf85 --- /dev/null +++ b/binutils/testsuite/binutils-all/locview-2.s @@ -0,0 +1,335 @@ + .text +.Ltext0: +.LFB0: + # locview.c:1 +.LM1: + # view -0 + # locview.c:2 +.LM2: + # view 1 +.LVL0: + # DEBUG i => 0 + # locview.c:3 +.LM3: + # view 2 + # DEBUG j => 0x1 + # locview.c:4 +.LM4: + # view 3 + # DEBUG i => 0x2 + # locview.c:5 +.LM5: + # view 4 + # DEBUG j => 0x3 + # locview.c:6 +.LM6: + # view 5 + # DEBUG k => 0x4 + # DEBUG l => 0x4 + # locview.c:7 +.LM7: + # view 6 + # DEBUG k => 0x5 + # DEBUG l => 0x5 + # locview.c:8 +.LM8: + # view 7 + # DEBUG k => 0x6 + # DEBUG l => 0x6 + # locview.c:9 +.LM9: + # view 8 + .byte 0 +.LFE0: +.Letext0: + + .section .debug_info,"",@progbits +.Ldebug_info0: +.LIbase: + .4byte .LIend - .LIstart # Length of Compilation Unit Info +.LIstart: + .2byte 0x5 # DWARF version number + .byte 0x1 # DW_UT_compile + .byte 0x4 # Pointer Size (in bytes) + .4byte .Ldebug_abbrev0 # Offset Into Abbrev. Section +.LIcu: + .uleb128 0x2 # (DIE (cu) DW_TAG_compile_unit) + .ascii "hand-crafted based on GCC output\0" + .byte 0x1d # DW_AT_language + .ascii "locview.c\0" + .ascii "/tmp\0" + .4byte 0 # DW_AT_low_pc +.LIsubf: + .uleb128 0x3 # (DIE (subf) DW_TAG_subprogram) + .ascii "f\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (locview.c) + .byte 0x1 # DW_AT_decl_line + .4byte .LIint-.LIbase # DW_AT_type + .4byte .LFB0 # DW_AT_low_pc + .4byte .LFE0-.LFB0 # DW_AT_high_pc + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + # DW_AT_call_all_calls + .4byte .LIint - .LIbase # DW_AT_sibling +.LIvari: + .uleb128 0x1 # (DIE (vari) DW_TAG_variable) + .ascii "i\0" # DW_AT_name + # DW_AT_decl_file (1, locview.c) + .byte 0x2 # DW_AT_decl_line + .4byte .LIint - .LIbase # DW_AT_type + .4byte .LLST0 # DW_AT_location + .4byte .LVUS0 # DW_AT_GNU_locviews +.LIvarj: + .uleb128 0x1 # (DIE (varj) DW_TAG_variable) + .ascii "j\0" # DW_AT_name + # DW_AT_decl_file (1, locview.c) + .byte 0x3 # DW_AT_decl_line + .4byte .LIint - .LIbase # DW_AT_type + .4byte .LLST1 # DW_AT_location + .4byte .LVUS1 # DW_AT_GNU_locviews +.LIvark: + .uleb128 0x5 # (DIE (vark) DW_TAG_variable) + .ascii "k\0" # DW_AT_name + # DW_AT_decl_file (1, locview.c) + .byte 0x6 # DW_AT_decl_line + .4byte .LIint - .LIbase # DW_AT_type + .4byte .LVUS2 # DW_AT_GNU_locviews + .4byte .LLST2 # DW_AT_location +.LIvarl: + .uleb128 0x6 # (DIE (varl) DW_TAG_variable) + .ascii "l\0" # DW_AT_name + # DW_AT_decl_file (1, locview.c) + .byte 0x6 # DW_AT_decl_line + .4byte .LIint - .LIbase # DW_AT_type + .4byte .LLST3 # DW_AT_location + .byte 0 # end of children of DIE subf + +.LIint: + .uleb128 0x4 # (DIE (int) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .ascii "int\0" # DW_AT_name + .byte 0 # end of children of DIE cu +.LIend: + .section .debug_abbrev,"",@progbits +.Ldebug_abbrev0: +.LAbrv1: + .uleb128 0x1 # (abbrev code) + .uleb128 0x34 # (TAG: DW_TAG_variable) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0x21 # (DW_FORM_implicit_const) + .sleb128 1 # (locview.c) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x17 # (DW_FORM_sec_offset) + .uleb128 0x2137 # (DW_AT_GNU_locviews) + .uleb128 0x17 # (DW_FORM_sec_offset) + .byte 0 + .byte 0 +.LAbrv2: + .uleb128 0x2 # (abbrev code) + .uleb128 0x11 # (TAG: DW_TAG_compile_unit) + .byte 0x1 # DW_children_yes + .uleb128 0x25 # (DW_AT_producer) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x13 # (DW_AT_language) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x1b # (DW_AT_comp_dir) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .byte 0 + .byte 0 +.LAbrv3: + .uleb128 0x3 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x6 # (DW_FORM_data4) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0x18 # (DW_FORM_exprloc) + .uleb128 0x7a # (DW_AT_call_all_calls) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x1 # (DW_AT_sibling) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 +.LAbrv4: + .uleb128 0x4 # (abbrev code) + .uleb128 0x24 # (TAG: DW_TAG_base_type) + .byte 0 # DW_children_no + .uleb128 0xb # (DW_AT_byte_size) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3e # (DW_AT_encoding) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .byte 0 + .byte 0 +.LAbrv5: + .uleb128 0x5 # (abbrev code) + .uleb128 0x34 # (TAG: DW_TAG_variable) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0x21 # (DW_FORM_implicit_const) + .sleb128 1 # (locview.c) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2137 # (DW_AT_GNU_locviews) + .uleb128 0x17 # (DW_FORM_sec_offset) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x17 # (DW_FORM_sec_offset) + .byte 0 + .byte 0 +.LAbrv6: + .uleb128 0x6 # (abbrev code) + .uleb128 0x34 # (TAG: DW_TAG_variable) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0x21 # (DW_FORM_implicit_const) + .sleb128 1 # (locview.c) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x17 # (DW_FORM_sec_offset) + .byte 0 + .byte 0 + .byte 0 + + .section .debug_loclists,"",@progbits + .4byte .Ldebug_loc2-.Ldebug_loc1 # Length of Location Lists +.Ldebug_loc1: + .2byte 0x5 # DWARF version number + .byte 0x4 # Address Size + .byte 0 # Segment Size + .4byte 0 # Offset Entry Count +.Ldebug_loc0: +.LVUS0: + .uleb128 0x2 # View list begin (*.LVUS0) + .uleb128 0x4 # View list end (*.LVUS0) + .uleb128 0x4 # View list begin (*.LVUS0) + .uleb128 0 # View list end (*.LVUS0) +.LLST0: + .byte 0x6 # DW_LLE_base_address (*.LLST0) + .4byte .LVL0 # Base address (*.LLST0) + .byte 0x4 # DW_LLE_offset_pair (*.LLST0) + .uleb128 .LVL0-.LVL0 # Location list begin address (*.LLST0) + .uleb128 .LVL0-.LVL0 # Location list end address (*.LLST0) + .uleb128 0x2 # Location expression size + .byte 0x30 # DW_OP_lit0 + .byte 0x9f # DW_OP_stack_value + .byte 0x4 # DW_LLE_offset_pair (*.LLST0) + .uleb128 .LVL0-.LVL0 # Location list begin address (*.LLST0) + .uleb128 .LFE0-.LVL0 # Location list end address (*.LLST0) + .uleb128 0x2 # Location expression size + .byte 0x32 # DW_OP_lit2 + .byte 0x9f # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list (*.LLST0) +.LLST1: + .byte 0x6 # DW_LLE_base_address (*.LLST1) + .4byte .LVL0 # Base address (*.LLST1) + .byte 0x4 # DW_LLE_offset_pair (*.LLST1) + .uleb128 .LVL0-.LVL0 # Location list begin address (*.LLST1) + .uleb128 .LVL0-.LVL0 # Location list end address (*.LLST1) + .uleb128 0x2 # Location expression size + .byte 0x31 # DW_OP_lit1 + .byte 0x9f # DW_OP_stack_value + .byte 0x4 # DW_LLE_offset_pair (*.LLST1) + .uleb128 .LVL0-.LVL0 # Location list begin address (*.LLST1) + .uleb128 .LFE0-.LVL0 # Location list end address (*.LLST1) + .uleb128 0x2 # Location expression size + .byte 0x33 # DW_OP_lit3 + .byte 0x9f # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list (*.LLST1) +.LVUS1: + .uleb128 0x3 # View list begin (*.LVUS1) + .uleb128 0x5 # View list end (*.LVUS1) + .uleb128 0x5 # View list begin (*.LVUS1) + .uleb128 0 # View list end (*.LVUS1) +.LVUS2: + .uleb128 0x6 # View list begin (*.LVUS2) + .uleb128 0x7 # View list end (*.LVUS2) + .uleb128 0x7 # View list begin (*.LVUS2) + .uleb128 0x8 # View list end (*.LVUS2) + .uleb128 0x8 # View list begin (*.LVUS2) + .uleb128 0 # View list end (*.LVUS2) +.LLST2: + .byte 0x6 # DW_LLE_base_address (*.LLST2) + .4byte .LVL0 # Base address (*.LLST2) + .byte 0x4 # DW_LLE_offset_pair (*.LLST2) + .uleb128 .LVL0-.LVL0 # Location list begin address (*.LLST2) + .uleb128 .LVL0-.LVL0 # Location list end address (*.LLST2) + .uleb128 0x2 # Location expression size + .byte 0x34 # DW_OP_lit4 + .byte 0x9f # DW_OP_stack_value + .byte 0x4 # DW_LLE_offset_pair (*.LLST2) + .uleb128 .LVL0-.LVL0 # Location list begin address (*.LLST2) + .uleb128 .LVL0-.LVL0 # Location list end address (*.LLST2) + .uleb128 0x2 # Location expression size + .byte 0x35 # DW_OP_lit5 + .byte 0x9f # DW_OP_stack_value + .byte 0x4 # DW_LLE_offset_pair (*.LLST2) + .uleb128 .LVL0-.LVL0 # Location list begin address (*.LLST2) + .uleb128 .LFE0-.LVL0 # Location list end address (*.LLST2) + .uleb128 0x2 # Location expression size + .byte 0x36 # DW_OP_lit6 + .byte 0x9f # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list (*.LLST2) +.LLST3: + .byte 0x6 # DW_LLE_base_address (*.LLST3) + .4byte .LVL0 # Base address (*.LLST3) + .byte 0x9 # DW_LLE_view_pair (extension proposed for DWARF6) + .uleb128 0x6 # View list begin (*.LLST3) + .uleb128 0x7 # View list end (*.LVUS3) + .byte 0x4 # DW_LLE_offset_pair (*.LLST3) + .uleb128 .LVL0-.LVL0 # Location list begin address (*.LLST3) + .uleb128 .LVL0-.LVL0 # Location list end address (*.LLST3) + .uleb128 0x2 # Location expression size + .byte 0x34 # DW_OP_lit4 + .byte 0x9f # DW_OP_stack_value + .byte 0x9 # DW_LLE_view_pair + .uleb128 0x7 # View list begin (*.LLST3) + .uleb128 0x8 # View list end (*.LVUS3) + .byte 0x4 # DW_LLE_offset_pair (*.LLST3) + .uleb128 .LVL0-.LVL0 # Location list begin address (*.LLST3) + .uleb128 .LVL0-.LVL0 # Location list end address (*.LLST3) + .uleb128 0x2 # Location expression size + .byte 0x35 # DW_OP_lit5 + .byte 0x9f # DW_OP_stack_value + .byte 0x9 # DW_LLE_view_pair + .uleb128 0x8 # View list begin (*.LLST3) + .uleb128 0x0 # View list end (*.LVUS3) + .byte 0x4 # DW_LLE_offset_pair (*.LLST3) + .uleb128 .LVL0-.LVL0 # Location list begin address (*.LLST3) + .uleb128 .LFE0-.LVL0 # Location list end address (*.LLST3) + .uleb128 0x2 # Location expression size + .byte 0x36 # DW_OP_lit6 + .byte 0x9f # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list (*.LLST3) +.Ldebug_loc2: diff --git a/binutils/testsuite/binutils-all/readelf.exp b/binutils/testsuite/binutils-all/readelf.exp index d9e437d9677..5fbe8396a30 100644 --- a/binutils/testsuite/binutils-all/readelf.exp +++ b/binutils/testsuite/binutils-all/readelf.exp @@ -366,7 +366,7 @@ if {![binutils_assemble $srcdir/$subdir/version.s tmpdir/version.o]} then { if {![binutils_assemble $srcdir/$subdir/pr18374.s tmpdir/pr18374.o]} then { perror "could not assemble PR18374 test file" unresolved "readelf - failed to assemble" - fail "readelf --debug-loc" + fail "readelf --debug-dump=loc" } else { if ![is_remote host] { @@ -379,6 +379,37 @@ if {![binutils_assemble $srcdir/$subdir/pr18374.s tmpdir/pr18374.o]} then { } +# locview - Check dumping of location lists with location views. +if {![binutils_assemble $srcdir/$subdir/locview-1.s tmpdir/locview-1.o]} then { + perror "could not assemble locview-1 test file" + unresolved "readelf - failed to assemble" + fail "readelf --debug-dump=loc" +} else { + + if ![is_remote host] { + set tempfile tmpdir/locview-1.o + } else { + set tempfile [remote_download host tmpdir/locview-1.o] + } + + readelf_test --debug-dump=loc $tempfile readelf.locview-1 {} +} +if {![binutils_assemble $srcdir/$subdir/locview-2.s tmpdir/locview-2.o]} then { + perror "could not assemble locview-2 test file" + unresolved "readelf - failed to assemble" + fail "readelf --debug-dump=loc" +} else { + + if ![is_remote host] { + set tempfile tmpdir/locview-2.o + } else { + set tempfile [remote_download host tmpdir/locview-2.o] + } + + readelf_test --debug-dump=loc $tempfile readelf.locview-2 {} +} + + # Check that decompressed dumps work. if {![binutils_assemble $srcdir/$subdir/z.s tmpdir/z.o]} then { perror "could not assemble decompress dump test file" diff --git a/binutils/testsuite/binutils-all/readelf.locview-1 b/binutils/testsuite/binutils-all/readelf.locview-1 new file mode 100644 index 00000000000..614852015e7 --- /dev/null +++ b/binutils/testsuite/binutils-all/readelf.locview-1 @@ -0,0 +1,35 @@ +Contents of the .*ebug_loc section: + + Offset Begin End Expression + + 00000000 v0000002 v0000004 location view pair + 00000002 v0000004 v0000000 location view pair + + 00000004 v0000002 v0000004 views at 00000000 for: + 00000000 00000000 \(DW_OP_lit0; DW_OP_stack_value\) + 00000010 v0000004 v0000000 views at 00000002 for: + 00000000 00000001 \(DW_OP_lit2; DW_OP_stack_value\) + 0000001c + 00000024 v0000003 v0000005 views at 00000044 for: + 00000000 00000000 \(DW_OP_lit1; DW_OP_stack_value\) + 00000030 v0000005 v0000000 views at 00000046 for: + 00000000 00000001 \(DW_OP_lit3; DW_OP_stack_value\) + 0000003c + + 00000044 v0000003 v0000005 location view pair + 00000046 v0000005 v0000000 location view pair + + + 00000048 v0000006 v0000007 location view pair + 0000004a v0000007 v0000008 location view pair + 0000004c v0000008 v0000000 location view pair + + 0000004e v0000006 v0000007 views at 00000048 for: + 00000000 00000000 \(DW_OP_lit4; DW_OP_stack_value\) + 0000005a v0000007 v0000008 views at 0000004a for: + 00000000 00000000 \(DW_OP_lit5; DW_OP_stack_value\) + 00000066 v0000008 v0000000 views at 0000004c for: + 00000000 00000001 \(DW_OP_lit6; DW_OP_stack_value\) + 00000072 + +#pass diff --git a/binutils/testsuite/binutils-all/readelf.locview-2 b/binutils/testsuite/binutils-all/readelf.locview-2 new file mode 100644 index 00000000000..20437f2aa67 --- /dev/null +++ b/binutils/testsuite/binutils-all/readelf.locview-2 @@ -0,0 +1,46 @@ +Contents of the .*ebug_loclists section: + + Offset Begin End Expression + + 0000000c v0000002 v0000004 location view pair + 0000000e v0000004 v0000000 location view pair + + 00000010 00000000 \(base address\) + 00000015 v0000002 v0000004 views at 0000000c for: + 00000000 00000000 \(DW_OP_lit0; DW_OP_stack_value\) + 0000001b v0000004 v0000000 views at 0000000e for: + 00000000 00000001 \(DW_OP_lit2; DW_OP_stack_value\) + 00000021 + 00000022 00000000 \(base address\) + 00000027 v0000003 v0000005 views at 00000034 for: + 00000000 00000000 \(DW_OP_lit1; DW_OP_stack_value\) + 0000002d v0000005 v0000000 views at 00000036 for: + 00000000 00000001 \(DW_OP_lit3; DW_OP_stack_value\) + 00000033 + + 00000034 v0000003 v0000005 location view pair + 00000036 v0000005 v0000000 location view pair + + + 00000038 v0000006 v0000007 location view pair + 0000003a v0000007 v0000008 location view pair + 0000003c v0000008 v0000000 location view pair + + 0000003e 00000000 \(base address\) + 00000043 v0000006 v0000007 views at 00000038 for: + 00000000 00000000 \(DW_OP_lit4; DW_OP_stack_value\) + 00000049 v0000007 v0000008 views at 0000003a for: + 00000000 00000000 \(DW_OP_lit5; DW_OP_stack_value\) + 0000004f v0000008 v0000000 views at 0000003c for: + 00000000 00000001 \(DW_OP_lit6; DW_OP_stack_value\) + 00000055 + 00000056 00000000 \(base address\) + 0000005b v0000006 v0000007 views for: + 0000005e 00000000 00000000 \(DW_OP_lit4; DW_OP_stack_value\) + 00000064 v0000007 v0000008 views for: + 00000067 00000000 00000000 \(DW_OP_lit5; DW_OP_stack_value\) + 0000006d v0000008 v0000000 views for: + 00000070 00000000 00000001 \(DW_OP_lit6; DW_OP_stack_value\) + 00000076 + +#pass diff --git a/include/dwarf2.def b/include/dwarf2.def index a91e9439cd8..1d6d13bc45f 100644 --- a/include/dwarf2.def +++ b/include/dwarf2.def @@ -443,6 +443,8 @@ DW_AT (DW_AT_GNU_pubtypes, 0x2135) /* Attribute for discriminator. See http://gcc.gnu.org/wiki/Discriminator */ DW_AT (DW_AT_GNU_discriminator, 0x2136) +DW_AT (DW_AT_GNU_locviews, 0x2137) +DW_AT (DW_AT_GNU_entry_view, 0x2138) /* VMS extensions. */ DW_AT (DW_AT_VMS_rtnbeg_pd_address, 0x2201) /* GNAT extensions. */ diff --git a/include/dwarf2.h b/include/dwarf2.h index 14b6f22e39e..c6d410e32e4 100644 --- a/include/dwarf2.h +++ b/include/dwarf2.h @@ -296,6 +296,14 @@ enum dwarf_location_list_entry_type DW_LLE_start_end = 0x07, DW_LLE_start_length = 0x08, + /* + has the proposal for now; only available to list members. + + A (possibly updated) copy of the proposal is available at + . */ + DW_LLE_GNU_view_pair = 0x09, +#define DW_LLE_view_pair DW_LLE_GNU_view_pair + /* Former extension for Fission. See http://gcc.gnu.org/wiki/DebugFission. */ DW_LLE_GNU_end_of_list_entry = 0x00,