From patchwork Thu Apr 27 18:31:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Blaikie X-Patchwork-Id: 20184 Received: (qmail 75062 invoked by alias); 27 Apr 2017 18:31:12 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 75043 invoked by uid 89); 27 Apr 2017 18:31:11 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-yw0-f176.google.com Received: from mail-yw0-f176.google.com (HELO mail-yw0-f176.google.com) (209.85.161.176) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 27 Apr 2017 18:31:09 +0000 Received: by mail-yw0-f176.google.com with SMTP id u70so20385044ywe.2 for ; Thu, 27 Apr 2017 11:31:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=Nd2sUf7jttZFlhgUG1XCpkrMJqYmIpA5TsJSqbs+gfo=; b=gJn79/xlecaXMvJPQoovFW/4SG/DlENSsXAw++Ni+Vm+xpHoXUT3pwXcd1TiA02gcn 3bADIUk4XnurQwezxSKd4Yv6T9awI+Lgg10nLEtI0kPcyzB/UtZDjxPEZbITD77Ob189 PrqaR1u+3LNqIz0WdnYRKh+yXbguFoDEN8K5cWUyMtpydLyyIuIVijx/Up2I6PvgT9MI PYhmSP4hJTjFLDGNv/mz+OPg75HvmVBP5C3Iw2FDxwUUX6l6lbfWHTkk0auGEjo/RWpb OsY5NZUiF94UKWU1WGUEDb/Ek1GAzcQDSiYx5nPqwe07Bu8xEBImZRmtKxZSnQgIYn50 JKbw== X-Gm-Message-State: AN3rC/6LmKnFlSuxI9UAghdFnKomuwWxb8KbXsmWU0Q68UjUV5kB4YiJ 92fk26TDK5ALMOYiJLF68B+6CkNDYCu+Ias= X-Received: by 10.13.199.7 with SMTP id j7mr5523784ywd.287.1493317869585; Thu, 27 Apr 2017 11:31:09 -0700 (PDT) MIME-Version: 1.0 Received: by 10.83.50.206 with HTTP; Thu, 27 Apr 2017 11:31:09 -0700 (PDT) From: David Blaikie Date: Thu, 27 Apr 2017 11:31:09 -0700 Message-ID: Subject: Support multiple CUs in a single DWO file To: gdb-patches X-IsSubscribed: yes With work on ThinLTO (a form of partial cross-file optimization) in LLVM I've been looking at support for Fission/Split DWARF in this scenario. Basically it seems like the best representation for LTO (Thin (small clusters of objects) and full (whole libraries/programs in a single optimization/object file step)) is to produce a .dwo file that matches the .o file granularity, but that means multiple CUs in that .o file (because it represents the merging of multiple source files) So I'd like to contribute patches to GDB to support this - the first one I've attached (though it still lacks a test case - open to suggestions, but I can probably figure it out on my own - just wanted to get some feedback on the general direction & start some conversation sooner rather than later) addresses the first error messages about "multiple CUs in a DWO" and "cannot find DWO CU" by keeping a map of CU signatures, the same as there's a map of TU signatures. Does this seem like a reasonable thing to support? Is this the right way to go about doing it? [The big thing I'm trying to do after this that seems more difficult & I'd love to discuss - is supporting DW_FORM_ref_addr in these situations. This comes up when there's cross-CU inlining (a large part of the point of LTO-like situations) and an inlined_subroutine in one CU needs to refer to an abstract_origin subprogram in another CU. Currently the resolution for finding these CUs, etc, isn't quite right for Fission] diff --git gdb/dwarf2read.c gdb/dwarf2read.c index b58d0fc16e..29eb5a14b2 100644 --- gdb/dwarf2read.c +++ gdb/dwarf2read.c @@ -852,12 +852,9 @@ struct dwo_file sections (for lack of a better name). */ struct dwo_sections sections; - /* The CU in the file. - We only support one because having more than one requires hacking the - dwo_name of each to match, which is highly unlikely to happen. - Doing this means all TUs can share comp_dir: We also assume that - DW_AT_comp_dir across all TUs in a DWO file will be identical. */ - struct dwo_unit *cu; + /* The CUs in the file. + Each element is a struct dwo_unit. */ + htab_t cus; /* Table of TUs in the file. Each element is a struct dwo_unit. */ @@ -9702,72 +9699,75 @@ create_dwo_cu_reader (const struct die_reader_specs *reader, hex_string (dwo_unit->signature)); } -/* Create the dwo_unit for the lone CU in DWO_FILE. - Note: This function processes DWO files only, not DWP files. */ - -static struct dwo_unit * -create_dwo_cu (struct dwo_file *dwo_file) +static void create_cus_hash_table (struct dwo_file &dwo_file, + dwarf2_section_info §ion, + htab_t &cus_htab) { struct objfile *objfile = dwarf2_per_objfile->objfile; - struct dwarf2_section_info *section = &dwo_file->sections.info; + const struct dwarf2_section_info *abbrev_section = &dwo_file.sections.abbrev; const gdb_byte *info_ptr, *end_ptr; - struct create_dwo_cu_data create_dwo_cu_data; - struct dwo_unit *dwo_unit; - dwarf2_read_section (objfile, section); - info_ptr = section->buffer; + dwarf2_read_section (objfile, §ion); + info_ptr = section.buffer; if (info_ptr == NULL) - return NULL; + return; if (dwarf_read_debug) { fprintf_unfiltered (gdb_stdlog, "Reading %s for %s:\n", - get_section_name (section), - get_section_file_name (section)); + get_section_name (§ion), + get_section_file_name (§ion)); } - create_dwo_cu_data.dwo_file = dwo_file; - dwo_unit = NULL; - - end_ptr = info_ptr + section->size; + end_ptr = info_ptr + section.size; while (info_ptr < end_ptr) { struct dwarf2_per_cu_data per_cu; + struct create_dwo_cu_data create_dwo_cu_data; + struct dwo_unit *dwo_unit; + void **slot; + sect_offset sect_off = (sect_offset) (info_ptr - section.buffer); memset (&create_dwo_cu_data.dwo_unit, 0, sizeof (create_dwo_cu_data.dwo_unit)); memset (&per_cu, 0, sizeof (per_cu)); per_cu.objfile = objfile; per_cu.is_debug_types = 0; - per_cu.sect_off = sect_offset (info_ptr - section->buffer); - per_cu.section = section; + per_cu.sect_off = sect_offset (info_ptr - section.buffer); + per_cu.section = §ion; + create_dwo_cu_data.dwo_file = &dwo_file; - init_cutu_and_read_dies_no_follow (&per_cu, dwo_file, + init_cutu_and_read_dies_no_follow (&per_cu, &dwo_file, create_dwo_cu_reader, &create_dwo_cu_data); + info_ptr += per_cu.length; - if (create_dwo_cu_data.dwo_unit.dwo_file != NULL) - { - /* If we've already found one, complain. We only support one - because having more than one requires hacking the dwo_name of - each to match, which is highly unlikely to happen. */ - if (dwo_unit != NULL) - { - complaint (&symfile_complaints, - _("Multiple CUs in DWO file %s [in module %s]"), - dwo_file->dwo_name, objfile_name (objfile)); - break; - } + if (create_dwo_cu_data.dwo_unit.dwo_file == NULL) + continue; - dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit); - *dwo_unit = create_dwo_cu_data.dwo_unit; - } + if (cus_htab == NULL) + { + cus_htab = allocate_dwo_unit_table (objfile); + } - info_ptr += per_cu.length; - } + dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit); + *dwo_unit = create_dwo_cu_data.dwo_unit; + slot = htab_find_slot (cus_htab, dwo_unit, INSERT); + gdb_assert (slot != NULL); + if (*slot != NULL) + { + const struct dwo_unit *dup_cu = (const struct dwo_unit *) *slot; + sect_offset dup_sect_off = dup_cu->sect_off; - return dwo_unit; + complaint (&symfile_complaints, + _("debug cu entry at offset 0x%x is duplicate to" + " the entry at offset 0x%x, signature %s"), + to_underlying (sect_off), to_underlying (dup_sect_off), + hex_string (dwo_unit->signature)); + } + *slot = (void *) dwo_unit; + } } /* DWP file .debug_{cu,tu}_index section format: @@ -10772,7 +10772,7 @@ open_and_init_dwo_file (struct dwarf2_per_cu_data *per_cu, bfd_map_over_sections (dwo_file->dbfd, dwarf2_locate_dwo_sections, &dwo_file->sections); - dwo_file->cu = create_dwo_cu (dwo_file); + create_cus_hash_table (*dwo_file, dwo_file->sections.info, dwo_file->cus); create_debug_types_hash_table (dwo_file, dwo_file->sections.types, dwo_file->tus); @@ -11139,10 +11139,13 @@ lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit, dwo_cutu = (struct dwo_unit *) htab_find (dwo_file->tus, &find_dwo_cutu); } - else if (!is_debug_types && dwo_file->cu) + else if (!is_debug_types && dwo_file->cus) { - if (signature == dwo_file->cu->signature) - dwo_cutu = dwo_file->cu; + struct dwo_unit find_dwo_cutu; + + memset (&find_dwo_cutu, 0, sizeof (find_dwo_cutu)); + find_dwo_cutu.signature = signature; + dwo_cutu = (struct dwo_unit *) htab_find (dwo_file->cus, &find_dwo_cutu); } if (dwo_cutu != NULL)