[binutils-gdb] PowerPC: fix external calls from modules built by the compile command

Abhay Kandpal via Gdb-cvs <[email protected]>
Newsgroups gmane.comp.gdb.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a6d0eb39462588ed757cb1fe97749863604588ff

commit a6d0eb39462588ed757cb1fe97749863604588ff
Author: Abhay Kandpal <[email protected]>
Date:   Thu Aug 20 07:03:57 2026 -0500

    PowerPC: fix external calls from modules built by the compile command
    
    A module built for the compile command is loaded into inferior memory
    without a linker, so it has no PLT.  On ELFv2 the default code model
    still emits a direct bl for a call to another module, leaving r12 unset
    and the caller's TOC pointer unrestored, and the callee then derives a
    wrong r2 from a stale r12.
    
    gdb.compile/compile-setjmp.exp shows this: the injected code calls
    setjmp, whose global entry point computes r2 from a stale r12, and the
    first TOC-relative load segfaults.
    
    -mlongcall makes the call indirect, but on its own it reaches the target
    through a PLT entry, giving R_PPC64_PLT16_HA/LO_DS relocations that BFD's
    generic linker rejects.  Adding -mno-pltseq resolves the call against the
    module's own TOC instead, via R_PPC64_TOC16_HA/LO_DS, which GDB already
    handles.  GCC then emits the r2 save and restore around the call itself.
    
    Tested on powerpc64le-linux; the two compile-setjmp.exp failures now pass
    with no unexpected failures in the full testsuite.
    
    gdb/
            * ppc-linux-tdep.c (ppc64_gcc_target_options): New function.
            (ppc_linux_init_abi): Set gcc_target_options for ELFv2.
    
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=34551
    Suggested-by: Ulrich Weigand <[email protected]>

Diff:
---
 gdb/ppc-linux-tdep.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index 8a55ff5d4af..b468dbcb62c 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -2196,6 +2196,18 @@ rs6000_linux_adjust_frame_regnum (struct gdbarch *gdbarch, int num,
   return num;
 }
 
+/* Implement gdbarch_gcc_target_options.  A module built for the "compile"
+   command is loaded into inferior memory without a linker, so it has no
+   PLT.  -mlongcall makes calls to other modules indirect, and -mno-pltseq
+   stops GCC reaching the target through a PLT entry; together they let the
+   call be resolved against the module's own TOC.  */
+
+static std::string
+ppc64_gcc_target_options (struct gdbarch *gdbarch)
+{
+  return default_gcc_target_options (gdbarch) + " -mlongcall -mno-pltseq";
+}
+
 static void
 ppc_linux_init_abi (struct gdbarch_info info,
 		    struct gdbarch *gdbarch)
@@ -2304,6 +2316,7 @@ ppc_linux_init_abi (struct gdbarch_info info,
 	    (gdbarch, ppc_elfv2_elf_make_msymbol_special);
 
 	  set_gdbarch_skip_entrypoint (gdbarch, ppc_elfv2_skip_entrypoint);
+	  set_gdbarch_gcc_target_options (gdbarch, ppc64_gcc_target_options);
 	}
 
       /* Shared library handling.  */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.