* [PATCH 0/2] Fix ODR violations in regformat target descriptions
@ 2026-06-18 14:23 Keith Seitz
2026-06-18 14:23 ` [PATCH 1/2] regdat.sh: generate const_target_desc_up for register descriptions Keith Seitz
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Keith Seitz @ 2026-06-18 14:23 UTC (permalink / raw)
To: gdb-patches
Commit 1a5362ce51ef ("gdb, gdbserver: propagate use of target_desc unique
pointers") changd most target descriptions to "const_target_desc_up," but
deliberately left gdb/regformats/regdat.sh unchanged because those descriptions
were still emitted as file-local static "struct target_desc" objects declared
"const struct target_desc *".
That mismatch breaks gdbserver on ppc64le when LTO is enabled. The shared
header gdb/arch/ppc-linux-tdesc.h declares symbols such as
"tdesc_powerpc_isa207_htm_vsx64l" as "const_target_desc_up," while regdat-
generated translation units still define them as raw pointers. This reintroduces
previously settled ODR violations.
This series updates regdat.sh to generate code consistent with the unique-pointer
API, then updates gdbserver targets that declare those symbols locally.
There are no intended user-visible changes.
Keith
Keith Seitz (2):
regdat.sh: generate const_target_desc_up for register descriptions
[gdbserver] Use const_target_desc_up for regformat tdescs
gdb/regformats/regdat.sh | 13 +++---
gdbserver/linux-ia64-low.cc | 5 ++-
gdbserver/linux-m68k-low.cc | 5 ++-
gdbserver/linux-microblaze-low.cc | 6 +--
gdbserver/linux-mips-low.cc | 11 ++---
gdbserver/linux-or1k-low.cc | 5 ++-
gdbserver/linux-s390-ipa.cc | 39 ++++++++---------
gdbserver/linux-s390-low.cc | 69 ++++++++++++++++---------------
gdbserver/linux-s390-tdesc.h | 34 +++++++--------
gdbserver/linux-sh-low.cc | 5 ++-
gdbserver/linux-sparc-low.cc | 5 ++-
gdbserver/linux-xtensa-low.cc | 5 ++-
12 files changed, 105 insertions(+), 97 deletions(-)
base-commit: ada409879cc393c4cf633efe3d7afb716523f6be
--
2.53.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] regdat.sh: generate const_target_desc_up for register descriptions
2026-06-18 14:23 [PATCH 0/2] Fix ODR violations in regformat target descriptions Keith Seitz
@ 2026-06-18 14:23 ` Keith Seitz
2026-06-18 15:52 ` Simon Marchi
2026-06-18 14:23 ` [PATCH 2/2] [gdbserver] Use const_target_desc_up for regformat tdescs Keith Seitz
2026-06-18 15:57 ` [PATCH 0/2] Fix ODR violations in regformat target descriptions Simon Marchi
2 siblings, 1 reply; 7+ messages in thread
From: Keith Seitz @ 2026-06-18 14:23 UTC (permalink / raw)
To: gdb-patches
Late last year, a patch propagated the use of target_desc unique
pointers (commit 1a5362ce51ef79ffb61caa20c93284dc368dc74a). At the
time, the "old regformats/regdat.sh [weren't] changed because their
target_desc objects are statically allocated in the generated files."
Unfortunately that re-introduced ODR violations on ppc64le:
CXXLD gdbserver
../../src/gdbserver/../gdb/arch/ppc-linux-tdesc.h:46:29: error: ‘tdesc_powerpc_isa207_htm_vsx64l’ violates the C++ One Definition Rule [-Werror=odr]
46 | extern const_target_desc_up tdesc_powerpc_isa207_htm_vsx64l;
| ^
powerpc-isa207-htm-vsx64l-generated.cc:26:27: note: ‘tdesc_powerpc_isa207_htm_vsx64l’ was previously declared here
26 | const struct target_desc *tdesc_powerpc_isa207_htm_vsx64l;
| ^
powerpc-isa207-htm-vsx64l-generated.cc:26:27: note: code may be misoptimized unless ‘-fno-strict-aliasing’ is used
Update regdat.sh so that generated init_registers_* code matches the
const-unique_ptr-based target description API, resolving the ODR violation.
A follow-up patch updates various gdbserver architectures to
accommodate this API change.
Tested on ppc64le and s390x Fedora 43 and mips-linux
cross build (all with LTO).
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28444
---
gdb/regformats/regdat.sh | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/gdb/regformats/regdat.sh b/gdb/regformats/regdat.sh
index aeb41f6b7ad..af2bdc28810 100755
--- a/gdb/regformats/regdat.sh
+++ b/gdb/regformats/regdat.sh
@@ -125,7 +125,7 @@ do
if test "${type}" = "name"; then
name="${entry}"
- echo "const struct target_desc *tdesc_${name};"
+ echo "const_target_desc_up tdesc_${name};"
echo ""
# This is necessary for -Wmissing-declarations.
@@ -134,9 +134,8 @@ do
echo "void"
echo "init_registers_${name} (void)"
echo "{"
- echo " static struct target_desc tdesc_${name}_s;"
- echo " struct target_desc *result = &tdesc_${name}_s;"
- echo " struct tdesc_feature *feature = tdesc_create_feature (result, \"${name}\");"
+ echo " target_desc_up result = allocate_target_description ();"
+ echo " struct tdesc_feature *feature = tdesc_create_feature (result.get (), \"${name}\");"
continue
elif test "${type}" = "xmltarget"; then
xmltarget="${entry}"
@@ -195,12 +194,12 @@ echo
osabi_enum=$(grep "${osabi}" "$2" | sed 's/.*(\([^,]\+\),.*/GDB_OSABI_\1/')
cat <<EOF
- result->xmltarget = xmltarget_${name};
+ result.get ()->xmltarget = xmltarget_${name};
#endif
- init_target_desc (result, expedite_regs_${name}, ${osabi_enum});
+ init_target_desc (result.get (), expedite_regs_${name}, ${osabi_enum});
- tdesc_${name} = result;
+ tdesc_${name} = std::move (result);
}
EOF
--
2.53.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/2] [gdbserver] Use const_target_desc_up for regformat tdescs
2026-06-18 14:23 [PATCH 0/2] Fix ODR violations in regformat target descriptions Keith Seitz
2026-06-18 14:23 ` [PATCH 1/2] regdat.sh: generate const_target_desc_up for register descriptions Keith Seitz
@ 2026-06-18 14:23 ` Keith Seitz
2026-06-18 15:57 ` [PATCH 0/2] Fix ODR violations in regformat target descriptions Simon Marchi
2 siblings, 0 replies; 7+ messages in thread
From: Keith Seitz @ 2026-06-18 14:23 UTC (permalink / raw)
To: gdb-patches
Regformat tdescs are now declared 'const_target_desc_up' by
gdb's regdat.sh, so update the various gdbserver target descriptions
to observe this API change.
There should be no user visible changes.
---
gdbserver/linux-ia64-low.cc | 5 ++-
gdbserver/linux-m68k-low.cc | 5 ++-
gdbserver/linux-microblaze-low.cc | 6 +--
gdbserver/linux-mips-low.cc | 11 ++---
gdbserver/linux-or1k-low.cc | 5 ++-
gdbserver/linux-s390-ipa.cc | 39 ++++++++---------
gdbserver/linux-s390-low.cc | 69 ++++++++++++++++---------------
gdbserver/linux-s390-tdesc.h | 34 +++++++--------
gdbserver/linux-sh-low.cc | 5 ++-
gdbserver/linux-sparc-low.cc | 5 ++-
gdbserver/linux-xtensa-low.cc | 5 ++-
11 files changed, 99 insertions(+), 90 deletions(-)
diff --git a/gdbserver/linux-ia64-low.cc b/gdbserver/linux-ia64-low.cc
index 337ef08257b..2a749f5a5ed 100644
--- a/gdbserver/linux-ia64-low.cc
+++ b/gdbserver/linux-ia64-low.cc
@@ -17,6 +17,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "linux-low.h"
+#include "tdesc.h"
#ifdef HAVE_SYS_REG_H
#include <sys/reg.h>
@@ -65,7 +66,7 @@ ia64_target::low_breakpoint_at (CORE_ADDR pc)
/* Defined in auto-generated file reg-ia64.c. */
void init_registers_ia64 (void);
-extern const struct target_desc *tdesc_ia64;
+extern const_target_desc_up tdesc_ia64;
#define ia64_num_regs 462
@@ -381,7 +382,7 @@ ia64_target::get_regs_info ()
void
ia64_target::low_arch_setup ()
{
- current_process ()->tdesc = tdesc_ia64;
+ current_process ()->tdesc = tdesc_ia64.get ();
}
/* The linux target ops object. */
diff --git a/gdbserver/linux-m68k-low.cc b/gdbserver/linux-m68k-low.cc
index f620a344a0a..df1d7346931 100644
--- a/gdbserver/linux-m68k-low.cc
+++ b/gdbserver/linux-m68k-low.cc
@@ -17,6 +17,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "linux-low.h"
+#include "tdesc.h"
/* Linux target op definitions for the m68k architecture. */
@@ -77,7 +78,7 @@ m68k_target::low_decr_pc_after_break ()
/* Defined in auto-generated file reg-m68k.c. */
void init_registers_m68k (void);
-extern const struct target_desc *tdesc_m68k;
+extern const_target_desc_up tdesc_m68k;
#ifdef HAVE_SYS_REG_H
#include <sys/reg.h>
@@ -252,7 +253,7 @@ m68k_target::get_regs_info ()
void
m68k_target::low_arch_setup ()
{
- current_process ()->tdesc = tdesc_m68k;
+ current_process ()->tdesc = tdesc_m68k.get ();
}
/* The linux target ops object. */
diff --git a/gdbserver/linux-microblaze-low.cc b/gdbserver/linux-microblaze-low.cc
index 21793d9a801..19c8751a0a9 100644
--- a/gdbserver/linux-microblaze-low.cc
+++ b/gdbserver/linux-microblaze-low.cc
@@ -28,7 +28,7 @@
#include <sys/ptrace.h>
#include "gdb_proc_service.h"
-
+#include "tdesc.h"
static int microblaze_regmap[] =
{PT_GPR(0), PT_GPR(1), PT_GPR(2), PT_GPR(3),
@@ -79,7 +79,7 @@ constexpr auto microblaze_num_regs
/* Defined in auto-generated file microblaze-linux-generated.c. */
void init_registers_microblaze_linux ();
-extern const target_desc *tdesc_microblaze_linux;
+extern const_target_desc_up tdesc_microblaze_linux;
bool
microblaze_target::low_supports_breakpoints ()
@@ -229,7 +229,7 @@ microblaze_target::get_regs_info ()
void
microblaze_target::low_arch_setup ()
{
- current_process ()->tdesc = tdesc_microblaze_linux;
+ current_process ()->tdesc = tdesc_microblaze_linux.get ();
}
linux_process_target *the_linux_target = &the_microblaze_target;
diff --git a/gdbserver/linux-mips-low.cc b/gdbserver/linux-mips-low.cc
index 746887027b5..a156085a557 100644
--- a/gdbserver/linux-mips-low.cc
+++ b/gdbserver/linux-mips-low.cc
@@ -23,6 +23,7 @@
#include "nat/mips-linux-watch.h"
#include "gdb_proc_service.h"
+#include "tdesc.h"
/* Linux target op definitions for the MIPS architecture. */
@@ -89,19 +90,19 @@ static mips_target the_mips_target;
/* Defined in auto-generated file mips-linux.c. */
void init_registers_mips_linux (void);
-extern const struct target_desc *tdesc_mips_linux;
+extern const_target_desc_up tdesc_mips_linux;
/* Defined in auto-generated file mips-dsp-linux.c. */
void init_registers_mips_dsp_linux (void);
-extern const struct target_desc *tdesc_mips_dsp_linux;
+extern const_target_desc_up tdesc_mips_dsp_linux;
/* Defined in auto-generated file mips64-linux.c. */
void init_registers_mips64_linux (void);
-extern const struct target_desc *tdesc_mips64_linux;
+extern const_target_desc_up tdesc_mips64_linux;
/* Defined in auto-generated file mips64-dsp-linux.c. */
void init_registers_mips64_dsp_linux (void);
-extern const struct target_desc *tdesc_mips64_dsp_linux;
+extern const_target_desc_up tdesc_mips64_dsp_linux;
#ifdef __mips64
#define tdesc_mips_linux tdesc_mips64_linux
@@ -206,7 +207,7 @@ mips_read_description (void)
}
}
- return have_dsp ? tdesc_mips_dsp_linux : tdesc_mips_linux;
+ return have_dsp ? tdesc_mips_dsp_linux.get () : tdesc_mips_linux.get ();
}
void
diff --git a/gdbserver/linux-or1k-low.cc b/gdbserver/linux-or1k-low.cc
index 59d2bf7435f..a8d03d86c12 100644
--- a/gdbserver/linux-or1k-low.cc
+++ b/gdbserver/linux-or1k-low.cc
@@ -21,6 +21,7 @@
#include "nat/gdb_ptrace.h"
#include <endian.h>
#include "gdb_proc_service.h"
+#include "tdesc.h"
#include <asm/ptrace.h>
#ifndef PTRACE_GET_THREAD_AREA
@@ -86,7 +87,7 @@ or1k_target::low_set_pc (regcache *regcache, CORE_ADDR pc)
/* Defined in auto-generated file or1k-linux.c. */
void init_registers_or1k_linux (void);
-extern const struct target_desc *tdesc_or1k_linux;
+extern const_target_desc_up tdesc_or1k_linux;
/* This union is used to convert between int and byte buffer
representations of register contents. */
@@ -114,7 +115,7 @@ static int or1k_regmap[] = {
void
or1k_target::low_arch_setup ()
{
- current_process ()->tdesc = tdesc_or1k_linux;
+ current_process ()->tdesc = tdesc_or1k_linux.get ();
}
/* Implement the low_cannot_fetch_register linux target ops method. */
diff --git a/gdbserver/linux-s390-ipa.cc b/gdbserver/linux-s390-ipa.cc
index 548107f9819..c4e0e90db1b 100644
--- a/gdbserver/linux-s390-ipa.cc
+++ b/gdbserver/linux-s390-ipa.cc
@@ -20,6 +20,7 @@
#include <sys/mman.h>
#include "tracepoint.h"
+#include "tdesc.h"
#include "linux-s390-tdesc.h"
#include <elf.h>
#ifdef HAVE_GETAUXVAL
@@ -319,63 +320,63 @@ get_ipa_tdesc (int idx)
case S390_TDESC_64:
/* Subtract number of VX regs. */
SET_REGMAP(s390x_ft_collect_regmap, 32);
- return tdesc_s390x_linux64;
+ return tdesc_s390x_linux64.get ();
case S390_TDESC_64V1:
SET_REGMAP(s390x_ft_collect_regmap, 32);
- return tdesc_s390x_linux64v1;
+ return tdesc_s390x_linux64v1.get ();
case S390_TDESC_64V2:
SET_REGMAP(s390x_ft_collect_regmap, 32);
- return tdesc_s390x_linux64v2;
+ return tdesc_s390x_linux64v2.get ();
case S390_TDESC_TE:
SET_REGMAP(s390x_te_ft_collect_regmap, 32);
- return tdesc_s390x_te_linux64;
+ return tdesc_s390x_te_linux64.get ();
case S390_TDESC_VX:
SET_REGMAP(s390x_ft_collect_regmap, 0);
- return tdesc_s390x_vx_linux64;
+ return tdesc_s390x_vx_linux64.get ();
case S390_TDESC_TEVX:
SET_REGMAP(s390x_te_ft_collect_regmap, 0);
- return tdesc_s390x_tevx_linux64;
+ return tdesc_s390x_tevx_linux64.get ();
case S390_TDESC_GS:
SET_REGMAP(s390x_te_ft_collect_regmap, 0);
- return tdesc_s390x_gs_linux64;
+ return tdesc_s390x_gs_linux64.get ();
#else
case S390_TDESC_32:
SET_REGMAP(s390_linux32_ft_collect_regmap, 0);
- return tdesc_s390_linux32;
+ return tdesc_s390_linux32.get ();
case S390_TDESC_32V1:
SET_REGMAP(s390_linux32_ft_collect_regmap, 0);
- return tdesc_s390_linux32v1;
+ return tdesc_s390_linux32v1.get ();
case S390_TDESC_32V2:
SET_REGMAP(s390_linux32_ft_collect_regmap, 0);
- return tdesc_s390_linux32v2;
+ return tdesc_s390_linux32v2.get ();
case S390_TDESC_64:
SET_REGMAP(s390_linux64_ft_collect_regmap, 32);
- return tdesc_s390_linux64;
+ return tdesc_s390_linux64.get ();
case S390_TDESC_64V1:
SET_REGMAP(s390_linux64_ft_collect_regmap, 32);
- return tdesc_s390_linux64v1;
+ return tdesc_s390_linux64v1.get ();
case S390_TDESC_64V2:
SET_REGMAP(s390_linux64_ft_collect_regmap, 32);
- return tdesc_s390_linux64v2;
+ return tdesc_s390_linux64v2.get ();
case S390_TDESC_TE:
SET_REGMAP(s390_te_linux64_ft_collect_regmap, 32);
- return tdesc_s390_te_linux64;
+ return tdesc_s390_te_linux64.get ();
case S390_TDESC_VX:
SET_REGMAP(s390_linux64_ft_collect_regmap, 0);
- return tdesc_s390_vx_linux64;
+ return tdesc_s390_vx_linux64.get ();
case S390_TDESC_TEVX:
SET_REGMAP(s390_te_linux64_ft_collect_regmap, 0);
- return tdesc_s390_tevx_linux64;
+ return tdesc_s390_tevx_linux64.get ();
case S390_TDESC_GS:
SET_REGMAP(s390_te_linux64_ft_collect_regmap, 0);
- return tdesc_s390_gs_linux64;
+ return tdesc_s390_gs_linux64.get ();
#endif
default:
internal_error ("unknown ipa tdesc index: %d", idx);
#ifdef __s390x__
- return tdesc_s390x_linux64;
+ return tdesc_s390x_linux64.get ();
#else
- return tdesc_s390_linux32;
+ return tdesc_s390_linux32.get ();
#endif
}
}
diff --git a/gdbserver/linux-s390-low.cc b/gdbserver/linux-s390-low.cc
index 8a4567837bd..4bb761de1bd 100644
--- a/gdbserver/linux-s390-low.cc
+++ b/gdbserver/linux-s390-low.cc
@@ -30,6 +30,7 @@
#include <elf.h>
#include <inttypes.h>
+#include "tdesc.h"
#include "linux-s390-tdesc.h"
#ifndef HWCAP_S390_HIGH_GPRS
@@ -615,18 +616,18 @@ s390_target::low_arch_setup ()
if (wordsize == 8)
{
if (have_regset_gs)
- tdesc = tdesc_s390x_gs_linux64;
+ tdesc = tdesc_s390x_gs_linux64.get ();
else if (have_regset_vxrs)
- tdesc = (have_regset_tdb ? tdesc_s390x_tevx_linux64 :
- tdesc_s390x_vx_linux64);
+ tdesc = (have_regset_tdb ? tdesc_s390x_tevx_linux64.get () :
+ tdesc_s390x_vx_linux64.get ());
else if (have_regset_tdb)
- tdesc = tdesc_s390x_te_linux64;
+ tdesc = tdesc_s390x_te_linux64.get ();
else if (have_regset_system_call)
- tdesc = tdesc_s390x_linux64v2;
+ tdesc = tdesc_s390x_linux64v2.get ();
else if (have_regset_last_break)
- tdesc = tdesc_s390x_linux64v1;
+ tdesc = tdesc_s390x_linux64v1.get ();
else
- tdesc = tdesc_s390x_linux64;
+ tdesc = tdesc_s390x_linux64.get ();
}
/* For a 31-bit inferior, check whether the kernel supports
@@ -637,28 +638,28 @@ s390_target::low_arch_setup ()
{
have_hwcap_s390_high_gprs = 1;
if (have_regset_gs)
- tdesc = tdesc_s390_gs_linux64;
+ tdesc = tdesc_s390_gs_linux64.get ();
else if (have_regset_vxrs)
- tdesc = (have_regset_tdb ? tdesc_s390_tevx_linux64 :
- tdesc_s390_vx_linux64);
+ tdesc = (have_regset_tdb ? tdesc_s390_tevx_linux64.get () :
+ tdesc_s390_vx_linux64.get ());
else if (have_regset_tdb)
- tdesc = tdesc_s390_te_linux64;
+ tdesc = tdesc_s390_te_linux64.get ();
else if (have_regset_system_call)
- tdesc = tdesc_s390_linux64v2;
+ tdesc = tdesc_s390_linux64v2.get ();
else if (have_regset_last_break)
- tdesc = tdesc_s390_linux64v1;
+ tdesc = tdesc_s390_linux64v1.get ();
else
- tdesc = tdesc_s390_linux64;
+ tdesc = tdesc_s390_linux64.get ();
}
else
{
/* Assume 31-bit inferior process. */
if (have_regset_system_call)
- tdesc = tdesc_s390_linux32v2;
+ tdesc = tdesc_s390_linux32v2.get ();
else if (have_regset_last_break)
- tdesc = tdesc_s390_linux32v1;
+ tdesc = tdesc_s390_linux32v1.get ();
else
- tdesc = tdesc_s390_linux32;
+ tdesc = tdesc_s390_linux32.get ();
}
have_hwcap_s390_vx = have_regset_vxrs;
@@ -1451,41 +1452,41 @@ s390_target::get_ipa_tdesc_idx ()
const target_desc *tdesc = current_process ()->tdesc;
#ifdef __s390x__
- if (tdesc == tdesc_s390x_linux64)
+ if (tdesc == tdesc_s390x_linux64.get ())
return S390_TDESC_64;
- if (tdesc == tdesc_s390x_linux64v1)
+ if (tdesc == tdesc_s390x_linux64v1.get ())
return S390_TDESC_64V1;
- if (tdesc == tdesc_s390x_linux64v2)
+ if (tdesc == tdesc_s390x_linux64v2.get ())
return S390_TDESC_64V2;
- if (tdesc == tdesc_s390x_te_linux64)
+ if (tdesc == tdesc_s390x_te_linux64.get ())
return S390_TDESC_TE;
- if (tdesc == tdesc_s390x_vx_linux64)
+ if (tdesc == tdesc_s390x_vx_linux64.get ())
return S390_TDESC_VX;
- if (tdesc == tdesc_s390x_tevx_linux64)
+ if (tdesc == tdesc_s390x_tevx_linux64.get ())
return S390_TDESC_TEVX;
- if (tdesc == tdesc_s390x_gs_linux64)
+ if (tdesc == tdesc_s390x_gs_linux64.get ())
return S390_TDESC_GS;
#endif
- if (tdesc == tdesc_s390_linux32)
+ if (tdesc == tdesc_s390_linux32.get ())
return S390_TDESC_32;
- if (tdesc == tdesc_s390_linux32v1)
+ if (tdesc == tdesc_s390_linux32v1.get ())
return S390_TDESC_32V1;
- if (tdesc == tdesc_s390_linux32v2)
+ if (tdesc == tdesc_s390_linux32v2.get ())
return S390_TDESC_32V2;
- if (tdesc == tdesc_s390_linux64)
+ if (tdesc == tdesc_s390_linux64.get ())
return S390_TDESC_64;
- if (tdesc == tdesc_s390_linux64v1)
+ if (tdesc == tdesc_s390_linux64v1.get ())
return S390_TDESC_64V1;
- if (tdesc == tdesc_s390_linux64v2)
+ if (tdesc == tdesc_s390_linux64v2.get ())
return S390_TDESC_64V2;
- if (tdesc == tdesc_s390_te_linux64)
+ if (tdesc == tdesc_s390_te_linux64.get ())
return S390_TDESC_TE;
- if (tdesc == tdesc_s390_vx_linux64)
+ if (tdesc == tdesc_s390_vx_linux64.get ())
return S390_TDESC_VX;
- if (tdesc == tdesc_s390_tevx_linux64)
+ if (tdesc == tdesc_s390_tevx_linux64.get ())
return S390_TDESC_TEVX;
- if (tdesc == tdesc_s390_gs_linux64)
+ if (tdesc == tdesc_s390_gs_linux64.get ())
return S390_TDESC_GS;
return 0;
diff --git a/gdbserver/linux-s390-tdesc.h b/gdbserver/linux-s390-tdesc.h
index b4d63430df5..3c53a717f6b 100644
--- a/gdbserver/linux-s390-tdesc.h
+++ b/gdbserver/linux-s390-tdesc.h
@@ -41,31 +41,31 @@ enum s390_linux_tdesc {
/* Defined in auto-generated file s390x-linux64.c. */
void init_registers_s390x_linux64 (void);
-extern const struct target_desc *tdesc_s390x_linux64;
+extern const_target_desc_up tdesc_s390x_linux64;
/* Defined in auto-generated file s390x-linux64v1.c. */
void init_registers_s390x_linux64v1 (void);
-extern const struct target_desc *tdesc_s390x_linux64v1;
+extern const_target_desc_up tdesc_s390x_linux64v1;
/* Defined in auto-generated file s390x-linux64v2.c. */
void init_registers_s390x_linux64v2 (void);
-extern const struct target_desc *tdesc_s390x_linux64v2;
+extern const_target_desc_up tdesc_s390x_linux64v2;
/* Defined in auto-generated file s390x-te-linux64.c. */
void init_registers_s390x_te_linux64 (void);
-extern const struct target_desc *tdesc_s390x_te_linux64;
+extern const_target_desc_up tdesc_s390x_te_linux64;
/* Defined in auto-generated file s390x-vx-linux64.c. */
void init_registers_s390x_vx_linux64 (void);
-extern const struct target_desc *tdesc_s390x_vx_linux64;
+extern const_target_desc_up tdesc_s390x_vx_linux64;
/* Defined in auto-generated file s390x-tevx-linux64.c. */
void init_registers_s390x_tevx_linux64 (void);
-extern const struct target_desc *tdesc_s390x_tevx_linux64;
+extern const_target_desc_up tdesc_s390x_tevx_linux64;
/* Defined in auto-generated file s390x-gs-linux64.c. */
void init_registers_s390x_gs_linux64 (void);
-extern const struct target_desc *tdesc_s390x_gs_linux64;
+extern const_target_desc_up tdesc_s390x_gs_linux64;
#endif
@@ -73,43 +73,43 @@ extern const struct target_desc *tdesc_s390x_gs_linux64;
/* Defined in auto-generated file s390-linux32.c. */
void init_registers_s390_linux32 (void);
-extern const struct target_desc *tdesc_s390_linux32;
+extern const_target_desc_up tdesc_s390_linux32;
/* Defined in auto-generated file s390-linux32v1.c. */
void init_registers_s390_linux32v1 (void);
-extern const struct target_desc *tdesc_s390_linux32v1;
+extern const_target_desc_up tdesc_s390_linux32v1;
/* Defined in auto-generated file s390-linux32v2.c. */
void init_registers_s390_linux32v2 (void);
-extern const struct target_desc *tdesc_s390_linux32v2;
+extern const_target_desc_up tdesc_s390_linux32v2;
/* Defined in auto-generated file s390-linux64.c. */
void init_registers_s390_linux64 (void);
-extern const struct target_desc *tdesc_s390_linux64;
+extern const_target_desc_up tdesc_s390_linux64;
/* Defined in auto-generated file s390-linux64v1.c. */
void init_registers_s390_linux64v1 (void);
-extern const struct target_desc *tdesc_s390_linux64v1;
+extern const_target_desc_up tdesc_s390_linux64v1;
/* Defined in auto-generated file s390-linux64v2.c. */
void init_registers_s390_linux64v2 (void);
-extern const struct target_desc *tdesc_s390_linux64v2;
+extern const_target_desc_up tdesc_s390_linux64v2;
/* Defined in auto-generated file s390-te-linux64.c. */
void init_registers_s390_te_linux64 (void);
-extern const struct target_desc *tdesc_s390_te_linux64;
+extern const_target_desc_up tdesc_s390_te_linux64;
/* Defined in auto-generated file s390-vx-linux64.c. */
void init_registers_s390_vx_linux64 (void);
-extern const struct target_desc *tdesc_s390_vx_linux64;
+extern const_target_desc_up tdesc_s390_vx_linux64;
/* Defined in auto-generated file s390-tevx-linux64.c. */
void init_registers_s390_tevx_linux64 (void);
-extern const struct target_desc *tdesc_s390_tevx_linux64;
+extern const_target_desc_up tdesc_s390_tevx_linux64;
/* Defined in auto-generated file s390-gs-linux64.c. */
void init_registers_s390_gs_linux64 (void);
-extern const struct target_desc *tdesc_s390_gs_linux64;
+extern const_target_desc_up tdesc_s390_gs_linux64;
#endif
diff --git a/gdbserver/linux-sh-low.cc b/gdbserver/linux-sh-low.cc
index 6370c18c677..a71a3a9c742 100644
--- a/gdbserver/linux-sh-low.cc
+++ b/gdbserver/linux-sh-low.cc
@@ -17,6 +17,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "linux-low.h"
+#include "tdesc.h"
/* Linux target op definitions for the SH architecture. */
@@ -69,7 +70,7 @@ sh_target::low_set_pc (regcache *regcache, CORE_ADDR pc)
/* Defined in auto-generated file reg-sh.c. */
void init_registers_sh (void);
-extern const struct target_desc *tdesc_sh;
+extern const_target_desc_up tdesc_sh;
#ifdef HAVE_SYS_REG_H
#include <sys/reg.h>
@@ -179,7 +180,7 @@ sh_target::get_regs_info ()
void
sh_target::low_arch_setup ()
{
- current_process ()->tdesc = tdesc_sh;
+ current_process ()->tdesc = tdesc_sh.get ();
}
/* The linux target ops object. */
diff --git a/gdbserver/linux-sparc-low.cc b/gdbserver/linux-sparc-low.cc
index 77edfbdde2a..10926a93991 100644
--- a/gdbserver/linux-sparc-low.cc
+++ b/gdbserver/linux-sparc-low.cc
@@ -21,6 +21,7 @@
#include "nat/gdb_ptrace.h"
#include "gdb_proc_service.h"
+#include "tdesc.h"
/* The stack pointer is offset from the stack frame by a BIAS of 2047
(0x7ff) for 64-bit code. BIAS is likely to be defined on SPARC
@@ -142,7 +143,7 @@ static const struct regs_range_t fpregs_ranges[] = {
/* Defined in auto-generated file reg-sparc64.c. */
void init_registers_sparc64 (void);
-extern const struct target_desc *tdesc_sparc64;
+extern const_target_desc_up tdesc_sparc64;
bool
sparc_target::low_cannot_store_register (int regno)
@@ -298,7 +299,7 @@ sparc_target::low_breakpoint_at (CORE_ADDR where)
void
sparc_target::low_arch_setup ()
{
- current_process ()->tdesc = tdesc_sparc64;
+ current_process ()->tdesc = tdesc_sparc64.get ();
}
static struct regset_info sparc_regsets[] = {
diff --git a/gdbserver/linux-xtensa-low.cc b/gdbserver/linux-xtensa-low.cc
index 3af9bc44fb1..f06905645cf 100644
--- a/gdbserver/linux-xtensa-low.cc
+++ b/gdbserver/linux-xtensa-low.cc
@@ -18,6 +18,7 @@
#include "linux-low.h"
+#include "tdesc.h"
/* Linux target op definitions for the Xtensa architecture. */
@@ -84,7 +85,7 @@ xtensa_target::low_set_pc (regcache *regcache, CORE_ADDR pc)
/* Defined in auto-generated file reg-xtensa.c. */
void init_registers_xtensa (void);
-extern const struct target_desc *tdesc_xtensa;
+extern const_target_desc_up tdesc_xtensa;
#include <asm/ptrace.h>
#include <xtensa-config.h>
@@ -310,7 +311,7 @@ static struct regs_info myregs_info =
void
xtensa_target::low_arch_setup ()
{
- current_process ()->tdesc = tdesc_xtensa;
+ current_process ()->tdesc = tdesc_xtensa.get ();
}
const regs_info *
--
2.53.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] regdat.sh: generate const_target_desc_up for register descriptions
2026-06-18 14:23 ` [PATCH 1/2] regdat.sh: generate const_target_desc_up for register descriptions Keith Seitz
@ 2026-06-18 15:52 ` Simon Marchi
0 siblings, 0 replies; 7+ messages in thread
From: Simon Marchi @ 2026-06-18 15:52 UTC (permalink / raw)
To: Keith Seitz, gdb-patches
On 2026-06-18 10:23, Keith Seitz wrote:
> @@ -195,12 +194,12 @@ echo
> osabi_enum=$(grep "${osabi}" "$2" | sed 's/.*(\([^,]\+\),.*/GDB_OSABI_\1/')
>
> cat <<EOF
> - result->xmltarget = xmltarget_${name};
> + result.get ()->xmltarget = xmltarget_${name};
I don't think this .get() is needed.
Simon
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 0/2] Fix ODR violations in regformat target descriptions
2026-06-18 14:23 [PATCH 0/2] Fix ODR violations in regformat target descriptions Keith Seitz
2026-06-18 14:23 ` [PATCH 1/2] regdat.sh: generate const_target_desc_up for register descriptions Keith Seitz
2026-06-18 14:23 ` [PATCH 2/2] [gdbserver] Use const_target_desc_up for regformat tdescs Keith Seitz
@ 2026-06-18 15:57 ` Simon Marchi
2026-06-18 17:10 ` Tom Tromey
2 siblings, 1 reply; 7+ messages in thread
From: Simon Marchi @ 2026-06-18 15:57 UTC (permalink / raw)
To: Keith Seitz, gdb-patches
On 2026-06-18 10:23, Keith Seitz wrote:
> Commit 1a5362ce51ef ("gdb, gdbserver: propagate use of target_desc unique
> pointers") changd most target descriptions to "const_target_desc_up," but
> deliberately left gdb/regformats/regdat.sh unchanged because those descriptions
> were still emitted as file-local static "struct target_desc" objects declared
> "const struct target_desc *".
>
> That mismatch breaks gdbserver on ppc64le when LTO is enabled. The shared
> header gdb/arch/ppc-linux-tdesc.h declares symbols such as
> "tdesc_powerpc_isa207_htm_vsx64l" as "const_target_desc_up," while regdat-
> generated translation units still define them as raw pointers. This reintroduces
> previously settled ODR violations.
>
> This series updates regdat.sh to generate code consistent with the unique-pointer
> API, then updates gdbserver targets that declare those symbols locally.
>
> There are no intended user-visible changes.
Other than the little nit I sent on patch 1, this series LGTM (although
I still don't fully understand why regdat exists and how it works).
Approved-By: Simon Marchi <simon.marchi@efficios.com>
It's unfortunate that this problem was only found by building with LTO.
If one builds without LTO, then I suppose it goes unnoticed and the
program could misbehave. Although in this case, a unique_ptr and a raw
pointer have the same memory footprint, so it was probably fine, by
chance.
The problem is that we have hardcoded declarations for whatever is in
the generated files. And since the generated files don't see the
declarations, the compiler doesn't complain about any mismatch. I think
it would be nice to change the scripts that generate these .c files to
also generate header files with matching declarations, and then have
the hand-written source files include these generated header files.
Simon
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 0/2] Fix ODR violations in regformat target descriptions
2026-06-18 15:57 ` [PATCH 0/2] Fix ODR violations in regformat target descriptions Simon Marchi
@ 2026-06-18 17:10 ` Tom Tromey
2026-07-07 19:49 ` Keith Seitz
0 siblings, 1 reply; 7+ messages in thread
From: Tom Tromey @ 2026-06-18 17:10 UTC (permalink / raw)
To: Simon Marchi; +Cc: Keith Seitz, gdb-patches
>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:
Simon> Other than the little nit I sent on patch 1, this series LGTM (although
Simon> I still don't fully understand why regdat exists and how it works).
I was curious about this as well. Like, how hard is it to remove this?
Since IIUC it's an obsolete way of writing a target description.
Tom
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 0/2] Fix ODR violations in regformat target descriptions
2026-06-18 17:10 ` Tom Tromey
@ 2026-07-07 19:49 ` Keith Seitz
0 siblings, 0 replies; 7+ messages in thread
From: Keith Seitz @ 2026-07-07 19:49 UTC (permalink / raw)
To: Tom Tromey, Simon Marchi; +Cc: gdb-patches
On 6/18/26 10:10 AM, Tom Tromey wrote:
>>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:
>
> Simon> Other than the little nit I sent on patch 1, this series LGTM (although
> Simon> I still don't fully understand why regdat exists and how it works).
>
> I was curious about this as well. Like, how hard is it to remove this?
> Since IIUC it's an obsolete way of writing a target description.
From what I understand while hacking at this, you are correct. It is a
very outdated way of writing a target description. The modern way is via
XML/features.
I asked Claude to explain what would it would take to get rid of this
and update everything. Unless it is completely fabricating its response
(and I have not read anything to suggest such), it is a non-trivial
amount of work.
The short of it is, there are six "legacy" targets with no XML backing
whatsoever. These targets include padding registers, integer-only
registers (missing FP), and other peculiarities which may be non-trivial
to implement completely and/or correctly. [Or not -- I've not dug *that*
deeply into it.]
There are an additional 42 targets which are XML-backed that would also
require some conversion. Testing all of these will be a nightmare.
If you'd like, I can file a bug and add the complete Claude response.
Just let me know.
In the meantime, I've pushed these patches. Thank you to you and Simon
for your reviews.
Keith
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-07-07 19:50 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-18 14:23 [PATCH 0/2] Fix ODR violations in regformat target descriptions Keith Seitz
2026-06-18 14:23 ` [PATCH 1/2] regdat.sh: generate const_target_desc_up for register descriptions Keith Seitz
2026-06-18 15:52 ` Simon Marchi
2026-06-18 14:23 ` [PATCH 2/2] [gdbserver] Use const_target_desc_up for regformat tdescs Keith Seitz
2026-06-18 15:57 ` [PATCH 0/2] Fix ODR violations in regformat target descriptions Simon Marchi
2026-06-18 17:10 ` Tom Tromey
2026-07-07 19:49 ` Keith Seitz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox