From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 70947 invoked by alias); 27 Aug 2019 23:41:58 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 70806 invoked by uid 89); 27 Aug 2019 23:41:58 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-22.3 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.1 spammy=*die, longest, H*MI:google X-HELO: mail-pf1-f201.google.com Received: from mail-pf1-f201.google.com (HELO mail-pf1-f201.google.com) (209.85.210.201) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 27 Aug 2019 23:41:55 +0000 Received: by mail-pf1-f201.google.com with SMTP id w16so562686pfn.12 for ; Tue, 27 Aug 2019 16:41:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:message-id:mime-version:subject:from:to:cc; bh=WZaQGkrKcp90S3tnAbGgA2TeTsle3k+9X5kwd69lwFk=; b=RA8LWz76Hmb4BREzlDLxhaB3h1L+H2/xX2J+dWBzdQxLNGa/F/hjDP4N8XrlYHK3TT yjRASHL2dtkVKZ2EhKb++JZAPYnlIYbSUmsnfxVFmxR7I0PJwJjQZ4MvtHkxKTDixScZ ZiTKRy2DQTtLwwLTmQO0GGBXwQjuTkT0LzJMpYp5IP+RsEznrwu93x9FT4OV8UZ4FdC2 mEmLgS8RhZAxvMMZBgtyYMRHDa+ATymVQXI0P2lhdsH+JZ7I32vH8unZ9RT2RGOwMrDU PfReYTYKboF5ZBp/4NECeNGZEENRWhwlMSysNXevq92WMh+SVPriZPvAQhdWgFciq1oI Xp1Q== Date: Tue, 27 Aug 2019 23:41:00 -0000 Message-Id: <20190827234148.243410-1-tamur@google.com> Mime-Version: 1.0 Subject: [PATCH 1/4] Increasing support for dwarf 5. From: "Ali Tamur via gdb-patches" Reply-To: Ali Tamur To: gdb-patches@sourceware.org Cc: Ali Tamur Content-Type: text/plain; charset="UTF-8" X-IsSubscribed: yes X-SW-Source: 2019-08/txt/msg00620.txt.bz2 * DW_UT_skeleton and DW_UT_split_compile compilation units also have signatures to match the compilation unit in the skeleton and .dwo files. The signature is part of the header. gdb/ChangeLog: 2019-08-26 Ali Tamur * gdb/dwarf2read.c (comp_unit_head): Update comment. (dwarf2_dwo_name): New function declaration. (read_comp_unit_head): Add support for new compilation units, DW_UT_partial, DW_UT_skeleton, DW_UT_split_compile, DW_UT_split_type. Particularly, DW_UT_skeleton and DW_UT_split_compile also have signature in their header. (lookup_signature): New function. Returns the signature of the given compile unit. (lookup_dwo_unit): API change. Use the new lookup_signature function. (init_cutu_and_read_dies): Use dwarf2_dwo_name to find the dwo name. (create_dwo_cu_reader): Use the added lookup_signature function. (dwarf2_dwo_name): Get the dwo name if present. --- gdb/dwarf2read.c | 101 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 32 deletions(-) diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index de9755f6ce..91a4e48c8f 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -373,8 +373,9 @@ struct comp_unit_head This will be the first byte following the compilation unit header. */ cu_offset first_die_cu_offset; - /* 64-bit signature of this type unit - it is valid only for - UNIT_TYPE DW_UT_type. */ + /* 64-bit signature of this type unit. In dwarf 4, it is valid only for + UNIT_TYPE DW_UT_type. In dwarf 5, DW_UT_split_type, DW_UT_partial, + DW_UT_skeleton, DW_UT_split_compile also contain a signature. */ ULONGEST signature; /* For types, offset in the type's DIE of the type defined by this TU. */ @@ -1579,6 +1580,8 @@ static struct attribute *dwarf2_attr_no_follow (struct die_info *, static const char *dwarf2_string_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *cu); +static const char *dwarf2_dwo_name (struct die_info *die, struct dwarf2_cu *cu); + static int dwarf2_flag_true_p (struct die_info *die, unsigned name, struct dwarf2_cu *cu); @@ -6384,18 +6387,24 @@ read_comp_unit_head (struct comp_unit_head *cu_header, switch (cu_header->unit_type) { case DW_UT_compile: + case DW_UT_partial: + case DW_UT_skeleton: + case DW_UT_split_compile: if (section_kind != rcuh_kind::COMPILE) error (_("Dwarf Error: wrong unit_type in compilation unit header " - "(is DW_UT_compile, should be DW_UT_type) [in module %s]"), - filename); + "(is %d, should be DW_UT_type) [in module %s]"), + cu_header->unit_type, filename); break; case DW_UT_type: + case DW_UT_split_type: section_kind = rcuh_kind::TYPE; break; default: error (_("Dwarf Error: wrong unit_type in compilation unit header " - "(is %d, should be %d or %d) [in module %s]"), - cu_header->unit_type, DW_UT_compile, DW_UT_type, filename); + "(is %d, should be one of: %d, %d, %d, %d or %d) " + "[in module %s]"), + cu_header->unit_type, DW_UT_compile, DW_UT_skeleton, + DW_UT_split_compile, DW_UT_type, DW_UT_split_type, filename); } cu_header->addr_size = read_1_byte (abfd, info_ptr); @@ -6416,13 +6425,19 @@ read_comp_unit_head (struct comp_unit_head *cu_header, _("read_comp_unit_head: dwarf from non elf file")); cu_header->signed_addr_p = signed_addr; - if (section_kind == rcuh_kind::TYPE) - { - LONGEST type_offset; + bool header_has_signature = section_kind == rcuh_kind::TYPE + || cu_header->unit_type == DW_UT_skeleton + || cu_header->unit_type == DW_UT_split_compile; + if (header_has_signature) + { cu_header->signature = read_8_bytes (abfd, info_ptr); info_ptr += 8; + } + if (section_kind == rcuh_kind::TYPE) + { + LONGEST type_offset; type_offset = read_offset (abfd, info_ptr, cu_header, &bytes_read); info_ptr += bytes_read; cu_header->type_cu_offset_in_tu = (cu_offset) type_offset; @@ -7291,46 +7306,59 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu, return 1; } +/* Return the signature of the compile unit. In dwarf 4 and before, the + signature is in the DW_AT_GNU_dwo_id attribute. In dwarf 5 and later, the + signature is part of the header. Returns 0 if the signature is not found. */ +static ULONGEST +lookup_signature (struct dwarf2_cu *cu, struct die_info* comp_unit_die) +{ + ULONGEST signature = 0; + struct attribute *attr; + + attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_id, cu); + if (attr) + signature = DW_UNSND (attr); + else if (cu->header.signature) + signature = cu->header.signature; + return signature; +} + /* Subroutine of init_cutu_and_read_dies to simplify it. Look up the DWO unit specified by COMP_UNIT_DIE of THIS_CU. Returns NULL if the specified DWO unit cannot be found. */ static struct dwo_unit * -lookup_dwo_unit (struct dwarf2_per_cu_data *this_cu, +lookup_dwo_unit (const struct die_reader_specs *reader, struct die_info *comp_unit_die) { - struct dwarf2_cu *cu = this_cu->cu; - ULONGEST signature; + struct dwarf2_cu *cu = reader->cu; + struct dwarf2_per_cu_data *per_cu = cu->per_cu; struct dwo_unit *dwo_unit; const char *comp_dir, *dwo_name; gdb_assert (cu != NULL); /* Yeah, we look dwo_name up again, but it simplifies the code. */ - dwo_name = dwarf2_string_attr (comp_unit_die, DW_AT_GNU_dwo_name, cu); + dwo_name = dwarf2_dwo_name (comp_unit_die, cu); comp_dir = dwarf2_string_attr (comp_unit_die, DW_AT_comp_dir, cu); - if (this_cu->is_debug_types) + if (per_cu->is_debug_types) { struct signatured_type *sig_type; - /* Since this_cu is the first member of struct signatured_type, + /* Since per_cu is the first member of struct signatured_type, we can go from a pointer to one to a pointer to the other. */ - sig_type = (struct signatured_type *) this_cu; - signature = sig_type->signature; + sig_type = (struct signatured_type *) per_cu; dwo_unit = lookup_dwo_type_unit (sig_type, dwo_name, comp_dir); } else { - struct attribute *attr; - - attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_id, cu); - if (! attr) + ULONGEST signature = lookup_signature(cu, comp_unit_die); + if (!signature) error (_("Dwarf Error: missing dwo_id for dwo_name %s" " [in module %s]"), - dwo_name, objfile_name (this_cu->dwarf2_per_objfile->objfile)); - signature = DW_UNSND (attr); - dwo_unit = lookup_dwo_comp_unit (this_cu, dwo_name, comp_dir, + dwo_name, objfile_name (per_cu->dwarf2_per_objfile->objfile)); + dwo_unit = lookup_dwo_comp_unit (per_cu, dwo_name, comp_dir, signature); } @@ -7443,7 +7471,6 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, struct die_reader_specs reader; struct die_info *comp_unit_die; int has_children; - struct attribute *attr; struct signatured_type *sig_type = NULL; struct dwarf2_section_info *abbrev_section; /* Non-zero if CU currently points to a DWO file and we need to @@ -7580,9 +7607,9 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, Note that if USE_EXISTING_OK != 0, and THIS_CU->cu already contains a DWO CU, that this test will fail (the attribute will not be present). */ - attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_name, cu); + const char *dwo_name = dwarf2_dwo_name (comp_unit_die, cu); abbrev_table_up dwo_abbrev_table; - if (attr) + if (dwo_name) { struct dwo_unit *dwo_unit; struct die_info *dwo_comp_unit_die; @@ -7594,7 +7621,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, sect_offset_str (this_cu->sect_off), bfd_get_filename (abfd)); } - dwo_unit = lookup_dwo_unit (this_cu, comp_unit_die); + dwo_unit = lookup_dwo_unit (&reader, comp_unit_die); if (dwo_unit != NULL) { if (read_cutu_die_from_dwo (this_cu, dwo_unit, @@ -11833,10 +11860,9 @@ create_dwo_cu_reader (const struct die_reader_specs *reader, struct create_dwo_cu_data *data = (struct create_dwo_cu_data *) datap; struct dwo_file *dwo_file = data->dwo_file; struct dwo_unit *dwo_unit = &data->dwo_unit; - struct attribute *attr; - attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_id, cu); - if (attr == NULL) + ULONGEST signature = lookup_signature(cu, comp_unit_die); + if (!signature) { complaint (_("Dwarf Error: debug entry at offset %s is missing" " its dwo_id [in module %s]"), @@ -11845,7 +11871,7 @@ create_dwo_cu_reader (const struct die_reader_specs *reader, } dwo_unit->dwo_file = dwo_file; - dwo_unit->signature = DW_UNSND (attr); + dwo_unit->signature = signature; dwo_unit->section = section; dwo_unit->sect_off = sect_off; dwo_unit->length = cu->per_cu->length; @@ -20102,6 +20128,17 @@ dwarf2_string_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *c return str; } +/* Return the dwo name or NULL if not present. If present, it is in either + DW_AT_GNU_dwo_name or DW_AT_dwo_name atrribute. */ +static const char * +dwarf2_dwo_name (struct die_info *die, struct dwarf2_cu *cu) +{ + const char *dwo_name = dwarf2_string_attr (die, DW_AT_GNU_dwo_name, cu); + if (!dwo_name) + dwo_name = dwarf2_string_attr (die, DW_AT_dwo_name, cu); + return dwo_name; +} + /* Return non-zero iff the attribute NAME is defined for the given DIE, and holds a non-zero value. This function should only be used for DW_FORM_flag or DW_FORM_flag_present attributes. */ -- 2.23.0.187.g17f5b7556c-goog