From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by sourceware.org (Postfix) with ESMTPS id 28D1B3870869 for ; Fri, 12 Feb 2021 19:32:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 28D1B3870869 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=tdevries@suse.de X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 48D71B8F7 for ; Fri, 12 Feb 2021 19:32:45 +0000 (UTC) Date: Fri, 12 Feb 2021 20:32:43 +0100 From: Tom de Vries To: binutils@sourceware.org Subject: [PATCH][binutils] Fix printing of .debug_addr Message-ID: <20210212193242.GA17627@delia> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.10.1 (2018-07-13) X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 12 Feb 2021 19:32:47 -0000 Hi, Consider this exec: ... $ clang -gdwarf-5 ./src/gdb/testsuite/gdb.dwarf2/fission-mix*.c ... When trying to print the dwarf, we run into unsupported forms: - 37 (0x25, DW_FORM_strx1) and - 27 (0x1b, DW_FORM_addrx) like this: ... $ readelf -w a.out> READELF readelf: Warning: Unrecognized form: 37 ... readelf: Warning: Unrecognized form: 27 ... readelf: Warning: Unable to load/parse the .debug_info section, so cannot \ interpret the .debug_addr section. ... With an enablement patch that adds support for: - DW_FORM_strx* alongside DW_FORM_GNU_str_index - DW_FORM_addrx* alongside DW_FORM_GNU_addr_index - DW_AT_addr_base alongside DW_AT_GNU_addr_base we are able to interpret the .debug_addr section, and get: ... Contents of the .debug_addr section: For compilation unit at offset 0xc7: Index Address 0: 000000000060102c 1: 00000000004004a0 2: 000800050000001c For compilation unit at offset 0x118: Index Address 0: 0000000000601030 1: 00000000004004c0 2: 00000000004004d0 ... The entry with index 2 in the first CU (000800050000001c) is actually not an entry, but the header of the next CU, which we can see with f.i. llvm-dwarfdump: ... Addr Section: \ length = 0x0000001c, version = 0x0005, addr_size = 0x08, seg_size = 0x00 ... Fix this in display_debug_addr, and add support for DW_AT_addr_base. OK for trunk? Thanks, - Tom [binutils] Fix printing of .debug_addr binutils/ChangeLog: 2021-02-12 Tom de Vries * dwarf.c (read_and_display_attr_value): Handle DW_AT_addr_base. (display_debug_addr): Handle dwarf-5 .debug_addr bits. --- binutils/dwarf.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/binutils/dwarf.c b/binutils/dwarf.c index e55a7daa8fe..d682bac35f9 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -2844,6 +2844,7 @@ read_and_display_attr_value (unsigned long attribute, break; case DW_AT_GNU_addr_base: + case DW_AT_addr_base: debug_info_p->addr_base = uvalue; break; @@ -7308,6 +7309,7 @@ display_debug_addr (struct dwarf_section *section, debug_addr_info [count]->addr_base = section->size; qsort (debug_addr_info, count, sizeof (debug_info *), comp_addr_base); + unsigned char *header = section->start; for (i = 0; i < count; i++) { unsigned int idx; @@ -7318,7 +7320,34 @@ display_debug_addr (struct dwarf_section *section, printf (_("\tIndex\tAddress\n")); entry = section->start + debug_addr_info [i]->addr_base; - end = section->start + debug_addr_info [i + 1]->addr_base; + if (debug_addr_info [i]->dwarf_version >= 5) + { + size_t header_size = entry - header; + if (header_size != 8 && header_size != 16) + return 0; + + unsigned char *curr_header = header; + + dwarf_vma length; + SAFE_BYTE_GET_AND_INC (length, curr_header, 4, entry); + if (length == 0xffffffff) + SAFE_BYTE_GET (length, curr_header, 8, entry); + end = curr_header + length; + + int version; + SAFE_BYTE_GET_AND_INC (version, curr_header, 2, entry); + if (version != 5) + warn (_("Unexpected version number in .debug_addr header: %#x\n"), version); + + SAFE_BYTE_GET_AND_INC (address_size, curr_header, 1, entry); + + int segment_selector_size; + SAFE_BYTE_GET_AND_INC (segment_selector_size, curr_header, 1, entry); + address_size += segment_selector_size; + } + else + end = section->start + debug_addr_info [i + 1]->addr_base; + header = end; idx = 0; while (entry < end) {