PPC argument handling improvements
* sysdeps/linux-gnu/ppc/trace.c (arch_umovelong): New function.
* sysdeps/linux-gnu/ppc/regs.c (get_instruction): New function.
(get_count_register): New function.
* sysdeps/linux-gnu/ppc/arch.h (ARCH_HAVE_UMOVELONG): New define.
* sysdeps/linux-gnu/trace.c (umovelong): Create arch-specific
variant.
* ltrace.h (umovelong): Change prototype.
* process_event.c (process_breakpoint): Handle specifics of ppc3
* display_args.c: Call umovelong with info parameter.
diff --git a/process_event.c b/process_event.c
index 419eb9c..9e6ef81 100644
--- a/process_event.c
+++ b/process_event.c
@@ -248,21 +248,29 @@
struct breakpoint *sbp;
debug(2, "event: breakpoint (%p)", event->e_un.brk_addr);
- if ((sbp = event->proc->breakpoint_being_enabled) != 0) {
+
#ifdef __powerpc__
- struct breakpoint *nxtbp;
- char nop_inst[] = PPC_NOP;
- if (memcmp(sbp->orig_value, nop_inst, PPC_NOP_LENGTH) == 0) {
- nxtbp = address2bpstruct(event->proc,
- event->e_un.brk_addr +
- PPC_NOP_LENGTH);
- if (nxtbp != 0) {
- enable_breakpoint(event->proc->pid, sbp);
- continue_after_breakpoint(event->proc, nxtbp);
+ /* Need to skip following NOP's to prevent a fake function from being stacked. */
+ long stub_addr = (long) get_count_register(event->proc);
+ struct breakpoint *stub_bp = NULL;
+ char nop_instruction[] = PPC_NOP;
+
+ stub_bp = address2bpstruct (event->proc, event->e_un.brk_addr);
+
+ if (stub_bp) {
+ unsigned char *bp_instruction = stub_bp->orig_value;
+
+ if (memcmp(bp_instruction, nop_instruction,
+ PPC_NOP_LENGTH) == 0) {
+ if (stub_addr != (long) event->e_un.brk_addr) {
+ set_instruction_pointer (event->proc, event->e_un.brk_addr + 4);
+ continue_process(event->proc->pid);
return;
}
}
+ }
#endif
+ if ((sbp = event->proc->breakpoint_being_enabled) != 0) {
/* Reinsert breakpoint */
continue_enabling_breakpoint(event->proc->pid,
event->proc->