From patchwork Fri Mar 3 21:12:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 65991 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4ABFA3850213 for ; Fri, 3 Mar 2023 21:13:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4ABFA3850213 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1677877999; bh=pIfCIpmRhMlYkZtHCS/LwU8atPRVVZhrHopXuTYHPIk=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=EkmCq5Y90/4Znj1K6gbpWRUh0AXUHBuFIlcz7y+yGgMWZ0DiY6TvyXyP/LWlEbkm3 As4hMamNa8jQ8ctVK3ItxmGgf9//RtybB96A2tDR5fe4KGqZJFoYxJ+/mvMRe+NJbm ObdgbccgIZJJm+lvxIiJ/hKu66ewiDRQRmlz1J54= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-il1-x135.google.com (mail-il1-x135.google.com [IPv6:2607:f8b0:4864:20::135]) by sourceware.org (Postfix) with ESMTPS id 11A2B3858C74 for ; Fri, 3 Mar 2023 21:12:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 11A2B3858C74 Received: by mail-il1-x135.google.com with SMTP id a1so2566045iln.9 for ; Fri, 03 Mar 2023 13:12:22 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677877941; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=pIfCIpmRhMlYkZtHCS/LwU8atPRVVZhrHopXuTYHPIk=; b=zwx0dXS/vAlLGligsnlDzFieVQtF4h5jfLpJLR1Tap5xWeeZrWYm/Np+xfhvGobiuX 012nxEiPAgMqvWsXd/zRzN08xfROp1c4UwPu+P5mKSGHYyL5F/IiUX3TpHFYci8M6gub fimri1GfgeO7hPensduKqmApozwJSaj953bA8auY0Vfjcd4tN3qXGfIjRMat3nPYXOFu HaoDXcvkTFlweNpYJafoxOyFuAWjvQwc7cQpOB/uqLGgGPkdr+Ozgkes8HaRA+zBuVCY tL03Yn3PqHgx/hB6pj1BZBgIFWN84AvcBd/pWTUbyCWK34PhhITJ+AS0ytx7fJI+YGNS uPTw== X-Gm-Message-State: AO0yUKVGhRvmL7ekfKIIcgsoo1D2BYI2CAO3vGK1qFy4UUqFbDEY2xcZ XRXl5Zi5eXjAaAQxfF+hR1p3lIBZmPMQzqGzcw8= X-Google-Smtp-Source: AK7set/dPXHFbIm7poE0B5z429EQKPGzrHxznX0G/mcMmkOKpK11DtjKrne0lHCmjGrdWTKbDXLOXQ== X-Received: by 2002:a05:6e02:1bea:b0:316:f0d7:8cf with SMTP id y10-20020a056e021bea00b00316f0d708cfmr3013207ilv.5.1677877941210; Fri, 03 Mar 2023 13:12:21 -0800 (PST) Received: from localhost.localdomain (75-166-130-93.hlrn.qwest.net. [75.166.130.93]) by smtp.gmail.com with ESMTPSA id g8-20020a925208000000b00313b281ecd2sm867988ilb.70.2023.03.03.13.12.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Mar 2023 13:12:20 -0800 (PST) To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 4/8] Add value_as_mpz and value_from_mpz Date: Fri, 3 Mar 2023 14:12:03 -0700 Message-Id: <20230303211207.1053037-5-tromey@adacore.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230303211207.1053037-1-tromey@adacore.com> References: <20230303211207.1053037-1-tromey@adacore.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, 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 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-Patchwork-Original-From: Tom Tromey via Gdb-patches From: Tom Tromey Reply-To: Tom Tromey Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" This adds the two new functions, value_as_mpz and value_from_mpz, useful for manipulation values via gdb_mpz. --- gdb/value.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++ gdb/value.h | 7 ++++ 2 files changed, 113 insertions(+) diff --git a/gdb/value.c b/gdb/value.c index e9afa89c243..19da9e1a00b 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -2551,6 +2551,76 @@ value_as_long (struct value *val) return unpack_long (val->type (), val->contents ().data ()); } +/* See value.h. */ + +gdb_mpz +value_as_mpz (struct value *val) +{ + val = coerce_array (val); + struct type *type = check_typedef (val->type ()); + + switch (type->code ()) + { + case TYPE_CODE_ENUM: + case TYPE_CODE_BOOL: + case TYPE_CODE_INT: + case TYPE_CODE_CHAR: + case TYPE_CODE_RANGE: + break; + + default: + return gdb_mpz (value_as_long (val)); + } + + gdb_mpz result; + + gdb::array_view valbytes = val->contents (); + enum bfd_endian byte_order = type_byte_order (type); + + /* Handle integers that are either not a multiple of the word size, + or that are stored at some bit offset. */ + unsigned bit_off = 0, bit_size = 0; + if (type->bit_size_differs_p ()) + { + bit_size = type->bit_size (); + if (bit_size == 0) + { + /* We can just handle this immediately. */ + return result; + } + + bit_off = type->bit_offset (); + + unsigned n_bytes = ((bit_off % 8) + bit_size + 7) / 8; + valbytes = valbytes.slice (bit_off / 8, n_bytes); + + if (byte_order == BFD_ENDIAN_BIG) + bit_off = (n_bytes * 8 - bit_off % 8 - bit_size); + else + bit_off %= 8; + } + + result.read (val->contents (), byte_order, type->is_unsigned ()); + + /* Shift off any low bits, if needed. */ + if (bit_off != 0) + result >>= bit_off; + + /* Mask off any high bits, if needed. */ + if (bit_size) + result.mask (bit_size); + + /* Now handle any range bias. */ + if (type->code () == TYPE_CODE_RANGE && type->bounds ()->bias != 0) + { + /* Unfortunately we have to box here, because LONGEST is + probably wider than long. */ + result += gdb_mpz (type->bounds ()->bias); + } + + return result; +} + /* Extract a value as a C pointer. Does not deallocate the value. Note that val's type may not actually be a pointer; value_as_long handles all the cases. */ @@ -3378,6 +3448,42 @@ value_from_ulongest (struct type *type, ULONGEST num) return val; } +/* See value.h. */ + +struct value * +value_from_mpz (struct type *type, const gdb_mpz &v) +{ + struct type *real_type = check_typedef (type); + + const gdb_mpz *val = &v; + gdb_mpz storage; + if (real_type->code () == TYPE_CODE_RANGE && type->bounds ()->bias != 0) + { + storage = *val; + val = &storage; + storage -= type->bounds ()->bias; + } + + if (type->bit_size_differs_p ()) + { + unsigned bit_off = type->bit_offset (); + unsigned bit_size = type->bit_size (); + + if (val != &storage) + { + storage = *val; + val = &storage; + } + + storage.mask ((ULONGEST) 1 << bit_size); + storage <<= bit_off; + } + + struct value *result = value::allocate (type); + val->truncate (result->contents_raw (), type_byte_order (type), + type->is_unsigned ()); + return result; +} /* Create a value representing a pointer of type TYPE to the address ADDR. */ diff --git a/gdb/value.h b/gdb/value.h index d83c4ab3674..1b4eff22f37 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -1029,6 +1029,11 @@ extern bool is_floating_value (struct value *val); extern LONGEST value_as_long (struct value *val); extern CORE_ADDR value_as_address (struct value *val); +/* Extract the value from VAL as a MPZ. This coerces arrays and + handles various integer-like types as well. */ + +extern gdb_mpz value_as_mpz (struct value *val); + extern LONGEST unpack_long (struct type *type, const gdb_byte *valaddr); extern CORE_ADDR unpack_pointer (struct type *type, const gdb_byte *valaddr); @@ -1075,6 +1080,8 @@ extern struct value *value_from_history_ref (const char *, const char **); extern struct value *value_from_component (struct value *, struct type *, LONGEST); +/* Convert the value V into a newly allocated value. */ +extern struct value *value_from_mpz (struct type *type, const gdb_mpz &v); extern struct value *value_at (struct type *type, CORE_ADDR addr); extern struct value *value_at_lazy (struct type *type, CORE_ADDR addr);