1From ec41dd75c866599fc03c390c6afb5736c159c0ff Mon Sep 17 00:00:00 2001 2From: Nick Clifton <nickc@redhat.com> 3Date: Tue, 21 Jun 2022 16:37:27 +0100 4Subject: [PATCH] Binutils support for dwarf-5 (location and range lists 5 related) 6 7 * dwarf.h (struct debug_info): Add rnglists_base field. 8 * dwarf.c (read_and_display_attr_value): Read attribute DW_AT_rnglists_base. 9 (display_debug_rnglists_list): While handling DW_RLE_base_addressx, 10 DW_RLE_startx_endx, DW_RLE_startx_length items, pass the proper parameter 11 value to fetch_indexed_addr(), i.e. fetch the proper entry in .debug_addr section. 12 (display_debug_ranges): Add rnglists_base to the .debug_rnglists base address. 13 (load_separate_debug_files): Load .debug_addr section, if exists. 14 15Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=ec41dd75c866599fc03c390c6afb5736c159c0ff] 16 17Signed-off-by: Pgowda <pgowda.cve@gmail.com> 18--- 19 binutils/ChangeLog | 10 +++++++++ 20 binutils/dwarf.c | 53 ++++++++++++++++++++++++++++++++++------------ 21 binutils/dwarf.h | 1 + 22 3 files changed, 51 insertions(+), 13 deletions(-) 23 24diff --git a/binutils/dwarf.c b/binutils/dwarf.c 25index cb2523af1f3..30b64ac68a8 100644 26--- a/binutils/dwarf.c 27+++ b/binutils/dwarf.c 28@@ -2812,7 +2812,12 @@ read_and_display_attr_value (unsigned lo 29 dwarf_vmatoa ("x", debug_info_p->cu_offset)); 30 debug_info_p->loclists_base = uvalue; 31 break; 32- 33+ case DW_AT_rnglists_base: 34+ if (debug_info_p->rnglists_base) 35+ warn (_("CU @ 0x%s has multiple rnglists_base values"), 36+ dwarf_vmatoa ("x", debug_info_p->cu_offset)); 37+ debug_info_p->rnglists_base = uvalue; 38+ break; 39 case DW_AT_frame_base: 40 have_frame_base = 1; 41 /* Fall through. */ 42@@ -3303,6 +3308,7 @@ read_and_display_attr_value (unsigned lo 43 /* Fall through. */ 44 case DW_AT_location: 45 case DW_AT_loclists_base: 46+ case DW_AT_rnglists_base: 47 case DW_AT_string_length: 48 case DW_AT_return_addr: 49 case DW_AT_data_member_location: 50@@ -3322,7 +3328,10 @@ read_and_display_attr_value (unsigned lo 51 && (form == DW_FORM_data4 || form == DW_FORM_data8)) 52 || form == DW_FORM_sec_offset 53 || form == DW_FORM_loclistx) 54- printf (_(" (location list)")); 55+ { 56+ if (attribute != DW_AT_rnglists_base) 57+ printf (_(" (location list)")); 58+ } 59 /* Fall through. */ 60 case DW_AT_allocated: 61 case DW_AT_associated: 62@@ -3809,6 +3818,7 @@ process_debug_info (struct dwarf_section 63 debug_information [unit].range_lists = NULL; 64 debug_information [unit].max_range_lists= 0; 65 debug_information [unit].num_range_lists = 0; 66+ debug_information [unit].rnglists_base = 0; 67 } 68 69 if (!do_loc && dwarf_start_die == 0) 70@@ -7932,9 +7942,16 @@ display_debug_rnglists_list (unsigned ch 71 unsigned char * finish, 72 unsigned int pointer_size, 73 dwarf_vma offset, 74- dwarf_vma base_address) 75+ dwarf_vma base_address, 76+ unsigned int offset_size) 77 { 78 unsigned char *next = start; 79+ unsigned int debug_addr_section_hdr_len; 80+ 81+ if (offset_size == 4) 82+ debug_addr_section_hdr_len = 8; 83+ else 84+ debug_addr_section_hdr_len = 16; 85 86 while (1) 87 { 88@@ -7964,20 +7981,24 @@ display_debug_rnglists_list (unsigned ch 89 READ_ULEB (base_address, start, finish); 90 print_dwarf_vma (base_address, pointer_size); 91 printf (_("(base address index) ")); 92- base_address = fetch_indexed_addr (base_address, pointer_size); 93+ base_address = fetch_indexed_addr ((base_address * pointer_size) 94+ + debug_addr_section_hdr_len, pointer_size); 95 print_dwarf_vma (base_address, pointer_size); 96 printf (_("(base address)\n")); 97 break; 98 case DW_RLE_startx_endx: 99 READ_ULEB (begin, start, finish); 100 READ_ULEB (end, start, finish); 101- begin = fetch_indexed_addr (begin, pointer_size); 102- end = fetch_indexed_addr (begin, pointer_size); 103+ begin = fetch_indexed_addr ((begin * pointer_size) 104+ + debug_addr_section_hdr_len, pointer_size); 105+ end = fetch_indexed_addr ((begin * pointer_size) 106+ + debug_addr_section_hdr_len, pointer_size); 107 break; 108 case DW_RLE_startx_length: 109 READ_ULEB (begin, start, finish); 110 READ_ULEB (length, start, finish); 111- begin = fetch_indexed_addr (begin, pointer_size); 112+ begin = fetch_indexed_addr ((begin * pointer_size) 113+ + debug_addr_section_hdr_len, pointer_size); 114 end = begin + length; 115 break; 116 case DW_RLE_offset_pair: 117@@ -8003,6 +8024,7 @@ display_debug_rnglists_list (unsigned ch 118 rlet = DW_RLE_end_of_list; 119 break; 120 } 121+ 122 if (rlet == DW_RLE_end_of_list) 123 break; 124 if (rlet == DW_RLE_base_address || rlet == DW_RLE_base_addressx) 125@@ -8043,6 +8065,7 @@ display_debug_ranges (struct dwarf_secti 126 /* Initialize it due to a false compiler warning. */ 127 unsigned char address_size = 0; 128 dwarf_vma last_offset = 0; 129+ unsigned int offset_size = 0; 130 131 if (bytes == 0) 132 { 133@@ -8054,10 +8077,10 @@ display_debug_ranges (struct dwarf_secti 134 135 if (is_rnglists) 136 { 137- dwarf_vma initial_length; 138- unsigned char segment_selector_size; 139- unsigned int offset_size, offset_entry_count; 140- unsigned short version; 141+ dwarf_vma initial_length; 142+ unsigned char segment_selector_size; 143+ unsigned int offset_entry_count; 144+ unsigned short version; 145 146 /* Get and check the length of the block. */ 147 SAFE_BYTE_GET_AND_INC (initial_length, start, 4, finish); 148@@ -8230,7 +8253,8 @@ display_debug_ranges (struct dwarf_secti 149 (unsigned long) offset, i); 150 continue; 151 } 152- next = section_begin + offset; 153+ 154+ next = section_begin + offset + debug_info_p->rnglists_base; 155 156 /* If multiple DWARF entities reference the same range then we will 157 have multiple entries in the `range_entries' list for the same 158@@ -8262,7 +8286,7 @@ display_debug_ranges (struct dwarf_secti 159 160 if (is_rnglists) 161 display_debug_rnglists_list 162- (start, finish, pointer_size, offset, base_address); 163+ (start, finish, pointer_size, offset, base_address, offset_size); 164 else 165 display_debug_ranges_list 166 (start, finish, pointer_size, offset, base_address); 167@@ -11911,6 +11935,9 @@ load_separate_debug_files (void * file, 168 && load_debug_section (abbrev, file) 169 && load_debug_section (info, file)) 170 { 171+ /* Load the .debug_addr section, if it exists. */ 172+ load_debug_section (debug_addr, file); 173+ 174 free_dwo_info (); 175 176 if (process_debug_info (& debug_displays[info].section, file, abbrev, 177diff --git a/binutils/dwarf.h b/binutils/dwarf.h 178index 040e674c6ce..8a89c08e7c2 100644 179--- a/binutils/dwarf.h 180+++ b/binutils/dwarf.h 181@@ -192,6 +192,7 @@ typedef struct 182 dwarf_vma * range_lists; 183 unsigned int num_range_lists; 184 unsigned int max_range_lists; 185+ dwarf_vma rnglists_base; 186 } 187 debug_info; 188 189