[Bug compile/34456] ppc64le: "compile" command corrupts addresses of inferior symbols (-mcmodel=medium TOC16 relocation overflow)
abhay at sourceware dot org via Gdb-prs <[email protected]>
| Newsgroups | gmane.comp.gdb.bugs.discuss |
|---|---|
| Message-ID | <[email protected]/bugzilla/> |
https://sourceware.org/bugzilla/show_bug.cgi?id=34456 --- Comment #2 from Abhay Kandpal <abhay at sourceware dot org> --- proposed solution $ cat 0001-PowerPC-Use-mcmodel-large-for-the-compile-command.patch From 45e4c58f8458bd42dfcb1675fbcfc7900d18ed49 Mon Sep 17 00:00:00 2001 From: Abhay Kandpal <[email protected]> Date: Tue, 28 Jul 2026 00:22:15 -0500 Subject: [PATCH v1] PowerPC: Use -mcmodel=large for the compile command On ppc64le, the "compile" command produces corrupted code when the compiled expression takes the address of a symbol in the inferior. For example: (gdb) break -qualified main (gdb) run (gdb) compile code pmf = &A::get_var1 (gdb) x/2gx &pmf 0x7fffffffeb68: 0x0000800010000d78 0x0000000000000000 The stored address is wrong: the low 32 bits are correct (0x10000d78, the true address of A::get_var1) but bit 47 is incorrectly set. When the compiled code later calls through such a pointer the inferior jumps to unmapped memory and receives SIGSEGV. The cause is the code model used to compile the injected object. Commit 533f04079c7 ("[gdb] [rs6000] Add ppc64_linux_gcc_target_options method.") made ppc64 return an empty string from gdbarch_gcc_target_options, overriding the "-mcmodel=large" that default_gcc_target_options supplies for 64-bit targets, so GCC falls back to -mcmodel=medium. With the medium model, references to the inferior's symbols are compiled as TOC-relative accesses using R_PPC64_TOC16_HA/LO relocations, whose combined displacement is a signed 32-bit value (+/- 2GB). GDB allocates the compiled module in the inferior with an mmap that the kernel places in the high mmap region (e.g. around 0x7ffff7f30000), while the inferior's own text is low (e.g. around 0x10000000). The distance between them is close to 2^47, far beyond the reach of a TOC16 relocation, so the displacement is silently truncated to 32 bits, producing an address that is off by 2^47. Restore -mcmodel=large for ppc64. With the large model GCC emits a real .toc section and loads symbol addresses as full 64-bit values from it, so the only TOC-relative references are into the module's own .toc, which is always in range regardless of where the module is mapped. The .TOC. handling added by commit bad23de3543 ("[gdb] Handle .TOC. sections during gdb-compile for rs6000 target.") continues to work; it now resolves via the module's genuine .toc section rather than the .text fallback that the medium model required. Tested on powerpc64le-linux (Fedora, GCC 15.2.1). Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=34456 gdb/ * ppc-linux-tdep.c (ppc64_linux_gcc_target_options): Return "-mcmodel=large". --- This patch is reg tested. gdb/ppc-linux-tdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c index 1d54b72bb1d..67f31e7b308 100644 --- a/gdb/ppc-linux-tdep.c +++ b/gdb/ppc-linux-tdep.c @@ -2081,7 +2081,7 @@ ppc64_gnu_triplet_regexp (struct gdbarch *gdbarch) static std::string ppc64_linux_gcc_target_options (struct gdbarch *gdbarch) { - return ""; + return "-mcmodel=large"; } /* Fetch and return the TLS DTV (dynamic thread vector) address for PTID. -- 2.52.0 -- You are receiving this mail because: You are on the CC list for the bug.