From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 71D653858414 for ; Mon, 6 Dec 2021 14:09:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 71D653858414 Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-78-gCo4QFvmMQaSKRwbRRHLYQ-1; Mon, 06 Dec 2021 09:08:58 -0500 X-MC-Unique: gCo4QFvmMQaSKRwbRRHLYQ-1 Received: by mail-wr1-f70.google.com with SMTP id q7-20020adff507000000b0017d160d35a8so2060197wro.4 for ; Mon, 06 Dec 2021 06:08:58 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=WheEMLR6916716g1oCkMATEZhOohjP8d5jW5oFHBYEA=; b=AxKMO70m+ZDzU8G3LXUDgO9GVXiCg9jcPXR/fdESDNL8jqABqhhX5eROhHoLPVQoa2 gA5ro5whIr4qH+0VIhia61kBqJwrOQKOEI8zrF3DZpM/ex00T6nQyZbnDym6HCHMwI6a n70tF4xT9tcV8YdrVXj1lulJpNTBmWl2/WCof5HJyAKPIYra20k7pO3JUD62DRAz87GF sbXnCqmCTpNFjZb0zxPuqKyFHGeIZad14sEUox5kOjVdxUG9qm/v9mGxGQMWqDUh9niB Nggua1OdpHNbM92LUJS5WoW6cKd61CBPwHlTJz+sgR7hWklBAbo6ptJ/i8oQJxlxXJqn A6mw== X-Gm-Message-State: AOAM532bzHcrprfe6eXkS6pjUfQpP0ozw+IJ8XgEouleuF0SOjpqwui+ N5LrDXWJ4yKANgE+lHbKMxIU+O1bRPWaz4Z6ItussWMh7TEJnIh77i1vP033kiCq2xtmZ0G/5LB 70SzghxQiVrp0PVtj+US45NoaNe9ho5UOa/U9faAKCX/JRHcG4SgvGcI3hd9OFfiqkRi90As4RQ == X-Received: by 2002:adf:df0b:: with SMTP id y11mr42653080wrl.181.1638799737281; Mon, 06 Dec 2021 06:08:57 -0800 (PST) X-Google-Smtp-Source: ABdhPJwJ8/Ka+bNoo2WBbB/RZTYtSUNgByh2mbvKpl8Q2E6BJKZmQ501l7FHObgTguLgWdHNUjQU3g== X-Received: by 2002:adf:df0b:: with SMTP id y11mr42653030wrl.181.1638799736899; Mon, 06 Dec 2021 06:08:56 -0800 (PST) Received: from localhost (host86-134-238-138.range86-134.btcentralplus.com. [86.134.238.138]) by smtp.gmail.com with ESMTPSA id t16sm11348433wrn.49.2021.12.06.06.08.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Dec 2021 06:08:56 -0800 (PST) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess Subject: [PATCHv2 2/2] gdb/python: add Type.signedness attribute Date: Mon, 6 Dec 2021 14:08:51 +0000 Message-Id: <5e9277cbad4e17099261ddc413bfb7471d3eb4f9.1638799543.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII" X-Spam-Status: No, score=-9.0 required=5.0 tests=BAYES_00, DKIM_INVALID, DKIM_SIGNED, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, 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: Mon, 06 Dec 2021 14:09:02 -0000 Add a new gdb.Type.signedness attribute that describes whether a type is signed or not. Unfortunately types can be signed, unsigned, or neither, so this attribute is not a boolean, but is instead a integer that takes the value of one of three new constants: gdb.TYPE_SIGNEDNESS_SIGNED gdb.TYPE_SIGNEDNESS_UNSIGNED gdb.TYPE_SIGNEDNESS_NONE There's documentation, NEWS, and a few tests for the new functionality. --- gdb/NEWS | 4 ++ gdb/doc/python.texi | 24 +++++++++++ gdb/python/py-type.c | 61 ++++++++++++++++++++++++++++ gdb/testsuite/gdb.python/py-arch.exp | 15 ++++++- gdb/testsuite/gdb.python/py-type.c | 12 ++++++ gdb/testsuite/gdb.python/py-type.exp | 31 ++++++++++++++ 6 files changed, 146 insertions(+), 1 deletion(-) diff --git a/gdb/NEWS b/gdb/NEWS index 13b66286876..887530364c4 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -94,6 +94,10 @@ maint packet is equivalent to the existing 'maint packet' CLI command; it allows a user specified packet to be sent to the remote target. + ** New read-only attribute gdb.Type.signedness, which contains one + of three new constants, gdb.TYPE_SIGNEDNESS_UNSIGNED, + gdb.TYPE_SIGNEDNESS_SIGNED, or gdb.TYPE_SIGNEDNESS_NONE. + * New features in the GDB remote stub, GDBserver ** GDBserver is now supported on OpenRISC GNU/Linux. diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index 4a66c11c19d..d69b57f1ccf 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -1211,6 +1211,30 @@ there is no associated objfile. @end defvar +@defvar Type.signedness +A constant describing the signedness of this type. The valid values +for this field are defined in the @code{gdb} module: + +@vtable @code +@vindex TYPE_SIGNEDNESS_UNSIGNED +@item gdb.TYPE_SIGNEDNESS_UNSIGNED +This is an unsigned type. + +@vindex TYPE_SIGNEDNESS_SIGNED +@item gdb.TYPE_SIGNEDNESS_SIGNED +This is a signed type. + +@vindex TYPE_SIGNEDNESS_NONE +@item gdb.TYPE_SIGNEDNESS_NONE +This type is considered neither signed, or unsigned. This applies to +all non-scalar types (e.g.@: c language structs), but can sometimes be +the value return for scalar type, one example of where this can be +seen is in C++, where @code{char}, @code{signed char}, and +@code{unsigned char} are all considered distinct types. + +@end vtable +@end defvar + The following methods are provided: @defun Type.fields () diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c index 15d73fe94e4..f33833bda58 100644 --- a/gdb/python/py-type.c +++ b/gdb/python/py-type.c @@ -115,6 +115,40 @@ static struct pyty_code pyty_codes[] = ENTRY (TYPE_CODE_INTERNAL_FUNCTION), }; +#undef ENTRY + +/* Constants representing the possible signedness states. Every type is + in one of these states. */ + +enum py_type_signedness +{ + PY_TYPE_SIGNEDNESS_SIGNED, + PY_TYPE_SIGNEDNESS_UNSIGNED, + PY_TYPE_SIGNEDNESS_NONE, +}; + +/* This is used to initialize the gdb.TYPE_SIGNEDNESS_ constants. */ + +struct pyty_signedness +{ + /* The code. */ + enum py_type_signedness signedness; + /* The name. */ + const char *name; +}; + +/* A table mapping the PY_TYPE_SIGNEDNESS_ constants onto a string that + will be exported into Python as a constant in the gdb module. */ + +static struct pyty_signedness pyty_signedness_constants[] = +{ +#define ENTRY(X) { PY_ ## X, #X } + ENTRY (TYPE_SIGNEDNESS_SIGNED), + ENTRY (TYPE_SIGNEDNESS_UNSIGNED), + ENTRY (TYPE_SIGNEDNESS_NONE), +#undef ENTRY +}; + static void @@ -433,6 +467,24 @@ typy_get_objfile (PyObject *self, void *closure) return objfile_to_objfile_object (objfile).release (); } +/* Return the signedness constant for this type. */ + +static PyObject * +typy_get_signedness (PyObject *self, void *closure) +{ + struct type *type = ((type_object *) self)->type; + + enum py_type_signedness signedness; + if (!is_scalar_type (type) || type->has_no_signedness ()) + signedness = PY_TYPE_SIGNEDNESS_NONE; + else if (type->is_unsigned ()) + signedness = PY_TYPE_SIGNEDNESS_UNSIGNED; + else + signedness = PY_TYPE_SIGNEDNESS_SIGNED; + + return gdb_py_object_from_longest (signedness).release (); +} + /* Return the type, stripped of typedefs. */ static PyObject * typy_strip_typedefs (PyObject *self, PyObject *args) @@ -1456,6 +1508,13 @@ gdbpy_initialize_types (void) return -1; } + /* Place the gdb.TYPE_SIGNEDNESS_ constants into the gdb module. */ + for (const auto &item : pyty_signedness_constants) + { + if (PyModule_AddIntConstant (gdb_module, item.name, item.signedness) < 0) + return -1; + } + if (gdb_pymodule_addobject (gdb_module, "Type", (PyObject *) &type_object_type) < 0) return -1; @@ -1486,6 +1545,8 @@ static gdb_PyGetSetDef type_object_getset[] = "The tag name for this type, or None.", NULL }, { "objfile", typy_get_objfile, NULL, "The objfile this type was defined in, or None.", NULL }, + { "signedness", typy_get_signedness, NULL, + "The signedness for this type.", NULL }, { NULL } }; diff --git a/gdb/testsuite/gdb.python/py-arch.exp b/gdb/testsuite/gdb.python/py-arch.exp index 14dc1bf85ee..a919544f064 100644 --- a/gdb/testsuite/gdb.python/py-arch.exp +++ b/gdb/testsuite/gdb.python/py-arch.exp @@ -64,12 +64,25 @@ if { ![is_address_zero_readable] } { } foreach size {0 1 2 3 4 8 16} { - foreach sign {"" ", True" ", False" ", None" ", \"blah\""} { + foreach sign_data {{"" TYPE_SIGNEDNESS_SIGNED} \ + {", True" TYPE_SIGNEDNESS_SIGNED} \ + {", False" TYPE_SIGNEDNESS_UNSIGNED} \ + {", None" TYPE_SIGNEDNESS_UNSIGNED} \ + {", \"blah\"" TYPE_SIGNEDNESS_SIGNED}} { + set sign [lindex $sign_data 0] + # GDB's 0 bit type is always signed. + if { $size == 0 } { + set sign_result TYPE_SIGNEDNESS_SIGNED + } else { + set sign_result [lindex $sign_data 1] + } set fullsize [expr 8 * $size] gdb_test_no_output "python t = arch.integer_type($fullsize$sign)" \ "get integer type for $size$sign" gdb_test "python print(t.sizeof)" "$size" \ "print size of integer type for $size$sign" + gdb_test "python print(t.signedness == gdb.${sign_result})" "True" \ + "check signedness of type for $size$sign" } } diff --git a/gdb/testsuite/gdb.python/py-type.c b/gdb/testsuite/gdb.python/py-type.c index a599d0c901e..7a05fd356cf 100644 --- a/gdb/testsuite/gdb.python/py-type.c +++ b/gdb/testsuite/gdb.python/py-type.c @@ -32,6 +32,13 @@ TS ts; int aligncheck; +union UU +{ + int i; + float f; + int a[5]; +}; + #ifdef __cplusplus struct C { @@ -70,6 +77,10 @@ struct Temargs Temargs temvar; +unsigned char global_unsigned_char; +char global_char; +signed char global_signed_char; + #endif enum E @@ -91,6 +102,7 @@ main () int ar[2] = {1,2}; struct s st; struct SS ss; + union UU uu; #ifdef __cplusplus C c; c.c = 1; diff --git a/gdb/testsuite/gdb.python/py-type.exp b/gdb/testsuite/gdb.python/py-type.exp index 733b25d3210..982b0bbf261 100644 --- a/gdb/testsuite/gdb.python/py-type.exp +++ b/gdb/testsuite/gdb.python/py-type.exp @@ -270,6 +270,27 @@ proc test_template {} { gdb_test "python print (ttype.template_argument(2))" "&C::c" } +# Check the signedness of some types. +proc test_signedness {lang} { + if {$lang == "c++"} { + gdb_test "python print (gdb.parse_and_eval ('global_unsigned_char').type.signedness == gdb.TYPE_SIGNEDNESS_UNSIGNED)" "True" + gdb_test "python print (gdb.parse_and_eval ('global_char').type.signedness == gdb.TYPE_SIGNEDNESS_NONE)" "True" + gdb_test "python print (gdb.parse_and_eval ('global_signed_char').type.signedness == gdb.TYPE_SIGNEDNESS_SIGNED)" "True" + gdb_test "python print (gdb.parse_and_eval ('c').type.signedness == gdb.TYPE_SIGNEDNESS_NONE)" "True" + gdb_test "python print (gdb.parse_and_eval ('&c').type.signedness == gdb.TYPE_SIGNEDNESS_UNSIGNED)" "True" + } + + gdb_test "python print (gdb.parse_and_eval ('ss.x').type.signedness == gdb.TYPE_SIGNEDNESS_SIGNED)" "True" + gdb_test "python print (gdb.parse_and_eval ('ss').type.signedness == gdb.TYPE_SIGNEDNESS_NONE)" "True" + gdb_test "python print (gdb.parse_and_eval ('uu').type.signedness == gdb.TYPE_SIGNEDNESS_NONE)" "True" + gdb_test "python print (gdb.parse_and_eval ('uu.i').type.signedness == gdb.TYPE_SIGNEDNESS_SIGNED)" "True" + gdb_test "python print (gdb.parse_and_eval ('uu.f').type.signedness == gdb.TYPE_SIGNEDNESS_SIGNED)" "True" + gdb_test "python print (gdb.parse_and_eval ('uu.a').type.signedness == gdb.TYPE_SIGNEDNESS_NONE)" "True" + + gdb_test "python print (gdb.parse_and_eval ('&ss.x').type.signedness == gdb.TYPE_SIGNEDNESS_UNSIGNED)" "True" + gdb_test "python print (gdb.parse_and_eval ('&uu').type.signedness == gdb.TYPE_SIGNEDNESS_UNSIGNED)" "True" +} + # Perform C Tests. if { [build_inferior "${binfile}" "c"] == 0 } { restart_gdb "${binfile}" @@ -292,10 +313,19 @@ if { [build_inferior "${binfile}" "c"] == 0 } { gdb_test "python print(gdb.parse_and_eval('aligncheck').type.alignof)" \ $sint + # Ensure that all of the type signedness constants have different values. + gdb_test "python print (gdb.TYPE_SIGNEDNESS_SIGNED == gdb.TYPE_SIGNEDNESS_UNSIGNED)" \ + "False" + gdb_test "python print (gdb.TYPE_SIGNEDNESS_SIGNED == gdb.TYPE_SIGNEDNESS_NONE)" \ + "False" + gdb_test "python print (gdb.TYPE_SIGNEDNESS_UNSIGNED == gdb.TYPE_SIGNEDNESS_NONE)" \ + "False" + with_test_prefix "lang_c" { runto_bp "break to inspect struct and array." test_fields "c" test_enums + test_signedness "c" } } @@ -310,5 +340,6 @@ if { [build_inferior "${binfile}-cxx" "c++"] == 0 } { test_range test_template test_enums + test_signedness "c++" } } -- 2.25.4