From patchwork Thu Dec 5 02:20:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 1204435 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-515186-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=golang.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="FnPOB00/"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=golang-org.20150623.gappssmtp.com header.i=@golang-org.20150623.gappssmtp.com header.b="EzQ3pwi2"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47SzwC53CDz9sNx for ; Thu, 5 Dec 2019 13:20:41 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; q= dns; s=default; b=eYy9le3SFIJc3O5V/q6YXWEB7EZKa7NKL4TQArbn2UhTug 6zz95JEC7lDBeKq7BIQJIXpIzdbEowmYHEX89dHRcrqgz9paNLL5Kpu4Wd+ixRkr McQn0UJFLuNz0fmZcV2iwBwJ1W8p2Q/SqDWv6z0OjW0STmbMF9SvhRqP1J1Ao= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; s= default; bh=WuadydvaBMy1jVh4Sx111GBnDXM=; b=FnPOB00/NQ8Dt8rjJxnJ V/Z88AGNJlDXRt9AqBo2m+lgH5HdR8PVcynQCXYpqv7wNB7/vLraizFhAoLlGanU +lqwLWzyrRzwU1SnKM6bkSI+mKb8akHHOsQhlOWPlOQjvYONAQt7JfLn00Apb/YA tcqmuADiObLK2lYu8dcvLVs= Received: (qmail 70070 invoked by alias); 5 Dec 2019 02:20:33 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 69982 invoked by uid 89); 5 Dec 2019 02:20:32 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-13.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=Simplify, libbacktrace, int32_t, HX-HELO:sk:mail-ed X-HELO: mail-ed1-f53.google.com Received: from mail-ed1-f53.google.com (HELO mail-ed1-f53.google.com) (209.85.208.53) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 05 Dec 2019 02:20:29 +0000 Received: by mail-ed1-f53.google.com with SMTP id m8so1223266edi.13 for ; Wed, 04 Dec 2019 18:20:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=golang-org.20150623.gappssmtp.com; s=20150623; h=mime-version:from:date:message-id:subject:to; bh=JVXDV2Pp71GU4oBQTo4+ltiah9+tQgzsG9TpyJGNPNM=; b=EzQ3pwi2d3PJJ7c25i/fJ5c273ZDBkk1NBSGi8JDDzVvuyEeIipcKwUDY55EeFLL7M uRwp8OWj/ohdATUWTQ8YvOTOSw6Yf7ouIbev35U7MoB05CONV/yjxoL0iaLfA/JvMo5Y AaOGqpdB3N1Rd+qIBkz4ryKQzYsck2w8Yltq+wEKGXa2lX0M4NOy2JKeRGvrEK1psupf EqvGvCcp4DOoOIeUvehMcHIexew0oyDyQz0MnO99oA5+08T/hKWPWeRt44/7ecVnb6TK EWISD6dWHHsl2vVCsu1yMfFI0pU1Q7TqTJ7cpZBzSU7rBjo/QJH3w0NXrbm9Q9sqnvJK mnfA== MIME-Version: 1.0 From: Ian Lance Taylor Date: Wed, 4 Dec 2019 18:20:15 -0800 Message-ID: Subject: libbacktrace patch committed: Simplify DWARF section handling To: gcc-patches This libbacktrace patch simplifies the DWARF section handling. This is in preparation for DWARF 5 support, as DWARF 5 requires us to read more sections. Bootstrapped and ran libbacktrace and Go tests on x86_64-pc-linux-gnu. Committed to mainline. Ian 2019-12-04 Ian Lance Taylor * internal.h (enum dwarf_section): Define. (struct dwarf_sections): Define. (backtrace_dwarf_add): Update declaration to replace specific section parameters with dwarf_sections parameter. * dwarf.c (struct dwarf_data): Replace specific section fields with dwarf_sections field. (read_attribute): Use dwarf_sections with altlink. (build_address_map): Replace specific section parameters with dwarf_sections parameter. Change all callers. (read_line_info): Use dwarf_sections with ddata. (read_referenced_name): Likewise. (add_function_ranges): Likewise. (read_function_entry): Likewise. (read_function_info): Likewise. (build_dwarf_data): Replace specific section parameters with dwarf_sections parameter. Change all callers. (backtrace_dwarf_add): Likewise. * elf.c (enum debug_section): Remove. (dwarf_section_names): Remove .zdebug names. (elf_add): Track zsections separately. Build dwarf_sections. * pecoff.c (enum debug_section): Remove. (struct debug_section_info): Remove data field. (coff_add): Build dwarf_sections. * xcoff.c (enum dwarf_section): Remove. Replace DWSECT_xxx references with DEBUG_xxx references. (xcoff_add): Build dwarf_sections. Index: dwarf.c =================================================================== --- dwarf.c (revision 278944) +++ dwarf.c (working copy) @@ -373,18 +373,8 @@ struct dwarf_data struct unit **units; /* Number of units in the list. */ size_t units_count; - /* The unparsed .debug_info section. */ - const unsigned char *dwarf_info; - size_t dwarf_info_size; - /* The unparsed .debug_line section. */ - const unsigned char *dwarf_line; - size_t dwarf_line_size; - /* The unparsed .debug_ranges section. */ - const unsigned char *dwarf_ranges; - size_t dwarf_ranges_size; - /* The unparsed .debug_str section. */ - const unsigned char *dwarf_str; - size_t dwarf_str_size; + /* The unparsed DWARF debug data. */ + struct dwarf_sections dwarf_sections; /* Whether the data is big-endian or not. */ int is_bigendian; /* A vector used for function addresses. We keep this here so that @@ -871,13 +861,14 @@ read_attribute (enum dwarf_form form, st val->encoding = ATTR_VAL_NONE; return 1; } - if (offset >= altlink->dwarf_str_size) + if (offset >= altlink->dwarf_sections.size[DEBUG_STR]) { dwarf_buf_error (buf, "DW_FORM_GNU_strp_alt out of range"); return 0; } val->encoding = ATTR_VAL_STRING; - val->u.string = (const char *) altlink->dwarf_str + offset; + val->u.string = + (const char *) altlink->dwarf_sections.data[DEBUG_STR] + offset; return 1; } default: @@ -1499,10 +1490,7 @@ find_address_ranges (struct backtrace_st static int build_address_map (struct backtrace_state *state, uintptr_t base_address, - const unsigned char *dwarf_info, size_t dwarf_info_size, - const unsigned char *dwarf_abbrev, size_t dwarf_abbrev_size, - const unsigned char *dwarf_ranges, size_t dwarf_ranges_size, - const unsigned char *dwarf_str, size_t dwarf_str_size, + const struct dwarf_sections *dwarf_sections, int is_bigendian, struct dwarf_data *altlink, backtrace_error_callback error_callback, void *data, struct unit_addrs_vector *addrs, @@ -1525,9 +1513,9 @@ build_address_map (struct backtrace_stat not sure why. */ info.name = ".debug_info"; - info.start = dwarf_info; - info.buf = dwarf_info; - info.left = dwarf_info_size; + info.start = dwarf_sections->data[DEBUG_INFO]; + info.buf = info.start; + info.left = dwarf_sections->size[DEBUG_INFO]; info.is_bigendian = is_bigendian; info.error_callback = error_callback; info.data = data; @@ -1583,7 +1571,9 @@ build_address_map (struct backtrace_stat memset (&u->abbrevs, 0, sizeof u->abbrevs); abbrev_offset = read_offset (&unit_buf, is_dwarf64); - if (!read_abbrevs (state, abbrev_offset, dwarf_abbrev, dwarf_abbrev_size, + if (!read_abbrevs (state, abbrev_offset, + dwarf_sections->data[DEBUG_ABBREV], + dwarf_sections->size[DEBUG_ABBREV], is_bigendian, error_callback, data, &u->abbrevs)) goto fail; @@ -1610,8 +1600,10 @@ build_address_map (struct backtrace_stat u->function_addrs_count = 0; if (!find_address_ranges (state, base_address, &unit_buf, - dwarf_str, dwarf_str_size, - dwarf_ranges, dwarf_ranges_size, + dwarf_sections->data[DEBUG_STR], + dwarf_sections->size[DEBUG_STR], + dwarf_sections->data[DEBUG_RANGES], + dwarf_sections->size[DEBUG_RANGES], is_bigendian, altlink, error_callback, data, u, addrs, &unit_tag)) goto fail; @@ -2089,16 +2081,16 @@ read_line_info (struct backtrace_state * memset (hdr, 0, sizeof *hdr); if (u->lineoff != (off_t) (size_t) u->lineoff - || (size_t) u->lineoff >= ddata->dwarf_line_size) + || (size_t) u->lineoff >= ddata->dwarf_sections.size[DEBUG_LINE]) { error_callback (data, "unit line offset out of range", 0); goto fail; } line_buf.name = ".debug_line"; - line_buf.start = ddata->dwarf_line; - line_buf.buf = ddata->dwarf_line + u->lineoff; - line_buf.left = ddata->dwarf_line_size - u->lineoff; + line_buf.start = ddata->dwarf_sections.data[DEBUG_LINE]; + line_buf.buf = ddata->dwarf_sections.data[DEBUG_LINE] + u->lineoff; + line_buf.left = ddata->dwarf_sections.size[DEBUG_LINE] - u->lineoff; line_buf.is_bigendian = ddata->is_bigendian; line_buf.error_callback = error_callback; line_buf.data = data; @@ -2241,7 +2233,7 @@ read_referenced_name (struct dwarf_data offset -= u->unit_data_offset; unit_buf.name = ".debug_info"; - unit_buf.start = ddata->dwarf_info; + unit_buf.start = ddata->dwarf_sections.data[DEBUG_INFO]; unit_buf.buf = u->unit_data + offset; unit_buf.left = u->unit_data_len - offset; unit_buf.is_bigendian = ddata->is_bigendian; @@ -2267,7 +2259,8 @@ read_referenced_name (struct dwarf_data if (!read_attribute (abbrev->attrs[i].form, &unit_buf, u->is_dwarf64, u->version, u->addrsize, - ddata->dwarf_str, ddata->dwarf_str_size, + ddata->dwarf_sections.data[DEBUG_STR], + ddata->dwarf_sections.size[DEBUG_STR], ddata->altlink, &val)) return NULL; @@ -2364,16 +2357,16 @@ add_function_ranges (struct backtrace_st { struct dwarf_buf ranges_buf; - if (ranges >= ddata->dwarf_ranges_size) + if (ranges >= ddata->dwarf_sections.size[DEBUG_RANGES]) { error_callback (data, "function ranges offset out of range", 0); return 0; } ranges_buf.name = ".debug_ranges"; - ranges_buf.start = ddata->dwarf_ranges; - ranges_buf.buf = ddata->dwarf_ranges + ranges; - ranges_buf.left = ddata->dwarf_ranges_size - ranges; + ranges_buf.start = ddata->dwarf_sections.data[DEBUG_RANGES]; + ranges_buf.buf = ddata->dwarf_sections.data[DEBUG_RANGES] + ranges; + ranges_buf.left = ddata->dwarf_sections.size[DEBUG_RANGES] - ranges; ranges_buf.is_bigendian = ddata->is_bigendian; ranges_buf.error_callback = error_callback; ranges_buf.data = data; @@ -2479,7 +2472,8 @@ read_function_entry (struct backtrace_st if (!read_attribute (abbrev->attrs[i].form, unit_buf, u->is_dwarf64, u->version, u->addrsize, - ddata->dwarf_str, ddata->dwarf_str_size, + ddata->dwarf_sections.data[DEBUG_STR], + ddata->dwarf_sections.size[DEBUG_STR], ddata->altlink, &val)) return 0; @@ -2698,7 +2692,7 @@ read_function_info (struct backtrace_sta } unit_buf.name = ".debug_info"; - unit_buf.start = ddata->dwarf_info; + unit_buf.start = ddata->dwarf_sections.data[DEBUG_INFO]; unit_buf.buf = u->unit_data; unit_buf.left = u->unit_data_len; unit_buf.is_bigendian = ddata->is_bigendian; @@ -3077,16 +3071,7 @@ dwarf_fileline (struct backtrace_state * static struct dwarf_data * build_dwarf_data (struct backtrace_state *state, uintptr_t base_address, - const unsigned char *dwarf_info, - size_t dwarf_info_size, - const unsigned char *dwarf_line, - size_t dwarf_line_size, - const unsigned char *dwarf_abbrev, - size_t dwarf_abbrev_size, - const unsigned char *dwarf_ranges, - size_t dwarf_ranges_size, - const unsigned char *dwarf_str, - size_t dwarf_str_size, + const struct dwarf_sections *dwarf_sections, int is_bigendian, struct dwarf_data *altlink, backtrace_error_callback error_callback, @@ -3100,11 +3085,9 @@ build_dwarf_data (struct backtrace_state size_t units_count; struct dwarf_data *fdata; - if (!build_address_map (state, base_address, dwarf_info, dwarf_info_size, - dwarf_abbrev, dwarf_abbrev_size, dwarf_ranges, - dwarf_ranges_size, dwarf_str, dwarf_str_size, - is_bigendian, altlink, error_callback, data, - &addrs_vec, &units_vec)) + if (!build_address_map (state, base_address, dwarf_sections, is_bigendian, + altlink, error_callback, data, &addrs_vec, + &units_vec)) return NULL; if (!backtrace_vector_release (state, &addrs_vec.vec, error_callback, data)) @@ -3132,14 +3115,7 @@ build_dwarf_data (struct backtrace_state fdata->addrs_count = addrs_count; fdata->units = units; fdata->units_count = units_count; - fdata->dwarf_info = dwarf_info; - fdata->dwarf_info_size = dwarf_info_size; - fdata->dwarf_line = dwarf_line; - fdata->dwarf_line_size = dwarf_line_size; - fdata->dwarf_ranges = dwarf_ranges; - fdata->dwarf_ranges_size = dwarf_ranges_size; - fdata->dwarf_str = dwarf_str; - fdata->dwarf_str_size = dwarf_str_size; + fdata->dwarf_sections = *dwarf_sections; fdata->is_bigendian = is_bigendian; memset (&fdata->fvec, 0, sizeof fdata->fvec); @@ -3153,16 +3129,7 @@ build_dwarf_data (struct backtrace_state int backtrace_dwarf_add (struct backtrace_state *state, uintptr_t base_address, - const unsigned char *dwarf_info, - size_t dwarf_info_size, - const unsigned char *dwarf_line, - size_t dwarf_line_size, - const unsigned char *dwarf_abbrev, - size_t dwarf_abbrev_size, - const unsigned char *dwarf_ranges, - size_t dwarf_ranges_size, - const unsigned char *dwarf_str, - size_t dwarf_str_size, + const struct dwarf_sections *dwarf_sections, int is_bigendian, struct dwarf_data *fileline_altlink, backtrace_error_callback error_callback, @@ -3171,10 +3138,7 @@ backtrace_dwarf_add (struct backtrace_st { struct dwarf_data *fdata; - fdata = build_dwarf_data (state, base_address, dwarf_info, dwarf_info_size, - dwarf_line, dwarf_line_size, dwarf_abbrev, - dwarf_abbrev_size, dwarf_ranges, dwarf_ranges_size, - dwarf_str, dwarf_str_size, is_bigendian, + fdata = build_dwarf_data (state, base_address, dwarf_sections, is_bigendian, fileline_altlink, error_callback, data); if (fdata == NULL) return 0; Index: elf.c =================================================================== --- elf.c (revision 278944) +++ elf.c (working copy) @@ -337,41 +337,15 @@ typedef struct #define ELFCOMPRESS_ZLIB 1 -/* An index of ELF sections we care about. */ +/* Names of sections, indexed by enum dwarf_section in internal.h. */ -enum debug_section -{ - DEBUG_INFO, - DEBUG_LINE, - DEBUG_ABBREV, - DEBUG_RANGES, - DEBUG_STR, - - /* The old style compressed sections. This list must correspond to - the list of normal debug sections. */ - ZDEBUG_INFO, - ZDEBUG_LINE, - ZDEBUG_ABBREV, - ZDEBUG_RANGES, - ZDEBUG_STR, - - DEBUG_MAX -}; - -/* Names of sections, indexed by enum elf_section. */ - -static const char * const debug_section_names[DEBUG_MAX] = +static const char * const dwarf_section_names[DEBUG_MAX] = { ".debug_info", ".debug_line", ".debug_abbrev", ".debug_ranges", ".debug_str", - ".zdebug_info", - ".zdebug_line", - ".zdebug_abbrev", - ".zdebug_ranges", - ".zdebug_str" }; /* Information we gather for the sections we care about. */ @@ -2661,6 +2635,7 @@ elf_add (struct backtrace_state *state, unsigned int dynsym_shndx; unsigned int i; struct debug_section_info sections[DEBUG_MAX]; + struct debug_section_info zsections[DEBUG_MAX]; struct backtrace_view symtab_view; int symtab_view_valid; struct backtrace_view strtab_view; @@ -2685,6 +2660,7 @@ elf_add (struct backtrace_state *state, unsigned int using_debug_view; uint16_t *zdebug_table; struct elf_ppc64_opd_data opd_data, *opd; + struct dwarf_sections dwarf_sections; if (!debuginfo) { @@ -2825,6 +2801,7 @@ elf_add (struct backtrace_state *state, dynsym_shndx = 0; memset (sections, 0, sizeof sections); + memset (zsections, 0, sizeof zsections); /* Look for the symbol table. */ for (i = 1; i < shnum; ++i) @@ -2852,7 +2829,7 @@ elf_add (struct backtrace_state *state, for (j = 0; j < (int) DEBUG_MAX; ++j) { - if (strcmp (name, debug_section_names[j]) == 0) + if (strcmp (name, dwarf_section_names[j]) == 0) { sections[j].offset = shdr->sh_offset; sections[j].size = shdr->sh_size; @@ -2861,6 +2838,19 @@ elf_add (struct backtrace_state *state, } } + if (name[0] == '.' && name[1] == 'z') + { + for (j = 0; j < (int) DEBUG_MAX; ++j) + { + if (strcmp (name + 2, dwarf_section_names[j] + 1) == 0) + { + zsections[j].offset = shdr->sh_offset; + zsections[j].size = shdr->sh_size; + break; + } + } + } + /* Read the build ID if present. This could check for any SHT_NOTE section with the right note name and type, but gdb looks for a specific section name. */ @@ -3132,7 +3122,8 @@ elf_add (struct backtrace_state *state, } /* Read all the debug sections in a single view, since they are - probably adjacent in the file. We never release this view. */ + probably adjacent in the file. If any of sections are + uncompressed, we never release this view. */ min_offset = 0; max_offset = 0; @@ -3140,13 +3131,22 @@ elf_add (struct backtrace_state *state, { off_t end; - if (sections[i].size == 0) - continue; - if (min_offset == 0 || sections[i].offset < min_offset) - min_offset = sections[i].offset; - end = sections[i].offset + sections[i].size; - if (end > max_offset) - max_offset = end; + if (sections[i].size != 0) + { + if (min_offset == 0 || sections[i].offset < min_offset) + min_offset = sections[i].offset; + end = sections[i].offset + sections[i].size; + if (end > max_offset) + max_offset = end; + } + if (zsections[i].size != 0) + { + if (min_offset == 0 || zsections[i].offset < min_offset) + min_offset = zsections[i].offset; + end = zsections[i].offset + zsections[i].size; + if (end > max_offset) + max_offset = end; + } } if (min_offset == 0 || max_offset == 0) { @@ -3175,20 +3175,22 @@ elf_add (struct backtrace_state *state, { sections[i].data = ((const unsigned char *) debug_view.data + (sections[i].offset - min_offset)); - if (i < ZDEBUG_INFO) - ++using_debug_view; + ++using_debug_view; } + + if (zsections[i].size == 0) + zsections[i].data = NULL; + else + zsections[i].data = ((const unsigned char *) debug_view.data + + (zsections[i].offset - min_offset)); } /* Uncompress the old format (--compress-debug-sections=zlib-gnu). */ zdebug_table = NULL; - for (i = 0; i < ZDEBUG_INFO; ++i) + for (i = 0; i < (int) DEBUG_MAX; ++i) { - struct debug_section_info *pz; - - pz = §ions[i + ZDEBUG_INFO - DEBUG_INFO]; - if (sections[i].size == 0 && pz->size > 0) + if (sections[i].size == 0 && zsections[i].size > 0) { unsigned char *uncompressed_data; size_t uncompressed_size; @@ -3204,7 +3206,8 @@ elf_add (struct backtrace_state *state, uncompressed_data = NULL; uncompressed_size = 0; - if (!elf_uncompress_zdebug (state, pz->data, pz->size, zdebug_table, + if (!elf_uncompress_zdebug (state, zsections[i].data, + zsections[i].size, zdebug_table, error_callback, data, &uncompressed_data, &uncompressed_size)) goto fail; @@ -3216,7 +3219,7 @@ elf_add (struct backtrace_state *state, /* Uncompress the official ELF format (--compress-debug-sections=zlib-gabi). */ - for (i = 0; i < ZDEBUG_INFO; ++i) + for (i = 0; i < (int) DEBUG_MAX; ++i) { unsigned char *uncompressed_data; size_t uncompressed_size; @@ -3256,17 +3259,13 @@ elf_add (struct backtrace_state *state, debug_view_valid = 0; } - if (!backtrace_dwarf_add (state, base_address, - sections[DEBUG_INFO].data, - sections[DEBUG_INFO].size, - sections[DEBUG_LINE].data, - sections[DEBUG_LINE].size, - sections[DEBUG_ABBREV].data, - sections[DEBUG_ABBREV].size, - sections[DEBUG_RANGES].data, - sections[DEBUG_RANGES].size, - sections[DEBUG_STR].data, - sections[DEBUG_STR].size, + for (i = 0; i < (int) DEBUG_MAX; ++i) + { + dwarf_sections.data[i] = sections[i].data; + dwarf_sections.size[i] = sections[i].size; + } + + if (!backtrace_dwarf_add (state, base_address, &dwarf_sections, ehdr.e_ident[EI_DATA] == ELFDATA2MSB, fileline_altlink, error_callback, data, fileline_fn, Index: internal.h =================================================================== --- internal.h (revision 278944) +++ internal.h (working copy) @@ -286,22 +286,36 @@ extern int backtrace_initialize (struct void *data, fileline *fileline_fn); +/* An enum for the DWARF sections we care about. */ + +enum dwarf_section +{ + DEBUG_INFO, + DEBUG_LINE, + DEBUG_ABBREV, + DEBUG_RANGES, + DEBUG_STR, + + DEBUG_MAX +}; + +/* Data for the DWARF sections we care about. */ + +struct dwarf_sections +{ + const unsigned char *data[DEBUG_MAX]; + size_t size[DEBUG_MAX]; +}; + +/* DWARF data read from a file, used for .gnu_debugaltlink. */ + struct dwarf_data; /* Add file/line information for a DWARF module. */ extern int backtrace_dwarf_add (struct backtrace_state *state, uintptr_t base_address, - const unsigned char* dwarf_info, - size_t dwarf_info_size, - const unsigned char *dwarf_line, - size_t dwarf_line_size, - const unsigned char *dwarf_abbrev, - size_t dwarf_abbrev_size, - const unsigned char *dwarf_ranges, - size_t dwarf_range_size, - const unsigned char *dwarf_str, - size_t dwarf_str_size, + const struct dwarf_sections *dwarf_sections, int is_bigendian, struct dwarf_data *fileline_altlink, backtrace_error_callback error_callback, Index: pecoff.c =================================================================== --- pecoff.c (revision 278944) +++ pecoff.c (working copy) @@ -133,19 +133,7 @@ typedef struct { uint16_t sc; } b_coff_internal_symbol; -/* An index of sections we care about. */ - -enum debug_section -{ - DEBUG_INFO, - DEBUG_LINE, - DEBUG_ABBREV, - DEBUG_RANGES, - DEBUG_STR, - DEBUG_MAX -}; - -/* Names of sections, indexed by enum debug_section. */ +/* Names of sections, indexed by enum dwarf_section in internal.h. */ static const char * const debug_section_names[DEBUG_MAX] = { @@ -164,8 +152,6 @@ struct debug_section_info off_t offset; /* Section size. */ size_t size; - /* Section contents, after read from file. */ - const unsigned char *data; }; /* Information we keep for an coff symbol. */ @@ -616,6 +602,7 @@ coff_add (struct backtrace_state *state, struct backtrace_view debug_view; int debug_view_valid; uintptr_t image_base; + struct dwarf_sections dwarf_sections; *found_sym = 0; *found_dwarf = 0; @@ -848,28 +835,20 @@ coff_add (struct backtrace_state *state, for (i = 0; i < (int) DEBUG_MAX; ++i) { - if (sections[i].size == 0) - sections[i].data = NULL; + size_t size = sections[i].size; + dwarf_sections.size[i] = size; + if (size == 0) + dwarf_sections.data[i] = NULL; else - sections[i].data = ((const unsigned char *) debug_view.data - + (sections[i].offset - min_offset)); + dwarf_sections.data[i] = ((const unsigned char *) debug_view.data + + (sections[i].offset - min_offset)); } - if (!backtrace_dwarf_add (state, /* base_address */ 0, - sections[DEBUG_INFO].data, - sections[DEBUG_INFO].size, - sections[DEBUG_LINE].data, - sections[DEBUG_LINE].size, - sections[DEBUG_ABBREV].data, - sections[DEBUG_ABBREV].size, - sections[DEBUG_RANGES].data, - sections[DEBUG_RANGES].size, - sections[DEBUG_STR].data, - sections[DEBUG_STR].size, - 0, /* FIXME */ - NULL, + if (!backtrace_dwarf_add (state, /* base_address */ 0, &dwarf_sections, + 0, /* FIXME: is_bigendian */ + NULL, /* altlink */ error_callback, data, fileline_fn, - NULL)) + NULL /* returned fileline_entry */)) goto fail; *found_dwarf = 1; Index: xcoff.c =================================================================== --- xcoff.c (revision 278944) +++ xcoff.c (working copy) @@ -387,18 +387,6 @@ struct xcoff_fileline_data uintptr_t base_address; }; -/* An index of DWARF sections we care about. */ - -enum dwarf_section -{ - DWSECT_INFO, - DWSECT_LINE, - DWSECT_ABBREV, - DWSECT_RANGES, - DWSECT_STR, - DWSECT_MAX -}; - /* Information we gather for the DWARF sections we care about. */ struct dwsect_info @@ -1100,7 +1088,7 @@ xcoff_add (struct backtrace_state *state off_t str_off; off_t min_offset; off_t max_offset; - struct dwsect_info dwsect[DWSECT_MAX]; + struct dwsect_info dwsect[DEBUG_MAX]; size_t sects_size; size_t syms_size; int32_t str_size; @@ -1111,6 +1099,7 @@ xcoff_add (struct backtrace_state *state int dwarf_view_valid; int magic_ok; int i; + struct dwarf_sections dwarf_sections; *found_sym = 0; @@ -1255,19 +1244,19 @@ xcoff_add (struct backtrace_state *state switch (sects[i].s_flags & 0xffff0000) { case SSUBTYP_DWINFO: - idx = DWSECT_INFO; + idx = DEBUG_INFO; break; case SSUBTYP_DWLINE: - idx = DWSECT_LINE; + idx = DEBUG_LINE; break; case SSUBTYP_DWABREV: - idx = DWSECT_ABBREV; + idx = DEBUG_ABBREV; break; case SSUBTYP_DWARNGE: - idx = DWSECT_RANGES; + idx = DEBUG_RANGES; break; case SSUBTYP_DWSTR: - idx = DWSECT_STR; + idx = DEBUG_STR; break; default: continue; @@ -1288,7 +1277,7 @@ xcoff_add (struct backtrace_state *state goto fail; dwarf_view_valid = 1; - for (i = 0; i < (int) DWSECT_MAX; ++i) + for (i = 0; i < (int) DEBUG_MAX; ++i) { if (dwsect[i].offset == 0) dwsect[i].data = NULL; @@ -1297,27 +1286,28 @@ xcoff_add (struct backtrace_state *state + (dwsect[i].offset - min_offset)); } - if (!backtrace_dwarf_add (state, 0, - dwsect[DWSECT_INFO].data, - dwsect[DWSECT_INFO].size, + dwarf_sections.data[DEBUG_INFO] = dwsect[DEBUG_INFO].data; + dwarf_sections.size[DEBUG_INFO] = dwsect[DEBUG_INFO].size; #if BACKTRACE_XCOFF_SIZE == 32 - /* XXX workaround for broken lineoff */ - dwsect[DWSECT_LINE].data - 4, + /* XXX workaround for broken lineoff */ + dwarf_sections.data[DEBUG_LINE] = dwsect[DEBUG_LINE].data - 4; #else - /* XXX workaround for broken lineoff */ - dwsect[DWSECT_LINE].data - 12, + /* XXX workaround for broken lineoff */ + dwarf_sections.data[DEBUG_LINE] = dwsect[DEBUG_LINE].data - 12; #endif - dwsect[DWSECT_LINE].size, - dwsect[DWSECT_ABBREV].data, - dwsect[DWSECT_ABBREV].size, - dwsect[DWSECT_RANGES].data, - dwsect[DWSECT_RANGES].size, - dwsect[DWSECT_STR].data, - dwsect[DWSECT_STR].size, + dwarf_sections.size[DEBUG_LINE] = dwsect[DEBUG_LINE].size; + dwarf_sections.data[DEBUG_ABBREV] = dwsect[DEBUG_ABBREV].data; + dwarf_sections.size[DEBUG_ABBREV] = dwsect[DEBUG_ABBREV].size; + dwarf_sections.data[DEBUG_RANGES] = dwsect[DEBUG_RANGES].data; + dwarf_sections.size[DEBUG_RANGES] = dwsect[DEBUG_RANGES].size; + dwarf_sections.data[DEBUG_STR] = dwsect[DEBUG_STR].data; + dwarf_sections.size[DEBUG_STR] = dwsect[DEBUG_STR].size; + + if (!backtrace_dwarf_add (state, 0, &dwarf_sections, 1, /* big endian */ - NULL, + NULL, /* altlink */ error_callback, data, fileline_fn, - NULL)) + NULL /* returned fileline_entry */)) goto fail; }