From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id kAecNaeTLWQx+CMAWB0awg (envelope-from ) for ; Wed, 05 Apr 2023 11:28:39 -0400 Received: by simark.ca (Postfix, from userid 112) id D96971E223; Wed, 5 Apr 2023 11:28:39 -0400 (EDT) Authentication-Results: simark.ca; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=kgDUpDa+; dkim-atps=neutral X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-7.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, RDNS_DYNAMIC,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from sourceware.org (ip-8-43-85-97.sourceware.org [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 110671E0D2 for ; Wed, 5 Apr 2023 11:28:39 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8093E3858404 for ; Wed, 5 Apr 2023 15:28:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8093E3858404 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1680708518; bh=/Jp2JgcTq2Dt7e+IohSYzv8UOiogIgZ5DV3iAUkt9RM=; h=Subject:To:Cc:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=kgDUpDa+a2ayEfNtL51Nfu9YotSdXG6xDP7b6yhHW7oMQwChoJOWApRzTJF96o95a a0HgOVA9k0LpuMoWGJi9qMzQ7xf5+nVrmbNgAbmNvUBhX8f4KdekzCARAHFI/8SQKp I96vFPr4Oq1NxrjlaSCQktpLpDuL+brVMfk5DknA= Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) by sourceware.org (Postfix) with ESMTPS id 844133858D20 for ; Wed, 5 Apr 2023 15:28:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 844133858D20 Received: from pps.filterd (m0098420.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 335EEPpk002095 for ; Wed, 5 Apr 2023 15:28:16 GMT Received: from ppma04wdc.us.ibm.com (1a.90.2fa9.ip4.static.sl-reverse.com [169.47.144.26]) by mx0b-001b2d01.pphosted.com (PPS) with ESMTPS id 3psajn23kw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 05 Apr 2023 15:28:15 +0000 Received: from pps.filterd (ppma04wdc.us.ibm.com [127.0.0.1]) by ppma04wdc.us.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 335EY3OK009626 for ; Wed, 5 Apr 2023 15:28:15 GMT Received: from smtprelay03.wdc07v.mail.ibm.com ([9.208.129.113]) by ppma04wdc.us.ibm.com (PPS) with ESMTPS id 3ppc87xyry-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 05 Apr 2023 15:28:15 +0000 Received: from smtpav02.wdc07v.mail.ibm.com (smtpav02.wdc07v.mail.ibm.com [10.39.53.229]) by smtprelay03.wdc07v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 335FSBpV28639918 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 5 Apr 2023 15:28:11 GMT Received: from smtpav02.wdc07v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id CD16658059; Wed, 5 Apr 2023 15:28:11 +0000 (GMT) Received: from smtpav02.wdc07v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 5E2AD58058; Wed, 5 Apr 2023 15:28:11 +0000 (GMT) Received: from li-e362e14c-2378-11b2-a85c-87d605f3c641.ibm.com (unknown [9.211.150.219]) by smtpav02.wdc07v.mail.ibm.com (Postfix) with ESMTP; Wed, 5 Apr 2023 15:28:11 +0000 (GMT) Message-ID: <184c0edcf067acccdf71d4dcdd66447bb5d93d4c.camel@us.ibm.com> Subject: [PATCH] PowerPC: fix _Float128 type output string To: "gdb-patches@sourceware.org" , Ulrich Weigand Cc: cel@us.ibm.com Date: Wed, 05 Apr 2023 08:28:10 -0700 Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.28.5 (3.28.5-18.el8) X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: 1Oep6Sr8DKv_Npjfk2Vj09fhE2qjzrmh X-Proofpoint-GUID: 1Oep6Sr8DKv_Npjfk2Vj09fhE2qjzrmh Content-Transfer-Encoding: 7bit X-Proofpoint-UnRewURL: 0 URL was un-rewritten MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.942,Hydra:6.0.573,FMLib:17.11.170.22 definitions=2023-04-05_09,2023-04-05_01,2023-02-09_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 impostorscore=0 adultscore=0 malwarescore=0 mlxscore=0 suspectscore=0 priorityscore=1501 mlxlogscore=999 lowpriorityscore=0 phishscore=0 spamscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2303200000 definitions=main-2304050136 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: Carl Love via Gdb-patches Reply-To: Carl Love Errors-To: gdb-patches-bounces+public-inbox=simark.ca@sourceware.org Sender: "Gdb-patches" GDB maintainers: PowerPC supports the IBM and IEEE 128-bit floating point formats. However the DWARF information does not distinguish between the two. The PowerPC GCC support created a workaround to identify the two formats. Unfortunately, the workaround is not transparent to GDB when printing the name of the typedef. The issue occurs on systems where GCC is now set to generate the IEEE 128-bit format by default. This patch fixes the printing of the typedef. It fixes 74 test failures in gdb.base/whatis-ptype-typedefs.exp and 1 failure in gdb.base/complex-parts.exp. The patch has been tested on a Power 10 platform where GCC generates the IEEE 128-bit floats by default and on a Power 10 platform where the IBM 128-bit floating point format is used by default. Additionally, the patch has been tested on X86-64. The patch passes the regression runs with no new regressions. Please let me know if the patch is acceptable for mainline. Thanks. Carl ------------------------------------------------------ PowerPC: fix _Float128 type output string PowerPC supports two 128-bit floating point formats, the IBM long double and IEEE 128-bit float. The issue is the DWARF information does not distinguish between the two. There have been proposals of how to extend the DWARF information as discussed in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104194 but has not been fully implemented. GCC introduced the _Float128 internal type as a work around for the issue. The workaround is not transparent to GDB. The internal _Float128 type name is printed rather then the user specified long double type. This patch adds a new gdbarch method to allow PowerPC to detect the GCC workaround. The workaround checks for "_Float128" name when reading the base typedef from the die_info. If the workaround is detected, the type and format fields from the _Float128 typedef are copied to the long double typedef. The same is done for the complex long double typedef. This patch fixes 74 regression test failures in gdb.base/whatis-ptype-typedefs.exp on PowerPC with IEEE float 128 as the default on GCC. It fixes one regression test failure in gdb.base/complex-parts.exp. The patch has been tested on Power 10 where GCC defaults to IEEE Float 128-bit and on Power 10 where GCC defaults to the IBM 128-bit float. The patch as also been tested on X86-64 with no new regression failures. --- gdb/arch-utils.c | 7 +++++++ gdb/arch-utils.h | 5 +++++ gdb/dwarf2/read.c | 16 ++++++++++++---- gdb/gdbarch-gen.h | 8 ++++++++ gdb/gdbarch.c | 22 ++++++++++++++++++++++ gdb/gdbarch_components.py | 19 +++++++++++++++++++ gdb/ppc-linux-tdep.c | 38 +++++++++++++++++++++++++++++++++++++- gdb/ppc-tdep.h | 3 +++ 8 files changed, 113 insertions(+), 5 deletions(-) diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index e3af9ce2dbc..997a292e9ef 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -1098,6 +1098,13 @@ default_get_return_buf_addr (struct type *val_type, frame_info_ptr cur_frame) return 0; } +bool +default_dwarf2_omit_typedef_p (struct type *target_type, const char *producer, + const char *name) +{ + return false; +} + /* Non-zero if we want to trace architecture code. */ #ifndef GDBARCH_DEBUG diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h index 56690f0fd43..fc0c0b16793 100644 --- a/gdb/arch-utils.h +++ b/gdb/arch-utils.h @@ -309,6 +309,11 @@ extern void default_read_core_file_mappings extern CORE_ADDR default_get_return_buf_addr (struct type *val_typegdbarch, frame_info_ptr cur_frame); +/* Default implementation of gdbaarch default_dwarf2_omit_typedef_p method. */ +extern bool default_dwarf2_omit_typedef_p (struct type *target_type, + const char *producer, + const char *name); + extern enum return_value_convention default_gdbarch_return_value (struct gdbarch *gdbarch, struct value *function, struct type *valtype, struct regcache *regcache, struct value **read_value, diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index c9208a097bf..fa319e346c0 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -14702,14 +14702,22 @@ static struct type * read_typedef (struct die_info *die, struct dwarf2_cu *cu) { struct objfile *objfile = cu->per_objfile->objfile; - const char *name = NULL; - struct type *this_type, *target_type; + const char *name = dwarf2_full_name (NULL, die, cu); + struct type *this_type; + struct gdbarch *gdbarch = objfile->arch (); + struct type *target_type = die_type (die, cu); + + if (gdbarch_dwarf2_omit_typedef_p (gdbarch, target_type, cu->producer, name)) + { + this_type = copy_type (target_type); + this_type->set_name (name); + set_die_type (die, this_type, cu); + return this_type; + } - name = dwarf2_full_name (NULL, die, cu); this_type = type_allocator (objfile).new_type (TYPE_CODE_TYPEDEF, 0, name); this_type->set_target_is_stub (true); set_die_type (die, this_type, cu); - target_type = die_type (die, cu); if (target_type != this_type) this_type->set_target_type (target_type); else diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h index a3fc0b9272b..3d8aafd5ea6 100644 --- a/gdb/gdbarch-gen.h +++ b/gdb/gdbarch-gen.h @@ -468,6 +468,14 @@ typedef CORE_ADDR (gdbarch_get_return_buf_addr_ftype) (struct type *val_type, fr extern CORE_ADDR gdbarch_get_return_buf_addr (struct gdbarch *gdbarch, struct type *val_type, frame_info_ptr cur_frame); extern void set_gdbarch_get_return_buf_addr (struct gdbarch *gdbarch, gdbarch_get_return_buf_addr_ftype *get_return_buf_addr); +/* Return true if the typedef record needs to be replaced.". + + Return 0 by default */ + +typedef bool (gdbarch_dwarf2_omit_typedef_p_ftype) (struct type *target_type, const char *producer, const char *name); +extern bool gdbarch_dwarf2_omit_typedef_p (struct gdbarch *gdbarch, struct type *target_type, const char *producer, const char *name); +extern void set_gdbarch_dwarf2_omit_typedef_p (struct gdbarch *gdbarch, gdbarch_dwarf2_omit_typedef_p_ftype *dwarf2_omit_typedef_p); + /* Return true if the return value of function is stored in the first hidden parameter. In theory, this feature should be language-dependent, specified by language and its ABI, such as C++. Unfortunately, compiler may diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index b676e346fd0..00e7191653a 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -114,6 +114,7 @@ struct gdbarch gdbarch_return_value_ftype *return_value = nullptr; gdbarch_return_value_as_value_ftype *return_value_as_value = default_gdbarch_return_value; gdbarch_get_return_buf_addr_ftype *get_return_buf_addr = default_get_return_buf_addr; + gdbarch_dwarf2_omit_typedef_p_ftype *dwarf2_omit_typedef_p = default_dwarf2_omit_typedef_p; gdbarch_return_in_first_hidden_param_p_ftype *return_in_first_hidden_param_p = default_return_in_first_hidden_param_p; gdbarch_skip_prologue_ftype *skip_prologue = nullptr; gdbarch_skip_main_prologue_ftype *skip_main_prologue = nullptr; @@ -370,6 +371,7 @@ verify_gdbarch (struct gdbarch *gdbarch) if ((gdbarch->return_value_as_value == default_gdbarch_return_value) == (gdbarch->return_value == nullptr)) log.puts ("\n\treturn_value_as_value"); /* Skip verify of get_return_buf_addr, invalid_p == 0 */ + /* Skip verify of dwarf2_omit_typedef_p, invalid_p == 0 */ /* Skip verify of return_in_first_hidden_param_p, invalid_p == 0 */ if (gdbarch->skip_prologue == 0) log.puts ("\n\tskip_prologue"); @@ -788,6 +790,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) gdb_printf (file, "gdbarch_dump: get_return_buf_addr = <%s>\n", host_address_to_string (gdbarch->get_return_buf_addr)); + gdb_printf (file, + "gdbarch_dump: dwarf2_omit_typedef_p = <%s>\n", + host_address_to_string (gdbarch->dwarf2_omit_typedef_p)); gdb_printf (file, "gdbarch_dump: return_in_first_hidden_param_p = <%s>\n", host_address_to_string (gdbarch->return_in_first_hidden_param_p)); @@ -2617,6 +2622,23 @@ set_gdbarch_get_return_buf_addr (struct gdbarch *gdbarch, gdbarch->get_return_buf_addr = get_return_buf_addr; } +bool +gdbarch_dwarf2_omit_typedef_p (struct gdbarch *gdbarch, struct type *target_type, const char *producer, const char *name) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->dwarf2_omit_typedef_p != NULL); + if (gdbarch_debug >= 2) + gdb_printf (gdb_stdlog, "gdbarch_dwarf2_omit_typedef_p called\n"); + return gdbarch->dwarf2_omit_typedef_p (target_type, producer, name); +} + +void +set_gdbarch_dwarf2_omit_typedef_p (struct gdbarch *gdbarch, + gdbarch_dwarf2_omit_typedef_p_ftype dwarf2_omit_typedef_p) +{ + gdbarch->dwarf2_omit_typedef_p = dwarf2_omit_typedef_p; +} + int gdbarch_return_in_first_hidden_param_p (struct gdbarch *gdbarch, struct type *type) { diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py index 2b1a2b4f602..7a64d9e006b 100644 --- a/gdb/gdbarch_components.py +++ b/gdb/gdbarch_components.py @@ -901,6 +901,25 @@ May return 0 when unable to determine that address.""", invalid=False, ) + +# The DWARF info currently does not distinquish between IEEE 128-bit floating +# point values and the IBM 128-bit floating point format. GCC has an internal +# hack that uses the _Float128 base typdef for IEEE 128-bit float values. The +# following method is used to "fix" the long double typedef so the _Float128 +# name is not printed. +Function( + comment=""" +Return true if the typedef record needs to be replaced.". + +Return 0 by default""", + type="bool", + name="dwarf2_omit_typedef_p", + params=[("struct type *", "target_type"), ("const char *", "producer"), + ("const char *", "name")], + predefault="default_dwarf2_omit_typedef_p", + invalid=False, +) + Method( comment=""" Return true if the return value of function is stored in the first hidden diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c index fcddb2008a0..830a60fd49b 100644 --- a/gdb/ppc-linux-tdep.c +++ b/gdb/ppc-linux-tdep.c @@ -1,4 +1,4 @@ -/* Target-dependent code for GDB, the GNU debugger. +* Target-dependent code for GDB, the GNU debugger. Copyright (C) 1986-2023 Free Software Foundation, Inc. @@ -62,6 +62,7 @@ #include "user-regs.h" #include #include "elf-bfd.h" +#include "producer.h" #include "features/rs6000/powerpc-32l.c" #include "features/rs6000/powerpc-altivec32l.c" @@ -2006,6 +2007,38 @@ ppc_floatformat_for_type (struct gdbarch *gdbarch, return default_floatformat_for_type (gdbarch, name, len); } +bool +linux_dwarf2_omit_typedef_p (struct type *target_type, + const char *producer, const char *name) +{ + int gcc_major, gcc_minor; + + if (producer_is_gcc (producer, &gcc_major, &gcc_minor)) + { + if ((target_type->code () == TYPE_CODE_FLT + || target_type->code () == TYPE_CODE_COMPLEX) + && (strcmp (name, "long double") == 0 + || strcmp (name, "complex long double") == 0)) + { + /* IEEE 128-bit floating point and IBM long double are two + encodings for 128-bit values. The DWARF debug data can't + distinguish between them. See bugzilla: + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104194 + + A GCC hack was introduced to still allow the debugger to identify + the case where "long double" uses the IEEE 128-bit floating point + format: GCC will emit a bogus DWARF type record pretending that + "long double" is a typedef alias for the _Float128 type. + + This hack should not be visible to the GDB user, so we replace + this bogus typedef by a normal floating-point type, copying the + format information from the target type of the bogus typedef. */ + return true; + } + } + return false; +} + /* Specify the powerpc64le target triplet. This can be variations of ppc64le-{distro}-linux-gcc @@ -2083,6 +2116,9 @@ ppc_linux_init_abi (struct gdbarch_info info, /* Support for floating-point data type variants. */ set_gdbarch_floatformat_for_type (gdbarch, ppc_floatformat_for_type); + /* Support for replacing typedef record. */ + set_gdbarch_dwarf2_omit_typedef_p (gdbarch, linux_dwarf2_omit_typedef_p); + /* Handle inferior calls during interrupted system calls. */ set_gdbarch_write_pc (gdbarch, ppc_linux_write_pc); diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h index db4e53205a6..f078b3d45ab 100644 --- a/gdb/ppc-tdep.h +++ b/gdb/ppc-tdep.h @@ -176,6 +176,9 @@ extern void ppc_collect_vsxregset (const struct regset *regset, int regnum, void *vsxregs, size_t len); extern CORE_ADDR ppc64_sysv_get_return_buf_addr (type*, frame_info_ptr); +extern bool linux_dwarf2_omit_typedef_p (struct type *target_type, + const char *producer, + const char *name); /* Private data that this module attaches to struct gdbarch. */ -- 2.37.2