From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM02-DM3-obe.outbound.protection.outlook.com (mail-dm3nam07on2068.outbound.protection.outlook.com [40.107.95.68]) by sourceware.org (Postfix) with ESMTPS id 30E86385803A for ; Fri, 5 Nov 2021 11:39:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 30E86385803A ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=lJtfxuGI3aC1YmmvJjr8OHmxHrbL+8YbSiGjv/3vUTIBiJRTNF9b3Q0rnqiF+3zuC8xNAFNPWwxyESf5JMIGpxRJVLLF1+1wF23BZ+74O12mE84LJ8jOndd0UA4GCgLRtuRvFLsKzfrQ5NAZPIKbNQu6HRx9ZN1W33qPeFlRfGnM5CH7oHKSnkyH+0X9S6QK3+qcXR7rA1pZrSTDVsRebIpaW+GVUyDjpTBpo2hvGb1CsZmUKFtFXmhBn3AuYTkLJsMVGDu2y+QZ3uWDEuaYDBqh7J8/x0b8/4O+8wqN9/htU3bCSz3wkt2EmUOwaGY/Ek2TYfQgmZVUCE728cOBpA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=8wdqnr+ocdEdo0ipWTUDg27bb0wmY3hjmC/ggsTpAEE=; b=PTIC06c6Li2oZK1AyntBafWvSe0ZfjeMqxqgPo7KN+CnNmt9ZDnSZywRLG1a4tcRljqu65oVJwGf9/U3E8aKX38kL0dVuGwVkIeOXREr0jTEOvfui9T8LaAvxsiJTq+9Z3Wz8T+MAB0bVZU3mnCKVNekHZCipcKVCVLQqWY4CsFjpGeCi79tRnXNdsQv3YwgNtS4MBJR4c5+5DAaXlYXEiQU1WchpNmk0Uo+xf9F8bb0JCPGEeVeTxdGYy2mpuX4JOMUG1qTvc7EmUca6LlFy4lx7PhG2L8oDoHkD+DgPSMS3RcwajFupJ5PKkjMDwN5/rDw+08GXQ6B//CENOpVPA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=sourceware.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none Received: from MW2PR16CA0017.namprd16.prod.outlook.com (2603:10b6:907::30) by MWHPR12MB1616.namprd12.prod.outlook.com (2603:10b6:301:b::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4669.11; Fri, 5 Nov 2021 11:39:24 +0000 Received: from CO1NAM11FT042.eop-nam11.prod.protection.outlook.com (2603:10b6:907:0:cafe::24) by MW2PR16CA0017.outlook.office365.com (2603:10b6:907::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4669.11 via Frontend Transport; Fri, 5 Nov 2021 11:39:24 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; sourceware.org; dkim=none (message not signed) header.d=none;sourceware.org; dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; Received: from SATLEXMB04.amd.com (165.204.84.17) by CO1NAM11FT042.mail.protection.outlook.com (10.13.174.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.4669.10 via Frontend Transport; Fri, 5 Nov 2021 11:39:24 +0000 Received: from localhost.localdomain (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.15; Fri, 5 Nov 2021 06:39:23 -0500 From: Zoran Zaric To: Subject: [PATCH v4 19/28] Remove dwarf_expr_context from expr.h interface Date: Fri, 5 Nov 2021 11:38:40 +0000 Message-ID: <20211105113849.118800-20-zoran.zaric@amd.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211105113849.118800-1-zoran.zaric@amd.com> References: <20211105113849.118800-1-zoran.zaric@amd.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: SATLEXMB04.amd.com (10.181.40.145) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: cfd90ac6-2770-42a9-9cdd-08d9a050eac3 X-MS-TrafficTypeDiagnostic: MWHPR12MB1616: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:5236; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Cw/IYXVYdQtRUsixlEuRUSoydJdeTVU3p2A3zBL4FcbSwLtBxoAWw9lr8sDaqfIeeeA9ux5dyevhzJXl98xh4Blz+hphW2PeSC+LhN4PfkEg7m/tuwk74IUnZWvWcwt9Bki8oOcpWoxDfpI72Y2d06R+LuseZYwXCyv4QOeMagosV4m5W6le88BVWCPCf+2WknSXtt9NdgbbNUX2C/6fyxs2BldzLpQyWqLBgL3JRdxSzb+iKbFaFO4BBIxEmmiJjqYOtt5f9tBolUK3yu6hb81TZ5VMzBfwkRvYxkMFkfliuA18gngqSeSJUVmBylhwaN+v6ZN42dCEp0MvtJF/Yq3eOJLWdYvswhZz2vrOsCVC8kYN2fkj9J8WyKNC59XgLd66U1acSbP0CyVczcQ5t6rASQDd3n+xrVRcP055mkZCadDhOqZ0sZdmLC0/GUZQh9YwZ5/YUhcC9NOqm2RFKtXFTn8l+fdzJ5eoJ2ZQgaO5AOZ3V93c26NR6e4lx83byvpjnt+p4GWEWuG+tv9NqXwiDxL39nbtKdEaGWvGGz6RUT5Xu1hkIepkxKLGM74BOTGckdsosrNPCVHaSUYbmFRYaGOXB2c97LXj4Sz6SNb+1TJvkjPj9EH9/GY0Jye1q7VnnMThxPk3CUAYvlXh3JOGsXzua+ym67oabeiPkMGG9/bz0b6a7ZmuX2w8cLuQJy458M0F8SCLhmrMNMJXUGbrg2x69OjmUtAE9ybrAwA= X-Forefront-Antispam-Report: CIP:165.204.84.17; CTRY:US; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:SATLEXMB04.amd.com; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(4636009)(36840700001)(46966006)(5660300002)(356005)(4326008)(70206006)(8936002)(30864003)(6666004)(26005)(44832011)(2616005)(508600001)(81166007)(186003)(426003)(83380400001)(82310400003)(36860700001)(16526019)(36756003)(47076005)(70586007)(8676002)(86362001)(6916009)(336012)(2906002)(316002)(1076003)(36900700001); DIR:OUT; SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Nov 2021 11:39:24.4512 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: cfd90ac6-2770-42a9-9cdd-08d9a050eac3 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d; Ip=[165.204.84.17]; Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CO1NAM11FT042.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR12MB1616 X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Nov 2021 11:39:30 -0000 From: Zoran Zaric After the switch to the new evaluator implementation, it is now possible to completely remove the dwarf_expr_context class from the expr.h interface and encapsulate it inside the expr.c file. The new interface consists of a new function called dwarf2_evaluate that takes a DWARF expression stream, initial DWARF stack elements (in a form of a vector of a struct value objects), evaluation context and expected result type information. Function returns an evaluation result in a form of a struct value object. Currently, there is ever only one initial stack element provided to the evaluator and that element is always a memory address, so having a vector of struct value object might seems like an overkill. In reality this new flexibility allows implementation of a new DWARF attribute extensions that could provide any number of initial stack elements to describe any location description or value. gdb/ChangeLog: * dwarf2/expr.c (dwarf2_evaluate): New function. (struct dwarf_expr_context): Move from expr.h. (class dwarf_entry): Move from expr.h (dwarf_expr_context::push_address): Remove function. * dwarf2/expr.h (struct dwarf_expr_context): Move to expr.c. (class dwarf_entry): Move to expr.c. (address_type): Expose function. * dwarf2/frame.c (execute_stack_op): Now calls dwarf2_evaluate. * dwarf2/loc.c (dwarf2_evaluate_loc_desc_full): Now calls dwarf2_evaluate. (dwarf2_locexpr_baton_eval): Now calls dwarf2_evaluate. --- gdb/dwarf2/expr.c | 214 +++++++++++++++++++++++++++++++++++---------- gdb/dwarf2/expr.h | 165 +++++----------------------------- gdb/dwarf2/frame.c | 14 ++- gdb/dwarf2/loc.c | 23 +++-- 4 files changed, 214 insertions(+), 202 deletions(-) diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index ec7a8d13dc8..8ebc1dfdfe4 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -285,12 +285,7 @@ write_to_memory (CORE_ADDR address, const gdb_byte *buffer, length, buffer); } -/* Return the type used for DWARF operations where the type is - generic in the DWARF spec, the ARCH is a target architecture - of the type and ADDR_SIZE is expected size of the address. - Only certain sizes are supported. */ - -static type * +type * address_type (gdbarch *arch, int addr_size) { dwarf_gdbarch_types *types @@ -408,6 +403,23 @@ class computed_closure : public refcounted_object frame_info *m_frame = nullptr; }; +/* Base class that describes entries found on a DWARF expression + evaluation stack. */ + +class dwarf_entry +{ +protected: + /* Not expected to be called on it's own. */ + dwarf_entry () = default; + +public: + virtual ~dwarf_entry () = default; + + virtual std::unique_ptr clone () const = 0; +}; + +using dwarf_entry_up = std::unique_ptr; + /* Location description entry found on a DWARF expression evaluation stack. @@ -2400,11 +2412,130 @@ sect_variable_value (sect_offset sect_off, type, true); } +/* The expression evaluator works with a dwarf_expr_context, describing + its current state and its callbacks. */ +struct dwarf_expr_context +{ + /* Create a new context for the expression evaluator. + + We should ever only pass in the PER_OBJFILE and the ADDR_SIZE + information should be retrievable from there. The PER_OBJFILE + contains a pointer to the PER_BFD information anyway and the + address size information must be the same for the whole BFD. */ + dwarf_expr_context (dwarf2_per_objfile *per_objfile, + int addr_size); + + /* Evaluate the expression at ADDR (LEN bytes long) in a given PER_CU + FRAME context. INIT_VALUES vector contains values that are + expected to be pushed on a DWARF expression stack before the + evaluation. AS_LVAL defines if the returned struct value is + expected to be a value or a location description. Where TYPE, + SUBOBJ_TYPE and SUBOBJ_OFFSET describe expected struct value + representation of the evaluation result. The ADDR_INFO property + can be specified to override the range of memory addresses with + the passed in buffer. */ + struct value *evaluate (const gdb_byte *addr, size_t len, bool as_lval, + dwarf2_per_cu_data *per_cu, frame_info *frame, + std::vector *init_values, + const property_addr_info *addr_info, + struct type *type, struct type *subobj_type, + LONGEST subobj_offset); + +private: + /* The stack of DWARF entries. */ + std::vector m_stack; + + /* Target address size in bytes. */ + int m_addr_size; + + /* The current depth of dwarf expression recursion, via DW_OP_call*, + DW_OP_fbreg, DW_OP_push_object_address, etc., and the maximum + depth we'll tolerate before raising an error. */ + int m_recursion_depth = 0, m_max_recursion_depth = 0x100; + + /* We evaluate the expression in the context of this objfile. */ + dwarf2_per_objfile *m_per_objfile; + + /* Frame information used for the evaluation. */ + frame_info *m_frame = nullptr; + + /* Compilation unit used for the evaluation. */ + dwarf2_per_cu_data *m_per_cu = nullptr; + + /* Property address info used for the evaluation. */ + const property_addr_info *m_addr_info = nullptr; + + /* Evaluate the expression at ADDR (LEN bytes long). */ + void eval (const gdb_byte *addr, size_t len); + + /* Return the type used for DWARF operations where the type is + unspecified in the DWARF spec. Only certain sizes are + supported. */ + type *address_type () const; + + /* Push ENTRY onto the stack. */ + void push (dwarf_entry_up value); + + /* Return true if the expression stack is empty. */ + bool stack_empty_p () const; + + /* Pop a top element of the stack and add as a composite piece + with an BIT_OFFSET offset and of a BIT_SIZE size. + + If the following top element of the stack is a composite + location description, the piece will be added to it. Otherwise + a new composite location description will be created, pushed on + the stack and the piece will be added to that composite. */ + void add_piece (ULONGEST bit_size, ULONGEST bit_offset); + + /* The engine for the expression evaluator. Using the context in this + object, evaluate the expression between OP_PTR and OP_END. */ + void execute_stack_op (const gdb_byte *op_ptr, const gdb_byte *op_end); + + /* Pop the top item off of the stack. */ + dwarf_entry_up pop (); + + /* Retrieve the N'th item on the stack. */ + dwarf_entry &fetch (int n); + + /* Fetch the result of the expression evaluation in a form of + a struct value, where TYPE, SUBOBJ_TYPE and SUBOBJ_OFFSET + describe the source level representation of that result. + AS_LVAL defines if the fetched struct value is expected to + be a value or a location description. */ + value *fetch_result (struct type *type, struct type *subobj_type, + LONGEST subobj_offset, bool as_lval); + + /* Return the location expression for the frame base attribute, in + START and LENGTH. The result must be live until the current + expression evaluation is complete. */ + void get_frame_base (const gdb_byte **start, size_t *length); + + /* Return the base type given by the indicated DIE at DIE_CU_OFF. + This can throw an exception if the DIE is invalid or does not + represent a base type. */ + type *get_base_type (cu_offset die_cu_off); + + /* Execute DW_AT_location expression for the DWARF expression + subroutine in the DIE at DIE_CU_OFF in the CU. Do not touch + STACK while it being passed to and returned from the called DWARF + subroutine. */ + void dwarf_call (cu_offset die_cu_off); + + /* Push on DWARF stack an entry evaluated for DW_TAG_call_site's + parameter matching KIND and KIND_U at the caller of specified + BATON. If DEREF_SIZE is not -1 then use DW_AT_call_data_value + instead of DW_AT_call_value. */ + void push_dwarf_reg_entry_value (call_site_parameter_kind kind, + call_site_parameter_u kind_u, + int deref_size); +}; + /* Return the type used for DWARF operations where the type is unspecified in the DWARF spec. Only certain sizes are supported. */ -struct type * +type * dwarf_expr_context::address_type () const { return ::address_type (this->m_per_objfile->objfile->arch (), @@ -2420,26 +2551,12 @@ dwarf_expr_context::dwarf_expr_context (dwarf2_per_objfile *per_objfile, { } -/* See expr.h. */ - void dwarf_expr_context::push (dwarf_entry_up entry) { this->m_stack.emplace_back (std::move (entry)); } -/* See expr.h. */ - -void -dwarf_expr_context::push_address (CORE_ADDR addr, bool in_stack_memory) -{ - this->m_stack.emplace_back (std::make_unique - (this->m_per_objfile->objfile->arch (), addr, in_stack_memory)); -} - - -/* See expr.h. */ - dwarf_entry_up dwarf_expr_context::pop () { @@ -2451,8 +2568,6 @@ dwarf_expr_context::pop () return entry; } -/* See expr.h. */ - dwarf_entry & dwarf_expr_context::fetch (int n) { @@ -2463,8 +2578,6 @@ dwarf_expr_context::fetch (int n) return *this->m_stack[this->m_stack.size () - (1 + n)]; } -/* See expr.h. */ - void dwarf_expr_context::get_frame_base (const gdb_byte **start, size_t * length) @@ -2491,24 +2604,20 @@ dwarf_expr_context::get_frame_base (const gdb_byte **start, start, length); } -/* See expr.h. */ - -struct type * +type * dwarf_expr_context::get_base_type (cu_offset die_cu_off) { if (this->m_per_cu == nullptr) return builtin_type (this->m_per_objfile->objfile->arch ())->builtin_int; - struct type *result = dwarf2_get_die_type (die_cu_off, this->m_per_cu, - this->m_per_objfile); + type *result = dwarf2_get_die_type (die_cu_off, this->m_per_cu, + this->m_per_objfile); if (result == nullptr) error (_("Could not find type for operation")); return result; } -/* See expr.h. */ - void dwarf_expr_context::dwarf_call (cu_offset die_cu_off) { @@ -2532,8 +2641,6 @@ dwarf_expr_context::dwarf_call (cu_offset die_cu_off) this->eval (block.data, block.size); } -/* See expr.h. */ - void dwarf_expr_context::push_dwarf_reg_entry_value (call_site_parameter_kind kind, call_site_parameter_u kind_u, @@ -2580,8 +2687,6 @@ dwarf_expr_context::push_dwarf_reg_entry_value (call_site_parameter_kind kind, this->eval (data_src, size); } -/* See expr.h. */ - value * dwarf_expr_context::fetch_result (struct type *type, struct type *subobj_type, LONGEST subobj_offset, bool as_lval) @@ -2607,18 +2712,22 @@ dwarf_expr_context::fetch_result (struct type *type, struct type *subobj_type, } } -/* See expr.h. */ - value * dwarf_expr_context::evaluate (const gdb_byte *addr, size_t len, bool as_lval, dwarf2_per_cu_data *per_cu, frame_info *frame, - const struct property_addr_info *addr_info, + std::vector *init_values, + const property_addr_info *addr_info, struct type *type, struct type *subobj_type, LONGEST subobj_offset) { this->m_per_cu = per_cu; this->m_frame = frame; this->m_addr_info = addr_info; + gdbarch *arch = this->m_per_objfile->objfile->arch (); + + if (init_values != nullptr) + for (value *val : *init_values) + push (gdb_value_to_dwarf_entry (arch, val)); eval (addr, len); return fetch_result (type, subobj_type, subobj_offset, as_lval); @@ -2679,16 +2788,12 @@ get_signed_type (struct gdbarch *gdbarch, struct type *type) } } -/* See expr.h. */ - bool dwarf_expr_context::stack_empty_p () const { return this->m_stack.empty (); } -/* See expr.h. */ - void dwarf_expr_context::add_piece (ULONGEST bit_size, ULONGEST bit_offset) { @@ -2740,9 +2845,6 @@ dwarf_expr_context::add_piece (ULONGEST bit_size, ULONGEST bit_offset) composite->add_piece (std::move (piece), bit_size); } - -/* See expr.h. */ - void dwarf_expr_context::eval (const gdb_byte *addr, size_t len) { @@ -2981,8 +3083,6 @@ dwarf_block_to_sp_offset (struct gdbarch *gdbarch, const gdb_byte *buf, return 1; } -/* See expr.h. */ - void dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, const gdb_byte *op_end) @@ -3940,6 +4040,24 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, gdb_assert (this->m_recursion_depth >= 0); } +/* See expr.h. */ + +value * +dwarf2_evaluate (const gdb_byte *addr, size_t len, bool as_lval, + dwarf2_per_objfile *per_objfile, dwarf2_per_cu_data *per_cu, + frame_info *frame, int addr_size, + std::vector *init_values, + const property_addr_info *addr_info, + struct type *type, struct type *subobj_type, + LONGEST subobj_offset) +{ + dwarf_expr_context ctx (per_objfile, addr_size); + + return ctx.evaluate (addr, len, as_lval, per_cu, + frame, init_values, addr_info, + type, subobj_type, subobj_offset); +} + void _initialize_dwarf2expr (); void _initialize_dwarf2expr () diff --git a/gdb/dwarf2/expr.h b/gdb/dwarf2/expr.h index aa371e4bda6..df097f8867d 100644 --- a/gdb/dwarf2/expr.h +++ b/gdb/dwarf2/expr.h @@ -25,150 +25,31 @@ #include "leb128.h" #include "gdbtypes.h" -/* Base class that describes entries found on a DWARF expression - evaluation stack. */ - -class dwarf_entry -{ -protected: - /* Not expected to be called on it's own. */ - dwarf_entry () = default; - -public: - virtual ~dwarf_entry () = default; - - virtual std::unique_ptr clone () const = 0; -}; - -using dwarf_entry_up = std::unique_ptr; - struct dwarf2_per_objfile; -/* The expression evaluator works with a dwarf_expr_context, describing - its current state and its callbacks. */ -struct dwarf_expr_context -{ - /* Create a new context for the expression evaluator. - - We should ever only pass in the PER_OBJFILE and the ADDR_SIZE - information should be retrievable from there. The PER_OBJFILE - contains a pointer to the PER_BFD information anyway and the - address size information must be the same for the whole BFD. */ - dwarf_expr_context (dwarf2_per_objfile *per_objfile, int addr_size); - - virtual ~dwarf_expr_context () = default; - - /* Push ADDR onto the stack. */ - void push_address (CORE_ADDR addr, bool in_stack_memory); - - /* Evaluate the expression at ADDR (LEN bytes long) in a given PER_CU - and FRAME context. - - AS_LVAL defines if the returned struct value is expected to be a - value (false) or a location description (true). - - TYPE, SUBOBJ_TYPE and SUBOBJ_OFFSET describe the expected struct - value representation of the evaluation result. - - The ADDR_INFO property can be specified to override the range of - memory addresses with the passed in buffer. */ - value *evaluate (const gdb_byte *addr, size_t len, bool as_lval, - dwarf2_per_cu_data *per_cu, frame_info *frame, - const struct property_addr_info *addr_info = nullptr, - struct type *type = nullptr, - struct type *subobj_type = nullptr, - LONGEST subobj_offset = 0); - -private: - /* The stack of DWARF entries. */ - std::vector m_stack; - - /* Target address size in bytes. */ - int m_addr_size = 0; - - /* The current depth of dwarf expression recursion, via DW_OP_call*, - DW_OP_fbreg, DW_OP_push_object_address, etc., and the maximum - depth we'll tolerate before raising an error. */ - int m_recursion_depth = 0, m_max_recursion_depth = 0x100; - - /* We evaluate the expression in the context of this objfile. */ - dwarf2_per_objfile *m_per_objfile; - - /* Frame information used for the evaluation. */ - frame_info *m_frame = nullptr; - - /* Compilation unit used for the evaluation. */ - dwarf2_per_cu_data *m_per_cu = nullptr; - - /* Property address info used for the evaluation. */ - const struct property_addr_info *m_addr_info = nullptr; - - /* Evaluate the expression at ADDR (LEN bytes long). */ - void eval (const gdb_byte *addr, size_t len); - - /* Return the type used for DWARF operations where the type is - unspecified in the DWARF spec. Only certain sizes are - supported. */ - struct type *address_type () const; - - /* Push ENTRY onto the stack. */ - void push (dwarf_entry_up entry); - - /* Return true if the expression stack is empty. */ - bool stack_empty_p () const; - - /* Pop a top element of the stack and add as a composite piece - with an BIT_OFFSET offset and of a BIT_SIZE size. - - If the following top element of the stack is a composite - location description, the piece will be added to it. Otherwise - a new composite location description will be created, pushed on - the stack and the piece will be added to that composite. */ - void add_piece (ULONGEST bit_size, ULONGEST bit_offset); - - /* The engine for the expression evaluator. Using the context in - this object, evaluate the expression between OP_PTR and - OP_END. */ - void execute_stack_op (const gdb_byte *op_ptr, const gdb_byte *op_end); - - /* Pop the top item off of the stack. */ - dwarf_entry_up pop (); - - /* Retrieve the N'th item on the stack. */ - dwarf_entry &fetch (int n); - - /* Fetch the result of the expression evaluation in a form of - a struct value, where TYPE, SUBOBJ_TYPE and SUBOBJ_OFFSET - describe the source level representation of that result. - AS_LVAL defines if the fetched struct value is expected to - be a value or a location description. */ - value *fetch_result (struct type *type, struct type *subobj_type, - LONGEST subobj_offset, bool as_lval); - - /* Return the location expression for the frame base attribute, in - START and LENGTH. The result must be live until the current - expression evaluation is complete. */ - void get_frame_base (const gdb_byte **start, size_t *length); - - /* Return the base type given by the indicated DIE at DIE_CU_OFF. - This can throw an exception if the DIE is invalid or does not - represent a base type. */ - struct type *get_base_type (cu_offset die_cu_off); - - /* Execute DW_AT_location expression for the DWARF expression - subroutine in the DIE at DIE_CU_OFF in the CU. Do not touch - STACK while it being passed to and returned from the called DWARF - subroutine. */ - void dwarf_call (cu_offset die_cu_off); - - /* Push on DWARF stack an entry evaluated for DW_TAG_call_site's - parameter matching KIND and KIND_U at the caller of specified BATON. - If DEREF_SIZE is not -1 then use DW_AT_call_data_value instead of - DW_AT_call_value. */ - void push_dwarf_reg_entry_value (call_site_parameter_kind kind, - call_site_parameter_u kind_u, - int deref_size); -}; +/* Evaluate the expression at ADDR (LEN bytes long) in a given PER_CU + FRAME context. The PER_OBJFILE contains a pointer to the PER_BFD + information. ADDR_SIZE defines a size of the DWARF generic type. + INIT_VALUES vector contains values that are expected to be pushed + on a DWARF expression stack before the evaluation. AS_LVAL defines + if the returned struct value is expected to be a value or a location + description. Where TYPE, SUBOBJ_TYPE and SUBOBJ_OFFSET describe + expected struct value representation of the evaluation result. The + ADDR_INFO property can be specified to override the range of memory + addresses with the passed in buffer. */ +value *dwarf2_evaluate (const gdb_byte *addr, size_t len, bool as_lval, + dwarf2_per_objfile *per_objfile, + dwarf2_per_cu_data *per_cu, + frame_info *frame, int addr_size, + std::vector *init_values, + const struct property_addr_info *addr_info, + struct type *type = nullptr, + struct type *subobj_type = nullptr, + LONGEST subobj_offset = 0); + +/* Return the address type used of the ARCH architecture and + ADDR_SIZE is expected size of the type. */ +type *address_type (gdbarch *arch, int addr_size); /* Return the value of register number REG (a DWARF register number), read as an address in a given FRAME. */ diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c index f3d38771708..f97387a9d71 100644 --- a/gdb/dwarf2/frame.c +++ b/gdb/dwarf2/frame.c @@ -229,11 +229,19 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size, struct frame_info *this_frame, CORE_ADDR initial, int initial_in_stack_memory, dwarf2_per_objfile *per_objfile) { - dwarf_expr_context ctx (per_objfile, addr_size); scoped_value_mark free_values; + struct type *type = address_type (per_objfile->objfile->arch (), + addr_size); - ctx.push_address (initial, initial_in_stack_memory); - value *result_val = ctx.evaluate (exp, len, true, nullptr, this_frame); + value *init_value = value_at_lazy (type, initial); + std::vector init_values; + + set_value_stack (init_value, initial_in_stack_memory); + init_values.push_back (init_value); + + value *result_val + = dwarf2_evaluate (exp, len, true, per_objfile, nullptr, + this_frame, addr_size, &init_values, nullptr); if (VALUE_LVAL (result_val) == lval_memory) return value_address (result_val); diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c index eb128fa5fc6..753ebbbae6c 100644 --- a/gdb/dwarf2/loc.c +++ b/gdb/dwarf2/loc.c @@ -1474,15 +1474,15 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, if (size == 0) return allocate_optimized_out_value (subobj_type); - dwarf_expr_context ctx (per_objfile, per_cu->addr_size ()); - value *retval; scoped_value_mark free_values; try { - retval = ctx.evaluate (data, size, as_lval, per_cu, frame, nullptr, - type, subobj_type, subobj_byte_offset); + retval + = dwarf2_evaluate (data, size, as_lval, per_objfile, per_cu, + frame, per_cu->addr_size (), nullptr, nullptr, + type, subobj_type, subobj_byte_offset); } catch (const gdb_exception_error &ex) { @@ -1553,23 +1553,28 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton, dwarf2_per_objfile *per_objfile = dlbaton->per_objfile; dwarf2_per_cu_data *per_cu = dlbaton->per_cu; - dwarf_expr_context ctx (per_objfile, per_cu->addr_size ()); value *result; scoped_value_mark free_values; + std::vector init_values; if (push_initial_value) { + struct type *type = address_type (per_objfile->objfile->arch (), + per_cu->addr_size ()); + if (addr_stack != nullptr) - ctx.push_address (addr_stack->addr, false); + init_values.push_back (value_at_lazy (type, addr_stack->addr)); else - ctx.push_address (0, false); + init_values.push_back (value_at_lazy (type, 0)); } try { - result = ctx.evaluate (dlbaton->data, dlbaton->size, - true, per_cu, frame, addr_stack); + result + = dwarf2_evaluate (dlbaton->data, dlbaton->size, true, per_objfile, + per_cu, frame, per_cu->addr_size (), &init_values, + addr_stack); } catch (const gdb_exception_error &ex) { -- 2.17.1