From patchwork Thu Jan 23 00:56:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 37478 Received: (qmail 79589 invoked by alias); 23 Jan 2020 00:57:26 -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 79433 invoked by uid 89); 23 Jan 2020 00:57:26 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-20.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS autolearn=ham version=3.3.1 spammy=Joint, complaint, sk:attr_fo, Harris X-HELO: gateway36.websitewelcome.com Received: from gateway36.websitewelcome.com (HELO gateway36.websitewelcome.com) (192.185.193.12) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 23 Jan 2020 00:57:20 +0000 Received: from cm14.websitewelcome.com (cm14.websitewelcome.com [100.42.49.7]) by gateway36.websitewelcome.com (Postfix) with ESMTP id 994DE407358B1 for ; Wed, 22 Jan 2020 18:10:12 -0600 (CST) Received: from box5379.bluehost.com ([162.241.216.53]) by cmsmtp with SMTP id uQoBigB8NNBC3uQoBiy055; Wed, 22 Jan 2020 18:57:19 -0600 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tromey.com; s=default; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Sender:Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=mdaJgmW+JBvQAKvgElVnN31MCMQKet7KXokW++nhtwE=; b=UIJ/P2GrlLGOS0FS9xE03m5Xul s4W7xDmBZC7YoBvAE7pJHit68HPybJzt622TGZkJW6RWe3D495Tq4CC//vCnllMwsQh84l8rb2p6z 11R58LLwO0SaDPda4CYspOCTi; Received: from 75-166-123-50.hlrn.qwest.net ([75.166.123.50]:40800 helo=bapiya.Home) by box5379.bluehost.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92) (envelope-from ) id 1iuQoB-004Kfy-5G; Wed, 22 Jan 2020 17:57:19 -0700 From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 05/38] Create dwarf2/attribute.[ch] Date: Wed, 22 Jan 2020 17:56:37 -0700 Message-Id: <20200123005710.7978-6-tom@tromey.com> In-Reply-To: <20200123005710.7978-1-tom@tromey.com> References: <20200123005710.7978-1-tom@tromey.com> This moves the attribute-related code out of dwarf2read.c and into the new files dwarf2/attribute.[ch]. gdb/ChangeLog 2020-01-22 Tom Tromey * dwarf2read.c (struct attribute, DW_STRING) (DW_STRING_IS_CANONICAL, DW_UNSND, DW_BLOCK, DW_SND, DW_ADDR) (DW_SIGNATURE, struct dwarf_block, attr_value_as_address) (attr_form_is_block, attr_form_is_section_offset) (attr_form_is_constant, attr_form_is_ref): Move. * dwarf2/attribute.h: New file. * dwarf2/attribute.c: New file, from dwarf2read.c. * Makefile.in (COMMON_SFILES): Add dwarf2/attribute.c. Change-Id: I1ea4c146256a1b9e38b66f1c605d782a14eeded7 --- gdb/ChangeLog | 11 +++ gdb/Makefile.in | 1 + gdb/dwarf2/attribute.c | 122 +++++++++++++++++++++++++++++ gdb/dwarf2/attribute.h | 118 ++++++++++++++++++++++++++++ gdb/dwarf2read.c | 169 +---------------------------------------- 5 files changed, 253 insertions(+), 168 deletions(-) create mode 100644 gdb/dwarf2/attribute.c create mode 100644 gdb/dwarf2/attribute.h diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 2188d32c4e6..e652e4f971a 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1003,6 +1003,7 @@ COMMON_SFILES = \ dwarf2loc.c \ dwarf2read.c \ dwarf2/abbrev.c \ + dwarf2/attribute.c \ dwarf2/leb.c \ dwarf2/section.c \ eval.c \ diff --git a/gdb/dwarf2/attribute.c b/gdb/dwarf2/attribute.c new file mode 100644 index 00000000000..75a2fa3774b --- /dev/null +++ b/gdb/dwarf2/attribute.c @@ -0,0 +1,122 @@ +/* DWARF attributes + + Copyright (C) 1994-2020 Free Software Foundation, Inc. + + Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology, + Inc. with support from Florida State University (under contract + with the Ada Joint Program Office), and Silicon Graphics, Inc. + Initial contribution by Brent Benson, Harris Computer Systems, Inc., + based on Fred Fish's (Cygnus Support) implementation of DWARF 1 + support. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "defs.h" +#include "dwarf2/attribute.h" + +/* See attribute.h. */ + +CORE_ADDR +attr_value_as_address (struct attribute *attr) +{ + CORE_ADDR addr; + + if (attr->form != DW_FORM_addr && attr->form != DW_FORM_addrx + && attr->form != DW_FORM_GNU_addr_index) + { + /* Aside from a few clearly defined exceptions, attributes that + contain an address must always be in DW_FORM_addr form. + Unfortunately, some compilers happen to be violating this + requirement by encoding addresses using other forms, such + as DW_FORM_data4 for example. For those broken compilers, + we try to do our best, without any guarantee of success, + to interpret the address correctly. It would also be nice + to generate a complaint, but that would require us to maintain + a list of legitimate cases where a non-address form is allowed, + as well as update callers to pass in at least the CU's DWARF + version. This is more overhead than what we're willing to + expand for a pretty rare case. */ + addr = DW_UNSND (attr); + } + else + addr = DW_ADDR (attr); + + return addr; +} + +/* See attribute.h. */ + +int +attr_form_is_block (const struct attribute *attr) +{ + return (attr == NULL ? 0 : + attr->form == DW_FORM_block1 + || attr->form == DW_FORM_block2 + || attr->form == DW_FORM_block4 + || attr->form == DW_FORM_block + || attr->form == DW_FORM_exprloc); +} + +/* See attribute.h. */ + +int +attr_form_is_section_offset (const struct attribute *attr) +{ + return (attr->form == DW_FORM_data4 + || attr->form == DW_FORM_data8 + || attr->form == DW_FORM_sec_offset); +} + +/* See attribute.h. */ + +int +attr_form_is_constant (const struct attribute *attr) +{ + switch (attr->form) + { + case DW_FORM_sdata: + case DW_FORM_udata: + case DW_FORM_data1: + case DW_FORM_data2: + case DW_FORM_data4: + case DW_FORM_data8: + case DW_FORM_implicit_const: + return 1; + default: + return 0; + } +} + +/* DW_ADDR is always stored already as sect_offset; despite for the forms + besides DW_FORM_ref_addr it is stored as cu_offset in the DWARF file. */ + +int +attr_form_is_ref (const struct attribute *attr) +{ + switch (attr->form) + { + case DW_FORM_ref_addr: + case DW_FORM_ref1: + case DW_FORM_ref2: + case DW_FORM_ref4: + case DW_FORM_ref8: + case DW_FORM_ref_udata: + case DW_FORM_GNU_ref_alt: + return 1; + default: + return 0; + } +} diff --git a/gdb/dwarf2/attribute.h b/gdb/dwarf2/attribute.h new file mode 100644 index 00000000000..11c6cb929d9 --- /dev/null +++ b/gdb/dwarf2/attribute.h @@ -0,0 +1,118 @@ +/* DWARF attributes + + Copyright (C) 1994-2020 Free Software Foundation, Inc. + + Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology, + Inc. with support from Florida State University (under contract + with the Ada Joint Program Office), and Silicon Graphics, Inc. + Initial contribution by Brent Benson, Harris Computer Systems, Inc., + based on Fred Fish's (Cygnus Support) implementation of DWARF 1 + support. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef GDB_DWARF2_ATTRIBUTE_H +#define GDB_DWARF2_ATTRIBUTE_H + +#include "dwarf2.h" + +/* Blocks are a bunch of untyped bytes. */ +struct dwarf_block +{ + size_t size; + + /* Valid only if SIZE is not zero. */ + const gdb_byte *data; +}; + +/* Attributes have a name and a value. */ +struct attribute +{ + ENUM_BITFIELD(dwarf_attribute) name : 16; + ENUM_BITFIELD(dwarf_form) form : 15; + + /* Has DW_STRING already been updated by dwarf2_canonicalize_name? This + field should be in u.str (existing only for DW_STRING) but it is kept + here for better struct attribute alignment. */ + unsigned int string_is_canonical : 1; + + union + { + const char *str; + struct dwarf_block *blk; + ULONGEST unsnd; + LONGEST snd; + CORE_ADDR addr; + ULONGEST signature; + } + u; +}; + +/* Get at parts of an attribute structure. */ + +#define DW_STRING(attr) ((attr)->u.str) +#define DW_STRING_IS_CANONICAL(attr) ((attr)->string_is_canonical) +#define DW_UNSND(attr) ((attr)->u.unsnd) +#define DW_BLOCK(attr) ((attr)->u.blk) +#define DW_SND(attr) ((attr)->u.snd) +#define DW_ADDR(attr) ((attr)->u.addr) +#define DW_SIGNATURE(attr) ((attr)->u.signature) + +/* Read the given attribute value as an address, taking the attribute's + form into account. */ + +extern CORE_ADDR attr_value_as_address (struct attribute *attr); + +/* Check if the attribute's form is a DW_FORM_block* + if so return true else false. */ + +extern int attr_form_is_block (const struct attribute *attr); + +/* Return non-zero if ATTR's value is a section offset --- classes + lineptr, loclistptr, macptr or rangelistptr --- or zero, otherwise. + You may use DW_UNSND (attr) to retrieve such offsets. + + Section 7.5.4, "Attribute Encodings", explains that no attribute + may have a value that belongs to more than one of these classes; it + would be ambiguous if we did, because we use the same forms for all + of them. */ + +extern int attr_form_is_section_offset (const struct attribute *attr); + +/* Return non-zero if ATTR's value falls in the 'constant' class, or + zero otherwise. When this function returns true, you can apply + dwarf2_get_attr_constant_value to it. + + However, note that for some attributes you must check + attr_form_is_section_offset before using this test. DW_FORM_data4 + and DW_FORM_data8 are members of both the constant class, and of + the classes that contain offsets into other debug sections + (lineptr, loclistptr, macptr or rangelistptr). The DWARF spec says + that, if an attribute's can be either a constant or one of the + section offset classes, DW_FORM_data4 and DW_FORM_data8 should be + taken as section offsets, not constants. + + DW_FORM_data16 is not considered as dwarf2_get_attr_constant_value + cannot handle that. */ + +extern int attr_form_is_constant (const struct attribute *attr); + +/* DW_ADDR is always stored already as sect_offset; despite for the forms + besides DW_FORM_ref_addr it is stored as cu_offset in the DWARF file. */ + +extern int attr_form_is_ref (const struct attribute *attr); + +#endif /* GDB_DWARF2_ATTRIBUTE_H */ diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 886bec1d7aa..5b77e397899 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -31,6 +31,7 @@ #include "defs.h" #include "dwarf2read.h" #include "dwarf2/abbrev.h" +#include "dwarf2/attribute.h" #include "dwarf-index-cache.h" #include "dwarf-index-common.h" #include "dwarf2/leb.h" @@ -1233,29 +1234,6 @@ struct partial_die_info : public allocate_on_obstack } }; -/* Attributes have a name and a value. */ -struct attribute - { - ENUM_BITFIELD(dwarf_attribute) name : 16; - ENUM_BITFIELD(dwarf_form) form : 15; - - /* Has DW_STRING already been updated by dwarf2_canonicalize_name? This - field should be in u.str (existing only for DW_STRING) but it is kept - here for better struct attribute alignment. */ - unsigned int string_is_canonical : 1; - - union - { - const char *str; - struct dwarf_block *blk; - ULONGEST unsnd; - LONGEST snd; - CORE_ADDR addr; - ULONGEST signature; - } - u; - }; - /* This data structure holds a complete die structure. */ struct die_info { @@ -1292,25 +1270,6 @@ struct die_info struct attribute attrs[1]; }; -/* Get at parts of an attribute structure. */ - -#define DW_STRING(attr) ((attr)->u.str) -#define DW_STRING_IS_CANONICAL(attr) ((attr)->string_is_canonical) -#define DW_UNSND(attr) ((attr)->u.unsnd) -#define DW_BLOCK(attr) ((attr)->u.blk) -#define DW_SND(attr) ((attr)->u.snd) -#define DW_ADDR(attr) ((attr)->u.addr) -#define DW_SIGNATURE(attr) ((attr)->u.signature) - -/* Blocks are a bunch of untyped bytes. */ -struct dwarf_block - { - size_t size; - - /* Valid only if SIZE is not zero. */ - const gdb_byte *data; - }; - /* FIXME: We might want to set this from BFD via bfd_arch_bits_per_byte, but this would require a corresponding change in unpack_field_as_long and friends. */ @@ -1785,14 +1744,6 @@ static struct die_info *dwarf_alloc_die (struct dwarf2_cu *, int); static void dwarf_decode_macros (struct dwarf2_cu *, unsigned int, int); -static int attr_form_is_block (const struct attribute *); - -static int attr_form_is_section_offset (const struct attribute *); - -static int attr_form_is_constant (const struct attribute *); - -static int attr_form_is_ref (const struct attribute *); - static void fill_in_loclist_baton (struct dwarf2_cu *cu, struct dwarf2_loclist_baton *baton, const struct attribute *attr); @@ -2055,37 +2006,6 @@ line_header_eq_voidp (const void *item_lhs, const void *item_rhs) -/* Read the given attribute value as an address, taking the attribute's - form into account. */ - -static CORE_ADDR -attr_value_as_address (struct attribute *attr) -{ - CORE_ADDR addr; - - if (attr->form != DW_FORM_addr && attr->form != DW_FORM_addrx - && attr->form != DW_FORM_GNU_addr_index) - { - /* Aside from a few clearly defined exceptions, attributes that - contain an address must always be in DW_FORM_addr form. - Unfortunately, some compilers happen to be violating this - requirement by encoding addresses using other forms, such - as DW_FORM_data4 for example. For those broken compilers, - we try to do our best, without any guarantee of success, - to interpret the address correctly. It would also be nice - to generate a complaint, but that would require us to maintain - a list of legitimate cases where a non-address form is allowed, - as well as update callers to pass in at least the CU's DWARF - version. This is more overhead than what we're willing to - expand for a pretty rare case. */ - addr = DW_UNSND (attr); - } - else - addr = DW_ADDR (attr); - - return addr; -} - /* See declaration. */ dwarf2_per_objfile::dwarf2_per_objfile (struct objfile *objfile_, @@ -24857,93 +24777,6 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset, include_hash.get ()); } -/* Check if the attribute's form is a DW_FORM_block* - if so return true else false. */ - -static int -attr_form_is_block (const struct attribute *attr) -{ - return (attr == NULL ? 0 : - attr->form == DW_FORM_block1 - || attr->form == DW_FORM_block2 - || attr->form == DW_FORM_block4 - || attr->form == DW_FORM_block - || attr->form == DW_FORM_exprloc); -} - -/* Return non-zero if ATTR's value is a section offset --- classes - lineptr, loclistptr, macptr or rangelistptr --- or zero, otherwise. - You may use DW_UNSND (attr) to retrieve such offsets. - - Section 7.5.4, "Attribute Encodings", explains that no attribute - may have a value that belongs to more than one of these classes; it - would be ambiguous if we did, because we use the same forms for all - of them. */ - -static int -attr_form_is_section_offset (const struct attribute *attr) -{ - return (attr->form == DW_FORM_data4 - || attr->form == DW_FORM_data8 - || attr->form == DW_FORM_sec_offset); -} - -/* Return non-zero if ATTR's value falls in the 'constant' class, or - zero otherwise. When this function returns true, you can apply - dwarf2_get_attr_constant_value to it. - - However, note that for some attributes you must check - attr_form_is_section_offset before using this test. DW_FORM_data4 - and DW_FORM_data8 are members of both the constant class, and of - the classes that contain offsets into other debug sections - (lineptr, loclistptr, macptr or rangelistptr). The DWARF spec says - that, if an attribute's can be either a constant or one of the - section offset classes, DW_FORM_data4 and DW_FORM_data8 should be - taken as section offsets, not constants. - - DW_FORM_data16 is not considered as dwarf2_get_attr_constant_value - cannot handle that. */ - -static int -attr_form_is_constant (const struct attribute *attr) -{ - switch (attr->form) - { - case DW_FORM_sdata: - case DW_FORM_udata: - case DW_FORM_data1: - case DW_FORM_data2: - case DW_FORM_data4: - case DW_FORM_data8: - case DW_FORM_implicit_const: - return 1; - default: - return 0; - } -} - - -/* DW_ADDR is always stored already as sect_offset; despite for the forms - besides DW_FORM_ref_addr it is stored as cu_offset in the DWARF file. */ - -static int -attr_form_is_ref (const struct attribute *attr) -{ - switch (attr->form) - { - case DW_FORM_ref_addr: - case DW_FORM_ref1: - case DW_FORM_ref2: - case DW_FORM_ref4: - case DW_FORM_ref8: - case DW_FORM_ref_udata: - case DW_FORM_GNU_ref_alt: - return 1; - default: - return 0; - } -} - /* Return the .debug_loc section to use for CU. For DWO files use .debug_loc.dwo. */