[PATCH v2] PowerPC: fix external calls from modules built by the compile command

Abhay Kandpal <[email protected]>
Newsgroups gmane.comp.gdb.patches
Message-ID <[email protected]>
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.

Suggested-by: Ulrich Weigand <[email protected]>
---
This patch is reg tested.

 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.  */
-- 
2.52.0
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.