Re: [PATCHi v1] PowerPC: Create call stubs for compiled modules
Abhay Kandpal <[email protected]>
| Newsgroups | gmane.comp.gdb.patches |
|---|---|
| Message-ID | <[email protected]> |
Hi Ulrich, Thanks for the suggestion. I tried|-mlongcall| and it doesn't work on PowerPC, though not for the reason I expected. gcc does generate the right calling sequence with it - saves r2, loads the target into r12, uses mtctr/bctrl, restores r2: 24: std r2,24(r1) 30: addis r12,r2,0 30: R_PPC64_PLT16_HA _setjmp 34: ld r12,0(r12) 34: R_PPC64_PLT16_LO_DS _setjmp 80: mtctr r12 80: R_PPC64_PLTSEQ longjmp 84: bctrl 84: R_PPC64_PLTCALL longjmp 88: ld r2,24(r1) But it obtains the target address from a PLT slot addressed off r2, so the calls need R_PPC64_PLT16_HA / R_PPC64_PLT16_LO_DS, which BFD's generic linker rejects: warning: Compiled module "/tmp/gdbobj-6tZVEd/out1.o" section ".text": dangerous relocation: generic linker can't handle R_PPC64_PLT16_HA warning: Compiled module "/tmp/gdbobj-6tZVEd/out1.o" section ".text": dangerous relocation: generic linker can't handle R_PPC64_PLT16_LO_DS |-mlongcall| also converts the intra-module call to a PLT call, so it fails earlier than before - in|_gdb_expr| rather than in the callee. Same result with|-mcmodel=large -mlongcall| and with|-fno-plt -mlongcall| (|-mno-plt| is not recognised on PowerPC). So on PowerPC|-mlongcall| gives the correct convention but still requires a PLT, which is the one thing GDB can't supply. Resolving PLT16 would mean building a table within +-32KB of the module's TOC and computing slot offsets - more machinery than the stub, not less. With the patch, GDB builds the target address as immediates instead, needing no table: call site: bl <stub> ld r2,24(r1) ; the nop, rewritten stub: std r2,24(r1) lis r12,target@highest ori r12,r12,target@higher rldicr r12,r12,32,31 oris r12,r12,target@h ori r12,r12,target@l mtctr r12 bctr At entry to|_setjmp|, r12 holds the callee's entry address and r2 the correct TOC; before the patch r2 pointed past the end of libc, which is the SIGSEGV. The patch applies cleanly to master and gives 526 passes, 0 failures in gdb.compile on powerpc64le. Thanks Abhay On 18/08/26 17:49, Ulrich Weigand wrote: > Abhay Kandpal<[email protected]> wrote: > >> The compile command loads a module into inferior memory and relocates >> it itself, without a linker. For R_PPC64_REL24 it patches the branch >> to point directly at the target. On ELFv2 that is not a valid call to >> another module: the callee derives its TOC pointer from r12, which > only >> a PLT-style call stub sets up, and the caller's TOC pointer is never >> restored because the nop following the bl is left alone. > On other platforms, the way this is supposed to work is to use a > set of compiler command-line options that result in code that does > not require PLTs for external calls. Typically, this means to use > -mcmodel=large. > > However, it seems that on PowerPC, while that option exists, it > generates code that still needs PLTs. There is another option > -mlongcall that should avoid this, however. > > I'm wondering if we were to just add -mlongcall to the platform- > specific compiler options for PowerPC, we could fix this issue > without having to reimplement a full PLT solution in GDB ... > > Bye, > Ulrich