From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM12-MW2-obe.outbound.protection.outlook.com (mail-mw2nam12on2045.outbound.protection.outlook.com [40.107.244.45]) by sourceware.org (Postfix) with ESMTPS id 398613951C10 for ; Mon, 7 Dec 2020 19:01:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 398613951C10 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=hXzeAY3y0wp8q1sMXNCf2DoEpe3vEtW75C6fGldb4eV3H3MyKbbIpMipYQ0NnqvzOPgqr6IrJKmzEBde8f5iDYZAkFlgSYss4KKYXSCftrK5tNK9rUp5FXVJqi6SJUjht8SVf9k5yT3prrpa3u/liwm/ELlxJ0ePlRgQXkBaH2busBWorR1gISwtlQ0AxT+to4VQR+fXc1JlidyDQiyx3JVzuXoe4lIP3pLpwqc83+cYwM5M3wEz5pAtAz4WoK2UWWqCY9ur2iw7BxpgYzKHFzLwgOL40TVnZqpkh8x2WkpYoR7mNiVGJ6xm/GSKseoOw1FY2crNveZazWvleaX7Ng== 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=mZV269VhLmpbopL4lVdnkK84gc7rqo3NNW8bNeMa3rc=; b=Tau0Du1t+Hl3aAsGu/Gz+drdmMgk2MNAxgW4yJXXdRyp3PqmK6ZqXBDFt8CPgJMAd7y+xtfkhpmrrYuPeHPFPuXhUNSOmafbRX9tojXAZj33tpXruPg68cdR2dxTKyczjsqkEB4yP5CY8SdaJ04wOsev+gsdRYgdpA9VqNZM7ZylO7M/33eNQxNBBCauv78DkxF+0oQRokUBPt7grLLpCWDPD8XgPGPVOrc17n1y5+HQpo761fdcyZv343kOyYt/phiX3NNiM+5W7iRdJOi7kD2qF3PVvW64YR/7rdJrl2cqP0OggPhs7Zhk+nuksDObxgEzqcH5RxPRezM8qm7n1w== 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 DM6PR12MB4561.namprd12.prod.outlook.com (2603:10b6:5:2ac::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3632.18; Mon, 7 Dec 2020 19:01:22 +0000 Received: from DM6PR12MB2762.namprd12.prod.outlook.com ([fe80::6841:61df:984b:b3c]) by DM6PR12MB2762.namprd12.prod.outlook.com ([fe80::6841:61df:984b:b3c%3]) with mapi id 15.20.3632.021; Mon, 7 Dec 2020 19:01:20 +0000 From: Zoran Zaric To: gdb-patches@sourceware.org Cc: Zoran Zaric Subject: [PATCH 19/30] Add new location description access interface Date: Mon, 7 Dec 2020 19:00:20 +0000 Message-Id: <20201207190031.13341-20-Zoran.Zaric@amd.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201207190031.13341-1-Zoran.Zaric@amd.com> References: <20201207190031.13341-1-Zoran.Zaric@amd.com> Content-Type: text/plain X-Originating-IP: [2a00:23c7:5a85:6801:5c7:2db6:d2c2:ae4e] X-ClientProxiedBy: AM4PR0101CA0053.eurprd01.prod.exchangelabs.com (2603:10a6:200:41::21) 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:5c7:2db6:d2c2:ae4e) by AM4PR0101CA0053.eurprd01.prod.exchangelabs.com (2603:10a6:200:41::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3632.17 via Frontend Transport; Mon, 7 Dec 2020 19:01:19 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: b72e39ca-f423-4783-7481-08d89ae27bd7 X-MS-TrafficTypeDiagnostic: DM6PR12MB4561: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:923; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Cogye0qQJOoO6MUnXTCO2J00zFZUhhJ0hJuXrbsLFIBQxCi/Vo9P4eUM7Ml1ij+R2a4yjme/4Ic7ClHko+y9wffKLRQ5D7+CAwZtVArKNvP9MipUjUmVFZxH7boXT4xWS/uYrtjPvxn6pi/W2FHSA/0KRSZDNFPGsqei+DMu7+DLj7sdWybIYZtlYNLk5KpbriXEQFnVVcmqhVCTQIT1P/QG23C6QL2hXuVBI6AzLoL1ODWm8pmLlyLwQy4hPmNS2qxuwPmKihbnFvSnO9aUCDASrSbsRlmbUmEQH3jLhN3E0KinL28hyQ1dRSlxPdYFXT8owEyd3M/w8nxBC9UwgH03XZGpNH0N/s4IdbVxOX9Iby5RGFbeKT1XRw+8nODM 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)(376002)(346002)(39860400002)(366004)(136003)(396003)(1076003)(30864003)(83380400001)(86362001)(6506007)(4326008)(69590400008)(52116002)(36756003)(2906002)(6512007)(8676002)(6486002)(16526019)(2616005)(66946007)(66476007)(66556008)(6916009)(5660300002)(186003)(8936002)(478600001)(6666004)(316002); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData: =?us-ascii?Q?uah7h9PJ7ATcV9CK6MOdXa+0gsV1rlAcIZor+vP9CyXAH0ximd30HLrW3FBg?= =?us-ascii?Q?QFQXFJ5pPe0v4R7Ryd+8vkhMAuulAhNKbkvYelap/s9KtVZmHHFkmYy33Goa?= =?us-ascii?Q?qdqrsrx3xDsx/8+FII3YsT8uVMp4jalN83/inkJHSzuFU/Q1UsKGK6mcR1u5?= =?us-ascii?Q?ivQhaSKqrNslUr0yIM2B3w2l9jENGgWXf7wI7RZFG1bF2qZ+mYxz415qXaYK?= =?us-ascii?Q?JZ3eoARrSBYZtaBloXW38GAMguiymBfNtChn/BXcjng1CakP+YTKUIpvXNAr?= =?us-ascii?Q?yZviW8WiDgGo1V8n7PdcyJNqB954FYKuG5JKQQpYDdN/7/jv0iWIn1YgXnTe?= =?us-ascii?Q?AhRwWwqUkL2a3NJgBQ3adM8SS6al65YEIihXQP8ERaIFoFQEO+UtzkhkD5Kz?= =?us-ascii?Q?O09gENHICWXGWaQVoaM1MX5herElLAvHNUUjtsKWwQOPXCTEDGVRlQWKfM0i?= =?us-ascii?Q?yLNo2f8w3p5OVZpiC5bCtVCQ/ZySaQc6pPORflcsUt64Vex1PVMpZ3L05zud?= =?us-ascii?Q?q8mdTHUzF63VX1eyoHBy1Hypox0le1X3iFzm/4mk39fqBYV0TOvwuQjxwj6d?= =?us-ascii?Q?0xfHw5viHXQ7n7Qfsn4HHCFwULy4OczGjVW9niCsPpIV6C057kpCLsfqMvrh?= =?us-ascii?Q?01bq+QGnQnkPe8TLDXTQYBiTIpkaZKCO7cfSJvtdUVjphUyNLgNBsyleQZgq?= =?us-ascii?Q?esb863z+JQ3rqSbIIxfWOg/f0b/5HZ3TIEr7LLfK6hOJKi7+OhZk8E6CPnej?= =?us-ascii?Q?MouFmP0VgcW+/NQK41YL4YpDOZOMtcuABIdTGNGLVhNK3RPCLmJqKYflGzCL?= =?us-ascii?Q?D9Uwmb/FP4kmdf1Yg8siRcUByjDK2EQHg/ZrHDqN85GFQpDHCscSg064PTam?= =?us-ascii?Q?1+OWMTmvvQPOxBNpnb75s1DRbJItTELgPsVfMhiWRcHq8aHAAhsb+25PqKow?= =?us-ascii?Q?4Y8GJW909U6fOAD/gkh92Df+w1YQtC/rRwqi1w/ynWMuToXFwxPjnqc17FCC?= =?us-ascii?Q?Ll5ZCvU67Y+JYT593IpvOWPlzaLFHBz/6VrJ99aLsszKR5u+X/4IOp2ixgRL?= =?us-ascii?Q?HcdkEgFF?= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-AuthSource: DM6PR12MB2762.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Dec 2020 19:01:20.2609 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-Network-Message-Id: b72e39ca-f423-4783-7481-08d89ae27bd7 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: xcfiAAyqZgat5LkS0XhTsMJEQ76lMXYpFEJItRPXHDrmWiVue9X0GyxijNBm92i3Ozm8lXHc5CQHsCbxLvZavQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB4561 X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, GIT_PATCH_0, MSGID_FROM_MTA_HEADER, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: Mon, 07 Dec 2020 19:01:35 -0000 After adding interface for register and memory location access, a new top level interface for accessing any location, described by the dwarf_location class based objects, can now be defined. Also, the address_type method is now needed to be outside of the dwarf_stack_value class to allow creation of the DWARF generic type independently of that class. * dwarf2/expr.c (read_from_location): New function. (write_to_location): New function. (address_type): New function. * dwarf2/expr.h (address_type): Exposed function. --- gdb/dwarf2/expr.c | 427 ++++++++++++++++++++++++++++++++++++++++++++-- gdb/dwarf2/expr.h | 4 + 2 files changed, 420 insertions(+), 11 deletions(-) diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index c0bb06fc4c..fea82f8a87 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -613,6 +613,404 @@ class dwarf_composite : public dwarf_location std::vector m_pieces; }; +/* Read contents from the location specified by the DWARF location + description entry LOCATION. + + The read operation is performed in the context of FRAME. BIT_SIZE + is the number of bits to read. The data read is copied to the + caller-managed buffer BUF. BIG_ENDIAN defines the endianness of + the target. BITS_TO_SKIP is a bit offset into the location and + BUF_BIT_OFFSET is buffer BUF's bit offset. LOCATION_BIT_LIMIT is a + a maximum number of bits that location can hold, where value zero + signifies that there is no such restriction. + + Note that some location types can be read without a FRAME context. + + If the location is optimized out or unavailable, the OPTIMIZED and + UNAVAILABLE outputs are set accordingly. */ + +static void +read_from_location (const dwarf_location *location, struct frame_info *frame, + LONGEST bits_to_skip, gdb_byte *buf, int buf_bit_offset, + size_t bit_size, size_t location_bit_limit, + bool big_endian, int* optimized, int* unavailable) +{ + LONGEST offset = location->get_offset (); + LONGEST bit_suboffset = location->get_bit_suboffset (); + LONGEST total_bits_to_skip = bits_to_skip; + size_t read_bit_limit = location_bit_limit; + gdb::byte_vector temp_buf; + + /* Reads from undefined locations are always marked as optimized + out. */ + if (dynamic_cast (location) != nullptr) + { + (*unavailable) = 0; + (*optimized) = 1; + } + else if (auto register_entry + = dynamic_cast (location)) + { + struct gdbarch *arch = get_frame_arch (frame); + int reg = dwarf_reg_to_regnum_or_error (arch, + register_entry->get_regnum ()); + ULONGEST reg_bits = HOST_CHAR_BIT * register_size (arch, reg); + + if (big_endian) + { + if (!read_bit_limit || reg_bits <= read_bit_limit) + read_bit_limit = bit_size; + + total_bits_to_skip + += reg_bits - (offset * HOST_CHAR_BIT + + bit_suboffset + read_bit_limit); + } + else + total_bits_to_skip += offset * HOST_CHAR_BIT + bit_suboffset; + + LONGEST this_size = bits_to_bytes (total_bits_to_skip, bit_size); + temp_buf.resize (this_size); + + /* Can only read from a register on byte granularity so an + additional buffer is required. */ + read_from_register (frame, reg, total_bits_to_skip / HOST_CHAR_BIT, + this_size, temp_buf.data (), optimized, unavailable); + + /* Only copy data if valid. */ + if (!(*optimized) && !(*unavailable)) + copy_bitwise (buf, buf_bit_offset, temp_buf.data (), + total_bits_to_skip % HOST_CHAR_BIT, + bit_size, big_endian); + } + else if (auto memory_entry = dynamic_cast (location)) + { + CORE_ADDR start_address + = offset + (bit_suboffset + total_bits_to_skip) / HOST_CHAR_BIT; + + (*optimized) = 0; + total_bits_to_skip += bit_suboffset; + + if ((total_bits_to_skip % HOST_CHAR_BIT) == 0 + && (bit_size % HOST_CHAR_BIT) == 0 + && (buf_bit_offset % HOST_CHAR_BIT) == 0) + { + /* Everything is byte-aligned, no buffer needed. */ + read_from_memory (start_address, + buf + buf_bit_offset / HOST_CHAR_BIT, + bit_size / HOST_CHAR_BIT, + memory_entry->in_stack (), unavailable); + } + else + { + LONGEST this_size = bits_to_bytes (total_bits_to_skip, bit_size); + temp_buf.resize (this_size); + + /* Can only read from memory on byte granularity so an + additional buffer is required. */ + read_from_memory (start_address, temp_buf.data (), this_size, + memory_entry->in_stack (), unavailable); + + if (!(*unavailable)) + copy_bitwise (buf, buf_bit_offset, temp_buf.data (), + total_bits_to_skip % HOST_CHAR_BIT, + bit_size, big_endian); + } + } + else if (auto implicit_entry + = dynamic_cast (location)) + { + ULONGEST literal_bit_size = HOST_CHAR_BIT * implicit_entry->get_size (); + + (*optimized) = 0; + (*unavailable) = 0; + + /* Cut off at the end of the implicit value. */ + if (implicit_entry->get_byte_order() == BFD_ENDIAN_BIG) + { + if (!read_bit_limit || read_bit_limit > literal_bit_size) + read_bit_limit = bit_size; + + total_bits_to_skip + += literal_bit_size - (offset * HOST_CHAR_BIT + + bit_suboffset + read_bit_limit); + } + else + total_bits_to_skip += offset * HOST_CHAR_BIT + bit_suboffset; + + if (total_bits_to_skip >= literal_bit_size) + { + (*unavailable) = 1; + return; + } + + if (bit_size > literal_bit_size - total_bits_to_skip) + bit_size = literal_bit_size - total_bits_to_skip; + + copy_bitwise (buf, buf_bit_offset, implicit_entry->get_contents (), + total_bits_to_skip, bit_size, big_endian); + } + else if (auto pointer_entry + = dynamic_cast (location)) + { + struct frame_info *read_frame = frame; + + if (read_frame == nullptr) + read_frame = get_selected_frame (_("No frame selected.")); + + struct type *type = address_type (get_frame_arch (read_frame), + pointer_entry->get_addr_size ()); + + struct value *value + = indirect_synthetic_pointer (pointer_entry->get_die_offset (), + pointer_entry->get_offset (), + pointer_entry->get_per_cu (), + pointer_entry->get_per_objfile (), + read_frame, type); + + total_bits_to_skip += bit_suboffset; + + gdb_byte *value_contents + = value_contents_raw (value) + total_bits_to_skip / HOST_CHAR_BIT; + + if ((total_bits_to_skip % HOST_CHAR_BIT) == 0 + && (bit_size % HOST_CHAR_BIT) == 0 + && (buf_bit_offset % HOST_CHAR_BIT) == 0) + { + memcpy (buf + buf_bit_offset / HOST_CHAR_BIT, + value_contents, bit_size / HOST_CHAR_BIT); + } + else + { + copy_bitwise (buf, buf_bit_offset, value_contents, + total_bits_to_skip % HOST_CHAR_BIT, + bit_size, big_endian); + } + } + else if (auto composite_entry + = dynamic_cast (location)) + { + unsigned int pieces_num = composite_entry->get_pieces_num (); + unsigned int i; + + total_bits_to_skip += offset * HOST_CHAR_BIT + bit_suboffset; + + /* Skip pieces covered by the read offset. */ + for (i = 0; i < pieces_num; i++) + { + LONGEST piece_bit_size = composite_entry->get_bit_size_at (i); + + if (total_bits_to_skip < piece_bit_size) + break; + + total_bits_to_skip -= piece_bit_size; + } + + for (; i < pieces_num; i++) + { + LONGEST piece_bit_size = composite_entry->get_bit_size_at (i); + LONGEST actual_bit_size = piece_bit_size; + + if (actual_bit_size > bit_size) + actual_bit_size = bit_size; + + read_from_location (composite_entry->get_piece_at (i), frame, + total_bits_to_skip, buf, buf_bit_offset, + actual_bit_size, piece_bit_size, big_endian, + optimized, unavailable); + + if (bit_size == actual_bit_size || (*optimized) || (*unavailable)) + break; + + buf_bit_offset += actual_bit_size; + bit_size -= actual_bit_size; + } + } + else + internal_error (__FILE__, __LINE__, _("invalid location type")); +} + +/* Write contents to a location specified by the DWARF location + description entry LOCATION. + + The write operation is performed in the context of FRAME. BIT_SIZE + is the number of bits written. The data written is copied from the + caller-managed BUF buffer. BIG_ENDIAN defines an endianness of the + target. BITS_TO_SKIP is a bit offset into the location and + BUF_BIT_OFFSET is buffer BUF's bit offset. LOCATION_BIT_LIMIT is a + a maximum number of bits that location can hold, where value zero + signifies that there is no such restriction. + + Note that some location types can be written without a FRAME + context. + + If the location is optimized out or unavailable, the OPTIMIZED and + UNAVAILABLE outputs are set. */ + +static void +write_to_location (const dwarf_location *location, struct frame_info *frame, + LONGEST bits_to_skip, const gdb_byte *buf, + int buf_bit_offset, size_t bit_size, + size_t location_bit_limit, bool big_endian, + int* optimized, int* unavailable) +{ + LONGEST offset = location->get_offset(); + LONGEST bit_suboffset = location->get_bit_suboffset(); + LONGEST total_bits_to_skip = bits_to_skip; + size_t write_bit_limit = location_bit_limit; + gdb::byte_vector temp_buf; + + /* Writes to undefined locations are always marked as optimized + out. */ + if (dynamic_cast (location) != nullptr) + { + (*unavailable) = 0; + (*optimized) = 1; + } + else if (auto register_entry + = dynamic_cast (location)) + { + struct gdbarch *arch = get_frame_arch (frame); + int gdb_regnum + = dwarf_reg_to_regnum_or_error (arch, register_entry->get_regnum ()); + ULONGEST reg_bits = HOST_CHAR_BIT * register_size (arch, gdb_regnum); + + if (big_endian) + { + if (!write_bit_limit || reg_bits <= write_bit_limit) + write_bit_limit = bit_size; + + total_bits_to_skip + += reg_bits - (offset * HOST_CHAR_BIT + + bit_suboffset + write_bit_limit); + } + else + total_bits_to_skip += offset * HOST_CHAR_BIT + bit_suboffset; + + LONGEST this_size = bits_to_bytes (total_bits_to_skip, bit_size); + temp_buf.resize (this_size); + + if (total_bits_to_skip % HOST_CHAR_BIT != 0 + || bit_size % HOST_CHAR_BIT != 0) + { + /* Contents is copied non-byte-aligned into the register. + Need some bits from original register value. */ + read_from_register (frame, gdb_regnum, + total_bits_to_skip / HOST_CHAR_BIT, + this_size, temp_buf.data (), optimized, + unavailable); + } + + copy_bitwise (temp_buf.data (), total_bits_to_skip % HOST_CHAR_BIT, buf, + buf_bit_offset, bit_size, big_endian); + + write_to_register (frame, gdb_regnum, total_bits_to_skip / HOST_CHAR_BIT, + this_size, temp_buf.data (), optimized, unavailable); + } + else if (auto memory_entry = dynamic_cast (location)) + { + CORE_ADDR start_address + = offset + (bit_suboffset + total_bits_to_skip) / HOST_CHAR_BIT; + + total_bits_to_skip += bit_suboffset; + (*optimized) = 0; + + if ((total_bits_to_skip % HOST_CHAR_BIT == 0) + && (bit_size % HOST_CHAR_BIT == 0) + && (buf_bit_offset % HOST_CHAR_BIT == 0)) + { + /* Everything is byte-aligned; no buffer needed. */ + write_to_memory (start_address, + buf + buf_bit_offset / HOST_CHAR_BIT, + bit_size / HOST_CHAR_BIT, memory_entry->in_stack (), + unavailable); + } + else + { + LONGEST this_size = bits_to_bytes (total_bits_to_skip, bit_size); + temp_buf.resize (this_size); + + if (total_bits_to_skip % HOST_CHAR_BIT != 0 + || bit_size % HOST_CHAR_BIT != 0) + { + if (this_size <= HOST_CHAR_BIT) + /* Perform a single read for small sizes. */ + read_from_memory (start_address, temp_buf.data (), + this_size, memory_entry->in_stack (), + unavailable); + else + { + /* Only the first and last bytes can possibly have + any bits reused. */ + read_from_memory (start_address, temp_buf.data (), + 1, memory_entry->in_stack (), unavailable); + + if (!(*unavailable)) + read_from_memory (start_address + this_size - 1, + &temp_buf[this_size - 1], 1, + memory_entry->in_stack (), unavailable); + } + } + + copy_bitwise (temp_buf.data (), total_bits_to_skip % HOST_CHAR_BIT, + buf, buf_bit_offset, bit_size, big_endian); + + write_to_memory (start_address, temp_buf.data (), this_size, + memory_entry->in_stack (), unavailable); + } + } + else if (dynamic_cast (location) != nullptr) + { + (*optimized) = 1; + (*unavailable) = 0; + } + else if (dynamic_cast (location) != nullptr) + { + (*optimized) = 1; + (*unavailable) = 0; + } + else if (auto composite_entry + = dynamic_cast (location)) + { + unsigned int pieces_num = composite_entry->get_pieces_num (); + unsigned int i; + + total_bits_to_skip += offset * HOST_CHAR_BIT + bit_suboffset; + + /* Skip pieces covered by the write offset. */ + for (i = 0; i < pieces_num; i++) + { + LONGEST piece_bit_size = composite_entry->get_bit_size_at (i); + + if (total_bits_to_skip < piece_bit_size) + break; + + total_bits_to_skip -= piece_bit_size; + } + + for (; i < pieces_num; i++) + { + LONGEST piece_bit_size = composite_entry->get_bit_size_at (i); + LONGEST actual_bit_size = piece_bit_size; + + if (actual_bit_size > bit_size) + actual_bit_size = bit_size; + + write_to_location (composite_entry->get_piece_at (i), frame, + total_bits_to_skip, buf, buf_bit_offset, + actual_bit_size, piece_bit_size, + big_endian, optimized, unavailable); + + if (bit_size == actual_bit_size || (*optimized) || (*unavailable)) + break; + + buf_bit_offset += actual_bit_size; + bit_size -= actual_bit_size; + } + } + else + internal_error (__FILE__, __LINE__, _("invalid location type")); +} + struct piece_closure { /* Reference count. */ @@ -1190,37 +1588,44 @@ sect_variable_value (sect_offset sect_off, type, true); } -/* Return the type used for DWARF operations where the type is - unspecified in the DWARF spec. Only certain sizes are - supported. */ +/* See expr.h. */ struct type * -dwarf_expr_context::address_type () const +address_type (struct gdbarch *gdbarch, int addr_size) { struct dwarf_gdbarch_types *types - = (struct dwarf_gdbarch_types *) gdbarch_data (this->gdbarch, + = (struct dwarf_gdbarch_types *) gdbarch_data (gdbarch, dwarf_arch_cookie); int ndx; - if (this->addr_size == 2) + if (addr_size == 2) ndx = 0; - else if (this->addr_size == 4) + else if (addr_size == 4) ndx = 1; - else if (this->addr_size == 8) + else if (addr_size == 8) ndx = 2; else error (_("Unsupported address size in DWARF expressions: %d bits"), - 8 * this->addr_size); + 8 * addr_size); if (types->dw_types[ndx] == NULL) types->dw_types[ndx] - = arch_integer_type (this->gdbarch, - 8 * this->addr_size, + = arch_integer_type (gdbarch, HOST_CHAR_BIT * addr_size, 0, ""); return types->dw_types[ndx]; } +/* Return the type used for DWARF operations where the type is + unspecified in the DWARF spec. Only certain sizes are + supported. */ + +struct type * +dwarf_expr_context::address_type () const +{ + return ::address_type (this->gdbarch, this->addr_size); +} + /* Create a new context for the expression evaluator. */ dwarf_expr_context::dwarf_expr_context (dwarf2_per_objfile *per_objfile, diff --git a/gdb/dwarf2/expr.h b/gdb/dwarf2/expr.h index 1c06308f99..739731daf8 100644 --- a/gdb/dwarf2/expr.h +++ b/gdb/dwarf2/expr.h @@ -260,6 +260,10 @@ struct dwarf_expr_context void read_mem (gdb_byte *buf, CORE_ADDR addr, size_t length); }; +/* 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. */ CORE_ADDR read_addr_from_reg (struct frame_info *, int); -- 2.17.1