From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 96E9B385455A for ; Wed, 14 Dec 2022 03:41:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 96E9B385455A Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 2BE3et6k031185 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 13 Dec 2022 22:40:59 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 2BE3et6k031185 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1670989260; bh=7Tb8RRoVqM8Z7R/mZepOi7oxBT7+ctOgcqkHwhm8gpY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=H2VivibujUWaFsFlGZ+fAzhUVvNar23KfQij4lyNSheFptFV9LJwXuMakx2laP9ts qVCtd2NMUxPBYRHmAJ6cFf3oFqjj/mnaoSwEt1r2UKKP2hdPTlPgwe5m6COCHSJ6t7 UXS6aE2bKi0LISDU+myerCXugfZu3b0x3ftRHUZ8= Received: from simark.localdomain (unknown [217.28.27.60]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 2F1BB1E12A; Tue, 13 Dec 2022 22:34:44 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH v2 05/13] gdb: move call site types to call-site.h Date: Tue, 13 Dec 2022 22:34:33 -0500 Message-Id: <20221214033441.499512-6-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221214033441.499512-1-simon.marchi@polymtl.ca> References: <20221214033441.499512-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Wed, 14 Dec 2022 03:40:55 +0000 X-Spam-Status: No, score=-3189.5 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: From: Simon Marchi I hesitated between putting the file in the dwarf2 directory (as gdb/dwarf2/call-site.h) or in the common directory (as gdb/call-site.h). The concept of call site is not DWARF-specific, another debug info reader could provide this information. But as it is, the implementation is a bit DWARF-specific, as one form it can take is a DWARF expression and parameters can be defined using a DWARF register number. So I ended up choosing to put it under dwarf2/. If another debug info reader ever wants to provide call site information, we can introduce a layer of abstraction between the "common" call site and the "dwarf2" call site. The copyright start year comes from the date `struct call_site` was introduced. Change-Id: I1cd84aa581fbbf729edc91b20f7d7a6e0377014d --- gdb/dwarf2/abbrev-cache.h | 1 - gdb/dwarf2/attribute.h | 2 +- gdb/dwarf2/call-site.h | 244 ++++++++++++++++++++++++++++++++++++ gdb/dwarf2/comp-unit-head.h | 5 +- gdb/dwarf2/cooked-index.h | 2 +- gdb/dwarf2/expr.h | 2 +- gdb/dwarf2/line-header.h | 2 - gdb/dwarf2/types.h | 1 + gdb/gdbtypes.h | 211 ------------------------------- gdb/symtab.c | 1 + 10 files changed, 253 insertions(+), 218 deletions(-) create mode 100644 gdb/dwarf2/call-site.h diff --git a/gdb/dwarf2/abbrev-cache.h b/gdb/dwarf2/abbrev-cache.h index d729eb9dd1bb..c56a7aba217a 100644 --- a/gdb/dwarf2/abbrev-cache.h +++ b/gdb/dwarf2/abbrev-cache.h @@ -21,7 +21,6 @@ #define GDB_DWARF2_ABBREV_CACHE_H #include "dwarf2/abbrev.h" -#include "gdbtypes.h" /* An abbrev cache holds abbrev tables for easier reuse. */ class abbrev_cache diff --git a/gdb/dwarf2/attribute.h b/gdb/dwarf2/attribute.h index 447d195eb9a4..aa6380cb11fb 100644 --- a/gdb/dwarf2/attribute.h +++ b/gdb/dwarf2/attribute.h @@ -28,7 +28,7 @@ #define GDB_DWARF2_ATTRIBUTE_H #include "dwarf2.h" -#include "gdbtypes.h" +#include "dwarf2/types.h" #include "gdbsupport/gdb_optional.h" /* Blocks are a bunch of untyped bytes. */ diff --git a/gdb/dwarf2/call-site.h b/gdb/dwarf2/call-site.h new file mode 100644 index 000000000000..f5bee967594e --- /dev/null +++ b/gdb/dwarf2/call-site.h @@ -0,0 +1,244 @@ +/* Call site information. + + Copyright (C) 2011-2022 Free Software Foundation, Inc. + + Contributed by Cygnus Support, using pieces from other GDB modules. + + 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 CALL_SITE_H +#define CALL_SITE_H + +#include "dwarf2/types.h" +#include "gdbsupport/function-view.h" +#include "frame-info.h" + +struct dwarf2_locexpr_baton; +struct dwarf2_per_cu_data; +struct dwarf2_per_objfile; + +/* struct call_site_parameter can be referenced in callees by several ways. */ + +enum call_site_parameter_kind +{ + /* * Use field call_site_parameter.u.dwarf_reg. */ + CALL_SITE_PARAMETER_DWARF_REG, + + /* * Use field call_site_parameter.u.fb_offset. */ + CALL_SITE_PARAMETER_FB_OFFSET, + + /* * Use field call_site_parameter.u.param_offset. */ + CALL_SITE_PARAMETER_PARAM_OFFSET +}; + +struct call_site_target +{ + /* The kind of location held by this call site target. */ + enum kind + { + /* An address. */ + PHYSADDR, + /* A name. */ + PHYSNAME, + /* A DWARF block. */ + DWARF_BLOCK, + /* An array of addresses. */ + ADDRESSES, + }; + + void set_loc_physaddr (CORE_ADDR physaddr) + { + m_loc_kind = PHYSADDR; + m_loc.physaddr = physaddr; + } + + void set_loc_physname (const char *physname) + { + m_loc_kind = PHYSNAME; + m_loc.physname = physname; + } + + void set_loc_dwarf_block (dwarf2_locexpr_baton *dwarf_block) + { + m_loc_kind = DWARF_BLOCK; + m_loc.dwarf_block = dwarf_block; + } + + void set_loc_array (unsigned length, const CORE_ADDR *data) + { + m_loc_kind = ADDRESSES; + m_loc.addresses.length = length; + m_loc.addresses.values = data; + } + + /* Callback type for iterate_over_addresses. */ + + using iterate_ftype = gdb::function_view; + + /* Call CALLBACK for each DW_TAG_call_site's DW_AT_call_target + address. CALLER_FRAME (for registers) can be NULL if it is not + known. This function always may throw NO_ENTRY_VALUE_ERROR. */ + + void iterate_over_addresses (struct gdbarch *call_site_gdbarch, + const struct call_site *call_site, + frame_info_ptr caller_frame, + iterate_ftype callback) const; + +private: + + union + { + /* Address. */ + CORE_ADDR physaddr; + /* Mangled name. */ + const char *physname; + /* DWARF block. */ + struct dwarf2_locexpr_baton *dwarf_block; + /* Array of addresses. */ + struct + { + unsigned length; + const CORE_ADDR *values; + } addresses; + } m_loc; + + /* * Discriminant for union field_location. */ + enum kind m_loc_kind; +}; + +union call_site_parameter_u +{ + /* * DW_TAG_formal_parameter's DW_AT_location's DW_OP_regX + as DWARF register number, for register passed + parameters. */ + + int dwarf_reg; + + /* * Offset from the callee's frame base, for stack passed + parameters. This equals offset from the caller's stack + pointer. */ + + CORE_ADDR fb_offset; + + /* * Offset relative to the start of this PER_CU to + DW_TAG_formal_parameter which is referenced by both + caller and the callee. */ + + cu_offset param_cu_off; +}; + +struct call_site_parameter +{ + ENUM_BITFIELD (call_site_parameter_kind) kind : 2; + + union call_site_parameter_u u; + + /* * DW_TAG_formal_parameter's DW_AT_call_value. It is never NULL. */ + + const gdb_byte *value; + size_t value_size; + + /* * DW_TAG_formal_parameter's DW_AT_call_data_value. + It may be NULL if not provided by DWARF. */ + + const gdb_byte *data_value; + size_t data_value_size; +}; + +/* * A place where a function gets called from, represented by + DW_TAG_call_site. It can be looked up from symtab->call_site_htab. */ + +struct call_site +{ + call_site (CORE_ADDR pc, dwarf2_per_cu_data *per_cu, + dwarf2_per_objfile *per_objfile) + : per_cu (per_cu), per_objfile (per_objfile), m_unrelocated_pc (pc) + {} + + static int + eq (const call_site *a, const call_site *b) + { + return a->m_unrelocated_pc == b->m_unrelocated_pc; + } + + static hashval_t + hash (const call_site *a) + { + return a->m_unrelocated_pc; + } + + static int + eq (const void *a, const void *b) + { + return eq ((const call_site *)a, (const call_site *)b); + } + + static hashval_t + hash (const void *a) + { + return hash ((const call_site *)a); + } + + /* Return the address of the first instruction after this call. */ + + CORE_ADDR pc () const; + + /* Call CALLBACK for each target address. CALLER_FRAME (for + registers) can be NULL if it is not known. This function may + throw NO_ENTRY_VALUE_ERROR. */ + + void iterate_over_addresses (struct gdbarch *call_site_gdbarch, + frame_info_ptr caller_frame, + call_site_target::iterate_ftype callback) + const + { + return target.iterate_over_addresses (call_site_gdbarch, this, + caller_frame, callback); + } + + /* * List successor with head in FUNC_TYPE.TAIL_CALL_LIST. */ + + struct call_site *tail_call_next = nullptr; + + /* * Describe DW_AT_call_target. Missing attribute uses + FIELD_LOC_KIND_DWARF_BLOCK with FIELD_DWARF_BLOCK == NULL. */ + + struct call_site_target target {}; + + /* * Size of the PARAMETER array. */ + + unsigned parameter_count = 0; + + /* * CU of the function where the call is located. It gets used + for DWARF blocks execution in the parameter array below. */ + + dwarf2_per_cu_data *const per_cu = nullptr; + + /* objfile of the function where the call is located. */ + + dwarf2_per_objfile *const per_objfile = nullptr; + +private: + /* Unrelocated address of the first instruction after this call. */ + const CORE_ADDR m_unrelocated_pc; + +public: + /* * Describe DW_TAG_call_site's DW_TAG_formal_parameter. */ + + struct call_site_parameter parameter[]; +}; + +#endif /* CALL_SITE_H */ diff --git a/gdb/dwarf2/comp-unit-head.h b/gdb/dwarf2/comp-unit-head.h index a7ee3e64546d..ba63c26d3a76 100644 --- a/gdb/dwarf2/comp-unit-head.h +++ b/gdb/dwarf2/comp-unit-head.h @@ -27,8 +27,11 @@ #ifndef GDB_DWARF2_COMP_UNIT_H #define GDB_DWARF2_COMP_UNIT_H +#include "dwarf2.h" #include "dwarf2/leb.h" -#include "gdbtypes.h" +#include "dwarf2/types.h" + +struct dwarf2_per_objfile; /* The data in a compilation unit header, after target2host translation, looks like this. */ diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h index 2ea32781be5c..8f9d250f467b 100644 --- a/gdb/dwarf2/cooked-index.h +++ b/gdb/dwarf2/cooked-index.h @@ -21,7 +21,7 @@ #define GDB_DWARF2_COOKED_INDEX_H #include "dwarf2.h" -#include "gdbtypes.h" +#include "dwarf2/types.h" #include "symtab.h" #include "hashtab.h" #include "dwarf2/index-common.h" diff --git a/gdb/dwarf2/expr.h b/gdb/dwarf2/expr.h index 6078dce0abc5..aa4b392bc99b 100644 --- a/gdb/dwarf2/expr.h +++ b/gdb/dwarf2/expr.h @@ -23,7 +23,7 @@ #define DWARF2EXPR_H #include "leb128.h" -#include "gdbtypes.h" +#include "dwarf2/call-site.h" struct dwarf2_per_objfile; diff --git a/gdb/dwarf2/line-header.h b/gdb/dwarf2/line-header.h index e7a63a37918a..ac73bf2e4ede 100644 --- a/gdb/dwarf2/line-header.h +++ b/gdb/dwarf2/line-header.h @@ -20,8 +20,6 @@ #ifndef DWARF2_LINE_HEADER_H #define DWARF2_LINE_HEADER_H -#include "gdbtypes.h" - /* dir_index is 1-based in DWARF 4 and before, and is 0-based in DWARF 5 and later. */ typedef int dir_index; diff --git a/gdb/dwarf2/types.h b/gdb/dwarf2/types.h index 463dc485925f..db026d3b6f3f 100644 --- a/gdb/dwarf2/types.h +++ b/gdb/dwarf2/types.h @@ -21,6 +21,7 @@ #define DWARF2_TYPES_H #include "gdbsupport/offset-type.h" +#include "gdbsupport/underlying.h" /* Offset relative to the start of its containing CU (compilation unit). */ diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index fbe46323216f..d5b966dc73f1 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -57,7 +57,6 @@ #include "gdbsupport/gdb_obstack.h" #include "gmp-utils.h" #include "frame-info.h" -#include "dwarf2/types.h" /* Forward declarations for prototypes. */ struct field; @@ -1735,216 +1734,6 @@ struct func_type struct type *self_type; }; -/* struct call_site_parameter can be referenced in callees by several ways. */ - -enum call_site_parameter_kind -{ - /* * Use field call_site_parameter.u.dwarf_reg. */ - CALL_SITE_PARAMETER_DWARF_REG, - - /* * Use field call_site_parameter.u.fb_offset. */ - CALL_SITE_PARAMETER_FB_OFFSET, - - /* * Use field call_site_parameter.u.param_offset. */ - CALL_SITE_PARAMETER_PARAM_OFFSET -}; - -struct call_site_target -{ - /* The kind of location held by this call site target. */ - enum kind - { - /* An address. */ - PHYSADDR, - /* A name. */ - PHYSNAME, - /* A DWARF block. */ - DWARF_BLOCK, - /* An array of addresses. */ - ADDRESSES, - }; - - void set_loc_physaddr (CORE_ADDR physaddr) - { - m_loc_kind = PHYSADDR; - m_loc.physaddr = physaddr; - } - - void set_loc_physname (const char *physname) - { - m_loc_kind = PHYSNAME; - m_loc.physname = physname; - } - - void set_loc_dwarf_block (dwarf2_locexpr_baton *dwarf_block) - { - m_loc_kind = DWARF_BLOCK; - m_loc.dwarf_block = dwarf_block; - } - - void set_loc_array (unsigned length, const CORE_ADDR *data) - { - m_loc_kind = ADDRESSES; - m_loc.addresses.length = length; - m_loc.addresses.values = data; - } - - /* Callback type for iterate_over_addresses. */ - - using iterate_ftype = gdb::function_view; - - /* Call CALLBACK for each DW_TAG_call_site's DW_AT_call_target - address. CALLER_FRAME (for registers) can be NULL if it is not - known. This function always may throw NO_ENTRY_VALUE_ERROR. */ - - void iterate_over_addresses (struct gdbarch *call_site_gdbarch, - const struct call_site *call_site, - frame_info_ptr caller_frame, - iterate_ftype callback) const; - -private: - - union - { - /* Address. */ - CORE_ADDR physaddr; - /* Mangled name. */ - const char *physname; - /* DWARF block. */ - struct dwarf2_locexpr_baton *dwarf_block; - /* Array of addresses. */ - struct - { - unsigned length; - const CORE_ADDR *values; - } addresses; - } m_loc; - - /* * Discriminant for union field_location. */ - enum kind m_loc_kind; -}; - -union call_site_parameter_u -{ - /* * DW_TAG_formal_parameter's DW_AT_location's DW_OP_regX - as DWARF register number, for register passed - parameters. */ - - int dwarf_reg; - - /* * Offset from the callee's frame base, for stack passed - parameters. This equals offset from the caller's stack - pointer. */ - - CORE_ADDR fb_offset; - - /* * Offset relative to the start of this PER_CU to - DW_TAG_formal_parameter which is referenced by both - caller and the callee. */ - - cu_offset param_cu_off; -}; - -struct call_site_parameter -{ - ENUM_BITFIELD (call_site_parameter_kind) kind : 2; - - union call_site_parameter_u u; - - /* * DW_TAG_formal_parameter's DW_AT_call_value. It is never NULL. */ - - const gdb_byte *value; - size_t value_size; - - /* * DW_TAG_formal_parameter's DW_AT_call_data_value. - It may be NULL if not provided by DWARF. */ - - const gdb_byte *data_value; - size_t data_value_size; -}; - -/* * A place where a function gets called from, represented by - DW_TAG_call_site. It can be looked up from symtab->call_site_htab. */ - -struct call_site - { - call_site (CORE_ADDR pc, dwarf2_per_cu_data *per_cu, - dwarf2_per_objfile *per_objfile) - : per_cu (per_cu), per_objfile (per_objfile), m_unrelocated_pc (pc) - {} - - static int - eq (const call_site *a, const call_site *b) - { - return a->m_unrelocated_pc == b->m_unrelocated_pc; - } - - static hashval_t - hash (const call_site *a) - { - return a->m_unrelocated_pc; - } - - static int - eq (const void *a, const void *b) - { - return eq ((const call_site *)a, (const call_site *)b); - } - - static hashval_t - hash (const void *a) - { - return hash ((const call_site *)a); - } - - /* Return the address of the first instruction after this call. */ - - CORE_ADDR pc () const; - - /* Call CALLBACK for each target address. CALLER_FRAME (for - registers) can be NULL if it is not known. This function may - throw NO_ENTRY_VALUE_ERROR. */ - - void iterate_over_addresses (struct gdbarch *call_site_gdbarch, - frame_info_ptr caller_frame, - call_site_target::iterate_ftype callback) - const - { - return target.iterate_over_addresses (call_site_gdbarch, this, - caller_frame, callback); - } - - /* * List successor with head in FUNC_TYPE.TAIL_CALL_LIST. */ - - struct call_site *tail_call_next = nullptr; - - /* * Describe DW_AT_call_target. Missing attribute uses - FIELD_LOC_KIND_DWARF_BLOCK with FIELD_DWARF_BLOCK == NULL. */ - - struct call_site_target target {}; - - /* * Size of the PARAMETER array. */ - - unsigned parameter_count = 0; - - /* * CU of the function where the call is located. It gets used - for DWARF blocks execution in the parameter array below. */ - - dwarf2_per_cu_data *const per_cu = nullptr; - - /* objfile of the function where the call is located. */ - - dwarf2_per_objfile *const per_objfile = nullptr; - - private: - /* Unrelocated address of the first instruction after this call. */ - const CORE_ADDR m_unrelocated_pc; - - public: - /* * Describe DW_TAG_call_site's DW_TAG_formal_parameter. */ - - struct call_site_parameter parameter[]; - }; /* The type-specific info for TYPE_CODE_FIXED_POINT types. */ diff --git a/gdb/symtab.c b/gdb/symtab.c index 0d342f765f2f..57102e2c085a 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -18,6 +18,7 @@ along with this program. If not, see . */ #include "defs.h" +#include "dwarf2/call-site.h" #include "symtab.h" #include "gdbtypes.h" #include "gdbcore.h" -- 2.38.1