From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id UKPfNqH+PGA3JAAAWB0awg (envelope-from ) for ; Mon, 01 Mar 2021 09:48:01 -0500 Received: by simark.ca (Postfix, from userid 112) id DDDA01EFC1; Mon, 1 Mar 2021 09:48:00 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,MSGID_FROM_MTA_HEADER,RDNS_NONE, URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2 Received: from sourceware.org (unknown [8.43.85.97]) (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 ESMTPS id 728251E590 for ; Mon, 1 Mar 2021 09:47:59 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id CC232393BC32; Mon, 1 Mar 2021 14:47:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CC232393BC32 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1614610078; bh=nYI2Bfh7kifadUMM2GIWmRfp7CpOx9lSqe/fd4twFmg=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=YZOEIjEyEKUgUuCuvSGTgo9EC6ZiJ4NZMaBopJ+Te3HRDJk65/Vy2JCxD9UKud1x2 WBNMgKWZ3l9lsegRXBAN0iOmx5UphB6O9BtRz1wlrXRPYnW8FwnGeiSWEKKbZQlKpD SZQ4TaQbepFweUeRELNoVBdIugJQcJgGGV3SuDWE= Received: from NAM12-BN8-obe.outbound.protection.outlook.com (mail-bn8nam12on2060.outbound.protection.outlook.com [40.107.237.60]) by sourceware.org (Postfix) with ESMTPS id D20A8393BC27 for ; Mon, 1 Mar 2021 14:47:54 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org D20A8393BC27 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=nR6NxhfsAoiHqqJRS3f3IB20CY0daFWI1DbaFBaOvIHCreTgDVNjx1sPbQOG8TE9dp0bRiFy7/OlS1P0TbIfUzQUo5fC+Eq8P0NB2oXuDH3lBMxFl37AT+CG9sIW3a3FXv36yu6mbgqdFGknW/j+I9FLCtwE6+Vdgf0SbjFO979ufk/twLGubGglbbH/OtPOHa5wdfpCmMBwD6vN1IacX2xgXJaEyyuZGEwhXwO4jdQgi92FL11cdJy9cT2HKkS5F6oO3qYK/m5wF1kBnPjAbo1TMDlqKD39lNXbhflpC0PoNrDKSBk4aNWd32wa0/3Nk1dZmfB/SFQ41J2x0PhH7g== 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-SenderADCheck; bh=nYI2Bfh7kifadUMM2GIWmRfp7CpOx9lSqe/fd4twFmg=; b=WVAKzH7VW3aWDoosAJRRhtlbig+h9TYuFLtwW3/7a/6QNqhhw+oufWJQvjJGsVkakOBga4mo/WUhcoCGO5ULoIEccCvX1l84wwSqx4uv7f6ZypF3WPlh686wk8a366itkilJIuQSmUL2BBisWjjgjbGeYotRg6su7Zv9UMcP3jORwviHEGPvh1nIfPXHxCvD6mnbukxzI6Y18J/MGDpnqOJ6POOs/0r+HMcWnM8Fym/vo0RFdILVh6R3BFrsbGtRXxdwQ2XEKf02tKTZYenJEI48gFFt8AehbfEmxtohlb43s+OvvBMqT/qdaqU21DMg8buwL6Fb+2wybe+R5htSGA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass header.d=amd.com; arc=none Received: from DM6PR12MB2762.namprd12.prod.outlook.com (2603:10b6:5:45::15) by DM5PR12MB2342.namprd12.prod.outlook.com (2603:10b6:4:ba::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3890.28; Mon, 1 Mar 2021 14:47:47 +0000 Received: from DM6PR12MB2762.namprd12.prod.outlook.com ([fe80::31d8:f503:f7b2:f44]) by DM6PR12MB2762.namprd12.prod.outlook.com ([fe80::31d8:f503:f7b2:f44%3]) with mapi id 15.20.3868.033; Mon, 1 Mar 2021 14:47:47 +0000 To: gdb-patches@sourceware.org Subject: [PATCH 35/43] Remove dwarf_expr_context from expr.h interface Date: Mon, 1 Mar 2021 14:46:12 +0000 Message-Id: <20210301144620.103016-36-Zoran.Zaric@amd.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210301144620.103016-1-Zoran.Zaric@amd.com> References: <20210301144620.103016-1-Zoran.Zaric@amd.com> Content-Type: text/plain X-Originating-IP: [2a00:23c7:5a85:6801:b4ed:fe7b:8064:d4d] X-ClientProxiedBy: AM0PR04CA0073.eurprd04.prod.outlook.com (2603:10a6:208:be::14) To DM6PR12MB2762.namprd12.prod.outlook.com (2603:10b6:5:45::15) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from localhost.localdomain (2a00:23c7:5a85:6801:b4ed:fe7b:8064:d4d) by AM0PR04CA0073.eurprd04.prod.outlook.com (2603:10a6:208:be::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3890.19 via Frontend Transport; Mon, 1 Mar 2021 14:47:18 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: dc680d86-2a8b-4fd3-de68-08d8dcc0ea3b X-MS-TrafficTypeDiagnostic: DM5PR12MB2342: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:3968; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: zj0LiEFn4eY2/QL4VCtFwYB2Q3XkyXTLLLmSVTqnsjB50LL8z9JZFLNHeGFOunUdsd9FS9UeJk83++RDyeBdVw0JYDbuKpdJjHqF2MhgrFCVOoip82gRgNlwBkMcK4rca5RL3/55aIVvFfvHXwDFQ7ctt2HEvy+u3Ww0bLdgAB+LCseNyOClBRVNMFaMEiDu6b0nl6vPKh8w7JH41xq4onEXbjrtck1yvNopvGYffv+dmdC1dN8yHyVKJnCIF8zFKaBac7swHvN3I9u+LfL2r3E8AREL4Ajhr62j4UbjZObiFXdY8vIpRr/4kZo8JmyZRZGgUTlCsvnebdDlzVtLh6t8ndWRRJKG+sokjCsvz0+r6v4AVIBHG1BGMsJz5CjdYtBeNNmBgYfAW93ZrEAEP5JBsn5lzUjY2VzGRZw79FCRKQTT8dKCF3Suhb7OcAzVv4DoudQkev45bfqzd/243MxpG3lbc+Ocs00rmWDCEH35IwmoCAjMyHlZTYJAR63okXLF70VpFV2pgYTlhqxJPdmnAVeNdEyJ9Wuakj/cqEV2kAhM0xsbbFyEmZ6IDltzFwPxM9bPBGKspCpAPfQUEg== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DM6PR12MB2762.namprd12.prod.outlook.com; PTR:; CAT:NONE; SFS:(4636009)(366004)(346002)(396003)(376002)(39860400002)(136003)(6486002)(66476007)(4326008)(478600001)(66556008)(2906002)(66946007)(69590400012)(316002)(52116002)(6666004)(6916009)(2616005)(86362001)(16526019)(6512007)(36756003)(8676002)(8936002)(6506007)(30864003)(5660300002)(186003)(1076003)(83380400001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData: =?us-ascii?Q?f5mnbdj2z1o8c9IEvV+fLzKp6GsOywdSr6VzEDLU6RTpbsyQLqrTP3g85xXH?= =?us-ascii?Q?TFtPRaMO+rqD8RYu0Yc77sWbuhudDJccn42EUuxyLBQ+pMTgs/bieSquwIOu?= =?us-ascii?Q?JOPZqEr2ZuTirLGrO/ULQq5NqBLuu4Rgu1OVjyI+gZjiDtBk5eSfPdG5c9HW?= =?us-ascii?Q?JtLnns6cx0uoc7/dQnJycd6J1zD8FjfXZE/WrIMdxUc0bQg6hNgOC8XVpvH3?= =?us-ascii?Q?JrbG6kK6rbfnw82QjB0hqQt9GJoDeQReBGObQxzel+iJpe/SF9CEnkusAr3h?= =?us-ascii?Q?PVEYGbnFhQGXWkenBwyGODvLPMekge+tcfw73NFU8BsK9+OtGzfYwpLBsFW8?= =?us-ascii?Q?4kxhRibcAphhDfozmGDraQK67TQgyCZkBNBEZO2Vpt+TIidpQD9v13d/+fyB?= =?us-ascii?Q?Gp/uagQ9f+U1IWAmUCOSvJxrRbx0pfieydl1W2eV3CQ9HinyYtGeq4RKv5v0?= =?us-ascii?Q?FeteQJxeZ6i53ttg8bdR1EEzy7OsbaWy5VQZrN0M6QSBx0HC8wQ5hZvwb7/V?= =?us-ascii?Q?pn42E8JKdPAoZD4zzz+Z+sFrrOG3HnUVbbz1uI5KrR1zriDd4A/xH0mwLZoM?= =?us-ascii?Q?abFlvA9U4ikt+Z75ndwRanBgrLytp/Uk2q1vadzj6gncPXsPqnckjABxOLZK?= =?us-ascii?Q?yOp0hOwXeimJL2VcC7Q4AlXHMmEptQxzTE3dpBfmkalgTWR23H0ikXFb5lK0?= =?us-ascii?Q?RPeTjpxmYYU9SGSZPu+yZlXYSWKa0um9rS1A8tVVfiOWejUVpCvh/MBpd5Jy?= =?us-ascii?Q?UPd8h2jdF/FrwC7vrPzuM7T3BHcqJPDDRI9hg+6bqUQRrrJA8OpAKQ8L0vw5?= =?us-ascii?Q?mqoZYBYiaF/JrhtBpJSU3Mrw0Qv4l4zrBAELH2+2PveDHSwShFY7a+qszY67?= =?us-ascii?Q?TT724ywg8lA3+IIJ17HDkJIqMhg8g/Vo6af4IdmcTMDIL9o7xG9c65/D+hj9?= =?us-ascii?Q?tRwwLHxQkOGYW6p67VePS8W/hRZLYJpgEmDNrRWniFGsvBlpKXXPewKGwP6w?= =?us-ascii?Q?CwLrdNfYfMZmwBOvH3Bhj5uX1JMf2IBIYNClOTUPzmtEUhZoPIU9cVaLibMM?= =?us-ascii?Q?0D+wKE8Fggn1zmE9wopGA9hZqoIIdiJTrCi38s+QLmV66wmqFEt4mrZ7z5Rd?= =?us-ascii?Q?4fGjZGkJp9PFrkJafyd902pSTQQI7qxC4wQVJ0iKW+ncFb/PRE7hi3QL0FWQ?= =?us-ascii?Q?5JxH7RAbtx/RG65afC+VbXOTE8ESD1qbT6nWoDUouUQnedwRuPQndi01b6d9?= =?us-ascii?Q?tTl9/++vtPd9Pydx9Hl4N5c4fPwhC8wDtA5epEgRAXDBO6DqM9A6bnZCgA9o?= =?us-ascii?Q?nZtpKf/ybr5wjS2UHUXMrtHEqwTZJtOLxhgzp/3x4PsGBmxlM8iOQgBHR6hT?= =?us-ascii?Q?NXJaMYwPHChxREkhz81RQijOAfEw?= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-Network-Message-Id: dc680d86-2a8b-4fd3-de68-08d8dcc0ea3b X-MS-Exchange-CrossTenant-AuthSource: DM6PR12MB2762.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Mar 2021 14:47:19.7926 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: UxDGL9wTFbkwM2XHwdnqKNDLx0n1L1MHZLTNA1UxyZmRsKvkBbpA3Q+mwHenmXUx/8gABeU6qCNf1G+lZp/PTg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR12MB2342 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: , From: Zoran Zaric via Gdb-patches Reply-To: Zoran Zaric Errors-To: gdb-patches-bounces@sourceware.org Sender: "Gdb-patches" 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. (dwarf_expr_context::push_address): Remove function. * dwarf2/expr.h (struct dwarf_expr_context): 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 | 199 +++++++++++++++++++++++++++++++++++---------- gdb/dwarf2/expr.h | 157 ++++++----------------------------- gdb/dwarf2/frame.c | 14 +++- gdb/dwarf2/loc.c | 23 ++++-- 4 files changed, 205 insertions(+), 188 deletions(-) diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index aa28d632442..7a091e74ce5 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -285,12 +285,9 @@ 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 struct type * + +struct type * address_type (struct gdbarch *gdbarch, int addr_size) { struct dwarf_gdbarch_types *types @@ -2221,6 +2218,137 @@ 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 (struct 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, + struct dwarf2_per_cu_data *per_cu, + struct frame_info *frame, + std::vector *init_values, + const struct property_addr_info *addr_info, + struct type *type, struct type *subobj_type, + LONGEST subobj_offset); + +private: + /* The stack of DWARF entries. */ + std::vector> stack; + + /* Target architecture to use for address operations. */ + struct gdbarch *gdbarch; + + /* Target address size in bytes. */ + int addr_size; + + /* DW_FORM_ref_addr size in bytes. If -1 DWARF is executed + from a frame context and operations depending on DW_FORM_ref_addr + are not allowed. */ + int ref_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 recursion_depth = 0, max_recursion_depth = 0x100; + + /* We evaluate the expression in the context of this objfile. */ + dwarf2_per_objfile *per_objfile; + + /* Frame information used for the evaluation. */ + struct frame_info *frame = nullptr; + + /* Compilation unit used for the evaluation. */ + struct dwarf2_per_cu_data *per_cu = nullptr; + + /* Property address info used for the evaluation. */ + const struct property_addr_info *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 (std::shared_ptr 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. + + If the fallowing 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 and + the piece will be added to that composite. */ + std::shared_ptr 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. */ + void pop (); + + /* Retrieve the N'th item on the stack. */ + std::shared_ptr 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. */ + struct 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. SIZE is non-zero if this function should + verify that the resulting type has the correct size. */ + struct type *get_base_type (cu_offset die_cu_off, int size); + + /* 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 (enum call_site_parameter_kind kind, + union 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. */ @@ -2241,26 +2369,12 @@ dwarf_expr_context::dwarf_expr_context (dwarf2_per_objfile *per_objfile, { } -/* See expr.h. */ - void dwarf_expr_context::push (std::shared_ptr entry) { stack.emplace_back (entry); } -/* See expr.h. */ - -void -dwarf_expr_context::push_address (CORE_ADDR addr, bool in_stack_memory) -{ - stack.emplace_back (std::make_shared (this->gdbarch, addr, - 0, in_stack_memory)); -} - - -/* See expr.h. */ - void dwarf_expr_context::pop () { @@ -2270,8 +2384,6 @@ dwarf_expr_context::pop () stack.pop_back (); } -/* See expr.h. */ - std::shared_ptr dwarf_expr_context::fetch (int n) { @@ -2282,8 +2394,6 @@ dwarf_expr_context::fetch (int n) return stack[stack.size () - (1 + n)]; } -/* See expr.h. */ - void dwarf_expr_context::get_frame_base (const gdb_byte **start, size_t * length) @@ -2310,8 +2420,6 @@ dwarf_expr_context::get_frame_base (const gdb_byte **start, start, length); } -/* See expr.h. */ - struct type * dwarf_expr_context::get_base_type (cu_offset die_cu_off, int size) { @@ -2329,8 +2437,6 @@ dwarf_expr_context::get_base_type (cu_offset die_cu_off, int size) return result; } -/* See expr.h. */ - void dwarf_expr_context::dwarf_call (cu_offset die_cu_off) { @@ -2354,8 +2460,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 (enum call_site_parameter_kind kind, @@ -2405,8 +2509,6 @@ dwarf_expr_context::push_dwarf_reg_entry_value this->eval (data_src, size); } -/* See expr.h. */ - struct value * dwarf_expr_context::fetch_result (struct type *type, struct type *subobj_type, @@ -2429,12 +2531,11 @@ dwarf_expr_context::fetch_result (struct type *type, return entry->to_gdb_value (this->frame, type, subobj_type, subobj_offset); } -/* See expr.h. */ - struct value * dwarf_expr_context::evaluate (const gdb_byte *addr, size_t len, bool as_lval, struct dwarf2_per_cu_data *per_cu, struct frame_info *frame, + std::vector *init_values, const struct property_addr_info *addr_info, struct type *type, struct type *subobj_type, @@ -2447,6 +2548,10 @@ dwarf_expr_context::evaluate (const gdb_byte *addr, size_t len, bool as_lval, if (per_cu != nullptr) this->ref_addr_size = per_cu->ref_addr_size (); + if (init_values != nullptr) + for (unsigned int i = 0; i < init_values->size (); i++) + push (gdb_value_to_dwarf_entry (this->gdbarch, (*init_values)[i])); + eval (addr, len); return fetch_result (type, subobj_type, subobj_offset, as_lval); } @@ -2506,16 +2611,12 @@ get_signed_type (struct gdbarch *gdbarch, struct type *type) } } -/* See expr.h. */ - bool dwarf_expr_context::stack_empty_p () const { return stack.empty (); } -/* See expr.h. */ - std::shared_ptr dwarf_expr_context::add_piece (ULONGEST bit_size, ULONGEST bit_offset) { @@ -2549,9 +2650,6 @@ dwarf_expr_context::add_piece (ULONGEST bit_size, ULONGEST bit_offset) return composite; } - -/* See expr.h. */ - void dwarf_expr_context::eval (const gdb_byte *addr, size_t len) { @@ -2790,8 +2888,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) @@ -3729,6 +3825,25 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, gdb_assert (this->recursion_depth >= 0); } +/* See expr.h. */ + +struct value * +dwarf2_evaluate (const gdb_byte *addr, size_t len, bool as_lval, + struct dwarf2_per_objfile *per_objfile, + struct dwarf2_per_cu_data *per_cu, + struct frame_info *frame, int addr_size, + std::vector *init_values, + const struct 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 5170ac2df43..132f924014f 100644 --- a/gdb/dwarf2/expr.h +++ b/gdb/dwarf2/expr.h @@ -25,142 +25,31 @@ #include "leb128.h" #include "gdbtypes.h" -class dwarf_entry; 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 (struct 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 - FRAME context. 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, - struct dwarf2_per_cu_data *per_cu, - struct 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> stack; - - /* Target architecture to use for address operations. */ - struct gdbarch *gdbarch = nullptr; - - /* Target address size in bytes. */ - int addr_size = 0; - - /* DW_FORM_ref_addr size in bytes. If -1 DWARF is executed from a frame - context and operations depending on DW_FORM_ref_addr are not allowed. */ - int ref_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 recursion_depth = 0, max_recursion_depth = 0x100; - - /* We evaluate the expression in the context of this objfile. */ - dwarf2_per_objfile *per_objfile; - - /* Frame information used for the evaluation. */ - struct frame_info *frame = nullptr; - - /* Compilation unit used for the evaluation. */ - struct dwarf2_per_cu_data *per_cu = nullptr; - - /* Property address info used for the evaluation. */ - const struct property_addr_info *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 (std::shared_ptr 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 and - the piece will be added to that composite. */ - std::shared_ptr 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. */ - void pop (); - - /* Retrieve the N'th item on the stack. */ - std::shared_ptr 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. */ - struct 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. SIZE is non-zero if this function should - verify that the resulting type has the correct size. */ - struct type *get_base_type (cu_offset die_cu_off, int size); - - /* 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 (enum call_site_parameter_kind kind, - union 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. */ +struct value *dwarf2_evaluate (const gdb_byte *addr, size_t len, bool as_lval, + struct dwarf2_per_objfile *per_objfile, + struct dwarf2_per_cu_data *per_cu, + struct 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 GDBARCH architecture and + ADDR_SIZE is expected size of the type. */ +struct type *address_type (struct gdbarch *gdbarch, 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 51d308fd94f..97bd0d35319 100644 --- a/gdb/dwarf2/frame.c +++ b/gdb/dwarf2/frame.c @@ -228,11 +228,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); - struct value *result_val = ctx.evaluate (exp, len, true, nullptr, this_frame); + struct 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); + + struct 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 c53413a942f..7dfe28c3e46 100644 --- a/gdb/dwarf2/loc.c +++ b/gdb/dwarf2/loc.c @@ -1434,15 +1434,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 ()); - struct 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) { @@ -1513,23 +1513,28 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton, dwarf2_per_objfile *per_objfile = dlbaton->per_objfile; struct dwarf2_per_cu_data *per_cu = dlbaton->per_cu; - dwarf_expr_context ctx (per_objfile, per_cu->addr_size ()); struct 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