Version 0.3.33
* Fixed two bugs, thanks to Mauro Meneghin <G1ld0@lycos.it>:
+ Cope correctly with breakpoint values greater than
sizeof(long) bytes
+ Fixed small bug in option -r (closes: Bug#212792)
* Show help if no (or few) arguments are given, just like
strace and fenris (thanks, Tomasz Wegrzanowski <taw@users.sf.net>)
* Some fixes from Jakub Bogusz <qboosh@pld-linux.org>:
+ Small 64-bit cleanup of code
+ support for more than 6 function arguments on amd64
+ Adapted SPARC port from Jakub Jelinek <jakub@redhat.com>
+ Added alpha support
diff --git a/sysdeps/linux-gnu/sparc/trace.c b/sysdeps/linux-gnu/sparc/trace.c
new file mode 100644
index 0000000..f88d503
--- /dev/null
+++ b/sysdeps/linux-gnu/sparc/trace.c
@@ -0,0 +1,81 @@
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <string.h>
+#include "ptrace.h"
+#include "ltrace.h"
+
+extern FILE *output;
+extern int opt_d;
+
+void get_arch_dep(struct process *proc)
+{
+ proc_archdep *a;
+ if (!proc->arch_ptr)
+ proc->arch_ptr = (void *)malloc(sizeof(proc_archdep));
+ a = (proc_archdep *)(proc->arch_ptr);
+ a->valid = (ptrace (PTRACE_GETREGS, proc->pid, &a->regs, 0) >= 0);
+}
+
+/* Returns syscall number if `pid' stopped because of a syscall.
+ * Returns -1 otherwise
+ */
+int syscall_p(struct process *proc, int status, int *sysnum)
+{
+ if (WIFSTOPPED(status) && WSTOPSIG(status)==SIGTRAP) {
+ void *ip = get_instruction_pointer(proc);
+ unsigned int insn;
+ if (ip == (void *)-1) return 0;
+ insn = ptrace(PTRACE_PEEKTEXT, proc->pid, ip, 0);
+ if ((insn & 0xc1f8007f) == 0x81d00010) {
+ *sysnum = ((proc_archdep *)proc->arch_ptr)->regs.r_g1;
+ if ((proc->callstack_depth > 0) && proc->callstack[proc->callstack_depth-1].is_syscall) {
+ return 2;
+ } else if(*sysnum>=0) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+long gimme_arg(enum tof type, struct process * proc, int arg_num)
+{
+ proc_archdep * a = (proc_archdep *)proc->arch_ptr;
+ if (!a->valid) {
+ fprintf(stderr, "Could not get child registers\n");
+ exit(1);
+ }
+ if (arg_num==-1) /* return value */
+ return a->regs.r_o0;
+
+ if (type==LT_TOF_FUNCTION || type==LT_TOF_SYSCALL || arg_num >= 6) {
+ if (arg_num < 6)
+ return ((int *)&a->regs.r_o0)[arg_num];
+ return ptrace(PTRACE_PEEKTEXT, proc->pid, proc->stack_pointer+64*(arg_num + 1));
+ } else if (type==LT_TOF_FUNCTIONR)
+ return a->func_arg[arg_num];
+ else if (type==LT_TOF_SYSCALLR)
+ return a->sysc_arg[arg_num];
+ else {
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ exit(1);
+ }
+ return 0;
+}
+
+void save_register_args(enum tof type, struct process * proc)
+{
+ proc_archdep * a = (proc_archdep *)proc->arch_ptr;
+ if (a->valid) {
+ if (type == LT_TOF_FUNCTION)
+ memcpy(a->func_arg, &a->regs.r_o0, sizeof(a->func_arg));
+ else
+ memcpy(a->sysc_arg, &a->regs.r_o0, sizeof(a->sysc_arg));
+ }
+}