aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/linux-gnu/Makefile21
-rw-r--r--sysdeps/linux-gnu/alpha/arch.h4
-rw-r--r--sysdeps/linux-gnu/alpha/plt.c10
-rw-r--r--sysdeps/linux-gnu/alpha/regs.c24
-rw-r--r--sysdeps/linux-gnu/alpha/trace.c46
-rw-r--r--sysdeps/linux-gnu/arm/arch.h3
-rw-r--r--sysdeps/linux-gnu/arm/plt.c10
-rw-r--r--sysdeps/linux-gnu/arm/regs.c16
-rw-r--r--sysdeps/linux-gnu/arm/trace.c51
-rw-r--r--sysdeps/linux-gnu/breakpoint.c55
-rw-r--r--sysdeps/linux-gnu/i386/arch.h3
-rw-r--r--sysdeps/linux-gnu/i386/plt.c10
-rw-r--r--sysdeps/linux-gnu/i386/regs.c22
-rw-r--r--sysdeps/linux-gnu/i386/syscallent.h9
-rw-r--r--sysdeps/linux-gnu/i386/trace.c61
-rw-r--r--sysdeps/linux-gnu/ia64/arch.h4
-rw-r--r--sysdeps/linux-gnu/ia64/plt.c5
-rw-r--r--sysdeps/linux-gnu/ia64/syscallent.h21
-rw-r--r--sysdeps/linux-gnu/ia64/trace.c3
-rw-r--r--sysdeps/linux-gnu/m68k/arch.h3
-rw-r--r--sysdeps/linux-gnu/m68k/plt.c12
-rw-r--r--sysdeps/linux-gnu/m68k/regs.c22
-rw-r--r--sysdeps/linux-gnu/m68k/trace.c69
-rw-r--r--sysdeps/linux-gnu/ppc/arch.h12
-rw-r--r--sysdeps/linux-gnu/ppc/plt.c38
-rw-r--r--sysdeps/linux-gnu/ppc/regs.c24
-rw-r--r--sysdeps/linux-gnu/ppc/syscallent.h9
-rw-r--r--sysdeps/linux-gnu/ppc/trace.c44
-rw-r--r--sysdeps/linux-gnu/proc.c10
-rw-r--r--sysdeps/linux-gnu/s390/arch.h10
-rw-r--r--sysdeps/linux-gnu/s390/plt.c11
-rw-r--r--sysdeps/linux-gnu/s390/regs.c50
-rw-r--r--sysdeps/linux-gnu/s390/signalent.h3
-rw-r--r--sysdeps/linux-gnu/s390/signalent1.h1
-rw-r--r--sysdeps/linux-gnu/s390/syscallent.h282
-rw-r--r--sysdeps/linux-gnu/s390/syscallent1.h1
-rw-r--r--sysdeps/linux-gnu/s390/syscalls31.h287
-rw-r--r--sysdeps/linux-gnu/s390/syscalls64.h287
-rw-r--r--sysdeps/linux-gnu/s390/trace.c191
-rw-r--r--sysdeps/linux-gnu/sparc/arch.h4
-rw-r--r--sysdeps/linux-gnu/sparc/plt.c10
-rw-r--r--sysdeps/linux-gnu/sparc/regs.c24
-rw-r--r--sysdeps/linux-gnu/sparc/syscallent.h14
-rw-r--r--sysdeps/linux-gnu/sparc/trace.c36
-rw-r--r--sysdeps/linux-gnu/trace.c156
-rw-r--r--sysdeps/linux-gnu/x86_64/arch.h9
-rw-r--r--sysdeps/linux-gnu/x86_64/plt.c10
-rw-r--r--sysdeps/linux-gnu/x86_64/regs.c36
-rw-r--r--sysdeps/linux-gnu/x86_64/signalent1.h1
-rw-r--r--sysdeps/linux-gnu/x86_64/syscallent.h8
-rw-r--r--sysdeps/linux-gnu/x86_64/syscallent1.h1
-rw-r--r--sysdeps/linux-gnu/x86_64/trace.c120
52 files changed, 1418 insertions, 755 deletions
diff --git a/sysdeps/linux-gnu/Makefile b/sysdeps/linux-gnu/Makefile
index 7163709..6cbff83 100644
--- a/sysdeps/linux-gnu/Makefile
+++ b/sysdeps/linux-gnu/Makefile
@@ -1,20 +1,34 @@
-ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
+ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
+ -e s/arm.*/arm/ -e s/sa110/arm/ -e s/ppc64/ppc/ -e s/s390x/s390/)
CPPFLAGS += -I$(TOPDIR)/sysdeps/linux-gnu/$(ARCH)
OBJ = trace.o proc.o breakpoint.o
-all: sysdep.h signalent.h syscallent.h ../sysdep.o
+all: sysdep.h signalent.h syscallent.h signalent1.h syscallent1.h ../sysdep.o
sysdep.h: $(ARCH)/arch.h
cat $(ARCH)/arch.h > sysdep.h
signalent.h:
cp $(ARCH)/signalent.h signalent.h
+signalent1.h:
+ if [ -f $(ARCH)/signalent1.h ]; then \
+ cp $(ARCH)/signalent1.h signalent1.h; \
+ else \
+ > signalent1.h; \
+ fi
syscallent.h:
cp $(ARCH)/syscallent.h syscallent.h
+syscallent1.h:
+ if [ -f $(ARCH)/syscallent1.h ]; then \
+ cp $(ARCH)/syscallent1.h syscallent1.h; \
+ else \
+ > syscallent1.h; \
+ fi
+
../sysdep.o: os.o $(ARCH)/arch.o
$(CC) -nostdlib -r -o ../sysdep.o os.o $(ARCH)/arch.o
@@ -26,6 +40,7 @@ $(ARCH)/arch.o: dummy
clean:
$(MAKE) -C $(ARCH) clean
- rm -f $(OBJ) sysdep.h signalent.h syscallent.h os.o sysdep.o ../sysdep.o
+ rm -f $(OBJ) sysdep.h signalent.h signalent1.h syscallent.h
+ rm -f syscallent1.h os.o sysdep.o ../sysdep.o
dummy:
diff --git a/sysdeps/linux-gnu/alpha/arch.h b/sysdeps/linux-gnu/alpha/arch.h
index cdeeb52..930b6f1 100644
--- a/sysdeps/linux-gnu/alpha/arch.h
+++ b/sysdeps/linux-gnu/alpha/arch.h
@@ -4,4 +4,8 @@
#define LT_ELFCLASS ELFCLASS64
#define LT_ELF_MACHINE EM_ALPHA
+#define LT_ELFCLASS2 ELFCLASS64
#define LT_ELF_MACHINE2 EM_FAKE_ALPHA
+
+#define PLTs_INIT_BY_HERE NULL
+#define E_ENTRY_NAME "_start"
diff --git a/sysdeps/linux-gnu/alpha/plt.c b/sysdeps/linux-gnu/alpha/plt.c
index 32dfafb..16ec3d0 100644
--- a/sysdeps/linux-gnu/alpha/plt.c
+++ b/sysdeps/linux-gnu/alpha/plt.c
@@ -2,7 +2,13 @@
#include "ltrace.h"
#include "elf.h"
-GElf_Addr arch_plt_sym_val(struct ltelf * lte, size_t ndx, GElf_Rela * rela)
+GElf_Addr
+arch_plt_sym_val (struct ltelf *lte, size_t ndx, GElf_Rela *rela)
{
- return lte->plt_addr + ndx * 12 + 32;
+ return lte->plt_addr + ndx * 12 + 32;
+}
+
+void * plt2addr(struct process *proc, void ** plt)
+{
+ return (void *) plt;
}
diff --git a/sysdeps/linux-gnu/alpha/regs.c b/sysdeps/linux-gnu/alpha/regs.c
index fcba535..c59eee9 100644
--- a/sysdeps/linux-gnu/alpha/regs.c
+++ b/sysdeps/linux-gnu/alpha/regs.c
@@ -16,22 +16,22 @@
# define PTRACE_POKEUSER PTRACE_POKEUSR
#endif
-void *get_instruction_pointer(struct process *proc)
-{
- return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 64 /* REG_PC */ , 0);
+void *
+get_instruction_pointer(struct process * proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 64 /* REG_PC */, 0);
}
-void set_instruction_pointer(struct process *proc, void *addr)
-{
- ptrace(PTRACE_POKEUSER, proc->pid, 64 /* REG_PC */ , addr);
+void
+set_instruction_pointer(struct process * proc, void * addr) {
+ ptrace(PTRACE_POKEUSER, proc->pid, 64 /* REG_PC */, addr);
}
-void *get_stack_pointer(struct process *proc)
-{
- return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 30 /* REG_FP */ , 0);
+void *
+get_stack_pointer(struct process * proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 30 /* REG_FP */, 0);
}
-void *get_return_addr(struct process *proc, void *stack_pointer)
-{
- return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 26 /* RA */ , 0);
+void *
+get_return_addr(struct process * proc, void * stack_pointer) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 26 /* RA */, 0);
}
diff --git a/sysdeps/linux-gnu/alpha/trace.c b/sysdeps/linux-gnu/alpha/trace.c
index 3d35cf2..3d6237c 100644
--- a/sysdeps/linux-gnu/alpha/trace.c
+++ b/sysdeps/linux-gnu/alpha/trace.c
@@ -25,51 +25,45 @@ void get_arch_dep(struct process *proc)
/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
*/
-int syscall_p(struct process *proc, int status, int *sysnum)
-{
- if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) {
- char *ip = get_instruction_pointer(proc) - 4;
+int
+syscall_p(struct process * proc, int status, int * sysnum) {
+ if (WIFSTOPPED(status) && WSTOPSIG(status)==(SIGTRAP | proc->tracesysgood)) {
+ char *ip=get_instruction_pointer(proc) - 4;
long x = ptrace(PTRACE_PEEKTEXT, proc->pid, ip, 0);
debug(2, "instr: %016lx", x);
- if ((x & 0xffffffff) != 0x00000083)
+ if((x & 0xffffffff) != 0x00000083)
return 0;
- *sysnum =
- ptrace(PTRACE_PEEKUSER, proc->pid, 0 /* REG_R0 */ , 0);
- if (proc->callstack_depth > 0
- && proc->callstack[proc->callstack_depth - 1].is_syscall) {
+ *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 0 /* REG_R0 */, 0);
+ if (proc->callstack_depth > 0 && proc->callstack[proc->callstack_depth-1].is_syscall) {
return 2;
}
- if (*sysnum >= 0 && *sysnum < 500) {
+ if (*sysnum>=0 && *sysnum<500) {
return 1;
}
}
return 0;
}
-long gimme_arg(enum tof type, struct process *proc, int arg_num)
-{
- if (arg_num == -1) { /* return value */
- return ptrace(PTRACE_PEEKUSER, proc->pid, 0 /* REG_R0 */ , 0);
+long
+gimme_arg(enum tof type, struct process * proc, int arg_num) {
+ if (arg_num==-1) { /* return value */
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 0 /* REG_R0 */, 0);
}
- if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) {
- if (arg_num <= 5)
- return ptrace(PTRACE_PEEKUSER, proc->pid,
- arg_num + 16 /* REG_A0 */ , 0);
+ if (type==LT_TOF_FUNCTION || type==LT_TOF_FUNCTIONR) {
+ if(arg_num <= 5)
+ return ptrace(PTRACE_PEEKUSER, proc->pid, arg_num + 16 /* REG_A0 */, 0);
else
- return ptrace(PTRACE_PEEKTEXT, proc->pid,
- proc->stack_pointer + 8 * (arg_num - 6),
- 0);
- } else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) {
- return ptrace(PTRACE_PEEKUSER, proc->pid,
- arg_num + 16 /* REG_A0 */ , 0);
+ return ptrace(PTRACE_PEEKTEXT, proc->pid, proc->stack_pointer+8*(arg_num-6), 0);
+ } else if (type==LT_TOF_SYSCALL || type==LT_TOF_SYSCALLR) {
+ return ptrace(PTRACE_PEEKUSER, proc->pid, arg_num + 16 /* REG_A0 */, 0);
} else {
fprintf(stderr, "gimme_arg called with wrong arguments\n");
exit(1);
}
return 0;
}
-
-void save_register_args(enum tof type, struct process *proc)
+
+void save_register_args(enum tof type, struct process * proc)
{
}
diff --git a/sysdeps/linux-gnu/arm/arch.h b/sysdeps/linux-gnu/arm/arch.h
index e8a8b66..315238d 100644
--- a/sysdeps/linux-gnu/arm/arch.h
+++ b/sysdeps/linux-gnu/arm/arch.h
@@ -4,3 +4,6 @@
#define LT_ELFCLASS ELFCLASS32
#define LT_ELF_MACHINE EM_ARM
+
+#define PLTs_INIT_BY_HERE NULL
+#define E_ENTRY_NAME "_start"
diff --git a/sysdeps/linux-gnu/arm/plt.c b/sysdeps/linux-gnu/arm/plt.c
index 1dae91f..51463c5 100644
--- a/sysdeps/linux-gnu/arm/plt.c
+++ b/sysdeps/linux-gnu/arm/plt.c
@@ -2,7 +2,13 @@
#include "ltrace.h"
#include "elf.h"
-GElf_Addr arch_plt_sym_val(struct ltelf * lte, size_t ndx, GElf_Rela * rela)
+GElf_Addr
+arch_plt_sym_val (struct ltelf *lte, size_t ndx, GElf_Rela *rela)
{
- return lte->plt_addr + 20 + ndx * 12;
+ return lte->plt_addr + 20 + ndx * 12;
+}
+
+void * plt2addr(struct process *proc, void ** plt)
+{
+ return (void *) plt;
}
diff --git a/sysdeps/linux-gnu/arm/regs.c b/sysdeps/linux-gnu/arm/regs.c
index 819754f..70ead10 100644
--- a/sysdeps/linux-gnu/arm/regs.c
+++ b/sysdeps/linux-gnu/arm/regs.c
@@ -20,24 +20,24 @@
#define off_lr 56
#define off_sp 52
-void *get_instruction_pointer(struct process *proc)
-{
+void *
+get_instruction_pointer(struct process * proc) {
return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0);
}
-void set_instruction_pointer(struct process *proc, void *addr)
-{
+void
+set_instruction_pointer(struct process * proc, void * addr) {
ptrace(PTRACE_POKEUSER, proc->pid, off_pc, addr);
}
-void *get_stack_pointer(struct process *proc)
-{
+void *
+get_stack_pointer(struct process * proc) {
return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_sp, 0);
}
/* really, this is given the *stack_pointer expecting
* a CISC architecture; in our case, we don't need that */
-void *get_return_addr(struct process *proc, void *stack_pointer)
-{
+void *
+get_return_addr(struct process * proc, void * stack_pointer) {
return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_lr, 0);
}
diff --git a/sysdeps/linux-gnu/arm/trace.c b/sysdeps/linux-gnu/arm/trace.c
index 0d68ae0..485f0ad 100644
--- a/sysdeps/linux-gnu/arm/trace.c
+++ b/sysdeps/linux-gnu/arm/trace.c
@@ -26,54 +26,47 @@
#define off_ip 48
#define off_pc 60
-void get_arch_dep(struct process *proc)
-{
+void
+get_arch_dep(struct process * proc) {
}
/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
*/
-int syscall_p(struct process *proc, int status, int *sysnum)
-{
- if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) {
+int
+syscall_p(struct process * proc, int status, int * sysnum) {
+ if (WIFSTOPPED(status) && WSTOPSIG(status)==(SIGTRAP | proc->tracesysgood)) {
/* get the user's pc (plus 8) */
int pc = ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0);
/* fetch the SWI instruction */
- int insn = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 4, 0);
-
+ int insn = ptrace(PTRACE_PEEKTEXT, proc->pid, pc-4, 0) ;
+
*sysnum = insn & 0xFFFF;
/* if it is a syscall, return 1 or 2 */
if ((insn & 0xFFFF0000) == 0xef900000) {
- return ptrace(PTRACE_PEEKUSER, proc->pid, off_ip,
- 0) ? 2 : 1;
+ return ptrace(PTRACE_PEEKUSER, proc->pid, off_ip, 0) ? 2 : 1;
}
}
return 0;
}
-
-long gimme_arg(enum tof type, struct process *proc, int arg_num)
-{
- if (arg_num == -1) { /* return value */
+
+long
+gimme_arg(enum tof type, struct process * proc, int arg_num) {
+ if (arg_num==-1) { /* return value */
return ptrace(PTRACE_PEEKUSER, proc->pid, off_r0, 0);
}
/* deal with the ARM calling conventions */
- if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) {
- if (arg_num < 4) {
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num,
- 0);
+ if (type==LT_TOF_FUNCTION || type==LT_TOF_FUNCTIONR) {
+ if (arg_num<4) {
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4*arg_num, 0);
} else {
- return ptrace(PTRACE_PEEKDATA, proc->pid,
- proc->stack_pointer + 4 * (arg_num - 4),
- 0);
+ return ptrace(PTRACE_PEEKDATA, proc->pid, proc->stack_pointer+4*(arg_num-4), 0);
}
- } else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) {
- if (arg_num < 5) {
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num,
- 0);
+ } else if (type==LT_TOF_SYSCALL || type==LT_TOF_SYSCALLR) {
+ if (arg_num<5) {
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4*arg_num, 0);
} else {
- return ptrace(PTRACE_PEEKDATA, proc->pid,
- proc->stack_pointer + 4 * (arg_num - 5),
- 0);
+ return ptrace(PTRACE_PEEKDATA, proc->pid, proc->stack_pointer+4*(arg_num-5), 0);
}
} else {
fprintf(stderr, "gimme_arg called with wrong arguments\n");
@@ -83,6 +76,6 @@ long gimme_arg(enum tof type, struct process *proc, int arg_num)
return 0;
}
-void save_register_args(enum tof type, struct process *proc)
-{
+void
+save_register_args(enum tof type, struct process * proc) {
}
diff --git a/sysdeps/linux-gnu/breakpoint.c b/sysdeps/linux-gnu/breakpoint.c
index fe6ac69..712f1a5 100644
--- a/sysdeps/linux-gnu/breakpoint.c
+++ b/sysdeps/linux-gnu/breakpoint.c
@@ -7,6 +7,7 @@
#include "arch.h"
#include "options.h"
#include "output.h"
+#include "debug.h"
static unsigned char break_insn[] = BREAKPOINT_VALUE;
@@ -14,30 +15,24 @@ static unsigned char break_insn[] = BREAKPOINT_VALUE;
extern void arch_enable_breakpoint(pid_t, struct breakpoint*);
void enable_breakpoint(pid_t pid, struct breakpoint *sbp)
{
- arch_enable_breakpoint(pid, sbp);
+ arch_enable_breakpoint(pid, sbp);
}
#else
-void enable_breakpoint(pid_t pid, struct breakpoint *sbp)
-{
- int i, j;
+void
+enable_breakpoint(pid_t pid, struct breakpoint * sbp) {
+ int i,j;
- if (opt_d > 1) {
- output_line(0, "enable_breakpoint(%d,%p)", pid, sbp->addr);
- }
+ debug(1, "enable_breakpoint(%d,%p)", pid, sbp->addr);
- for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
- long a =
- ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
- 0);
- for (j = 0;
- j < sizeof(long)
- && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
- unsigned char *bytes = (unsigned char *)&a;
+ for(i=0; i < 1+((BREAKPOINT_LENGTH-1)/sizeof(long)); i++) {
+ long a = ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i*sizeof(long), 0);
+ for(j=0; j<sizeof(long) && i*sizeof(long)+j < BREAKPOINT_LENGTH; j++) {
+ unsigned char * bytes = (unsigned char *)&a;
- sbp->orig_value[i * sizeof(long) + j] = bytes[+j];
- bytes[j] = break_insn[i * sizeof(long) + j];
+ sbp->orig_value[i*sizeof(long)+j] = bytes[+j];
+ bytes[j] = break_insn[i*sizeof(long)+j];
}
- ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
+ ptrace(PTRACE_POKETEXT, pid, sbp->addr + i*sizeof(long), a);
}
}
#endif /* ARCH_HAVE_ENABLE_BREAKPOINT */
@@ -49,26 +44,22 @@ disable_breakpoint(pid_t pid, const struct breakpoint * sbp) {
arch_disable_breakpoint(pid, sbp);
}
#else
-void disable_breakpoint(pid_t pid, const struct breakpoint *sbp)
-{
- int i, j;
+void
+disable_breakpoint(pid_t pid, const struct breakpoint * sbp) {
+ int i,j;
- if (opt_d > 1) {
+ if (opt_d>1) {
output_line(0, "disable_breakpoint(%d,%p)", pid, sbp->addr);
}
- for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
- long a =
- ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
- 0);
- for (j = 0;
- j < sizeof(long)
- && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
- unsigned char *bytes = (unsigned char *)&a;
+ for(i=0; i < 1+((BREAKPOINT_LENGTH-1)/sizeof(long)); i++) {
+ long a = ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i*sizeof(long), 0);
+ for(j=0; j<sizeof(long) && i*sizeof(long)+j < BREAKPOINT_LENGTH; j++) {
+ unsigned char * bytes = (unsigned char *)&a;
- bytes[j] = sbp->orig_value[i * sizeof(long) + j];
+ bytes[j] = sbp->orig_value[i*sizeof(long)+j];
}
- ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
+ ptrace(PTRACE_POKETEXT, pid, sbp->addr + i*sizeof(long), a);
}
}
#endif /* ARCH_HAVE_DISABLE_BREAKPOINT */
diff --git a/sysdeps/linux-gnu/i386/arch.h b/sysdeps/linux-gnu/i386/arch.h
index dc7383f..c624a8a 100644
--- a/sysdeps/linux-gnu/i386/arch.h
+++ b/sysdeps/linux-gnu/i386/arch.h
@@ -4,3 +4,6 @@
#define LT_ELFCLASS ELFCLASS32
#define LT_ELF_MACHINE EM_386
+
+#define PLTs_INIT_BY_HERE NULL
+#define E_ENTRY_NAME "_start"
diff --git a/sysdeps/linux-gnu/i386/plt.c b/sysdeps/linux-gnu/i386/plt.c
index 939bc4e..36d0ecd 100644
--- a/sysdeps/linux-gnu/i386/plt.c
+++ b/sysdeps/linux-gnu/i386/plt.c
@@ -2,7 +2,13 @@
#include "ltrace.h"
#include "elf.h"
-GElf_Addr arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela)
+GElf_Addr
+arch_plt_sym_val (struct ltelf *lte, size_t ndx, GElf_Rela *rela)
{
- return lte->plt_addr + (ndx + 1) * 16;
+ return lte->plt_addr + (ndx + 1) * 16;
+}
+
+void * plt2addr(struct process *proc, void ** plt)
+{
+ return (void *) plt;
}
diff --git a/sysdeps/linux-gnu/i386/regs.c b/sysdeps/linux-gnu/i386/regs.c
index 158fa24..75268e9 100644
--- a/sysdeps/linux-gnu/i386/regs.c
+++ b/sysdeps/linux-gnu/i386/regs.c
@@ -16,22 +16,22 @@
# define PTRACE_POKEUSER PTRACE_POKEUSR
#endif
-void *get_instruction_pointer(struct process *proc)
-{
- return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * EIP, 0);
+void *
+get_instruction_pointer(struct process * proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4*EIP, 0);
}
-void set_instruction_pointer(struct process *proc, void *addr)
-{
- ptrace(PTRACE_POKEUSER, proc->pid, 4 * EIP, (long)addr);
+void
+set_instruction_pointer(struct process * proc, void * addr) {
+ ptrace(PTRACE_POKEUSER, proc->pid, 4*EIP, (long)addr);
}
-void *get_stack_pointer(struct process *proc)
-{
- return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * UESP, 0);
+void *
+get_stack_pointer(struct process * proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4*UESP, 0);
}
-void *get_return_addr(struct process *proc, void *stack_pointer)
-{
+void *
+get_return_addr(struct process * proc, void * stack_pointer) {
return (void *)ptrace(PTRACE_PEEKTEXT, proc->pid, stack_pointer, 0);
}
diff --git a/sysdeps/linux-gnu/i386/syscallent.h b/sysdeps/linux-gnu/i386/syscallent.h
index b6eb2a8..c4bdae5 100644
--- a/sysdeps/linux-gnu/i386/syscallent.h
+++ b/sysdeps/linux-gnu/i386/syscallent.h
@@ -283,3 +283,12 @@
"mq_getsetattr", /* 282 */
"kexec_load", /* 283 */
"waitid", /* 284 */
+ "285", /* 285 */
+ "add_key", /* 286 */
+ "request_key", /* 287 */
+ "keyctl", /* 288 */
+ "ioprio_set", /* 289 */
+ "ioprio_get", /* 290 */
+ "inotify_init", /* 291 */
+ "inotify_add_watch", /* 292 */
+ "inotify_rm_watch", /* 293 */
diff --git a/sysdeps/linux-gnu/i386/trace.c b/sysdeps/linux-gnu/i386/trace.c
index fe9d8a4..b8eff3d 100644
--- a/sysdeps/linux-gnu/i386/trace.c
+++ b/sysdeps/linux-gnu/i386/trace.c
@@ -19,58 +19,51 @@
# define PTRACE_POKEUSER PTRACE_POKEUSR
#endif
-void get_arch_dep(struct process *proc)
-{
+void
+get_arch_dep(struct process * proc) {
}
/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
*/
-int syscall_p(struct process *proc, int status, int *sysnum)
-{
- if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) {
- *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 4 * ORIG_EAX, 0);
+int
+syscall_p(struct process * proc, int status, int * sysnum) {
+ if (WIFSTOPPED(status) && WSTOPSIG(status)==(SIGTRAP | proc->tracesysgood)) {
+ *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 4*ORIG_EAX, 0);
if (proc->callstack_depth > 0 &&
- proc->callstack[proc->callstack_depth - 1].is_syscall) {
+ proc->callstack[proc->callstack_depth-1].is_syscall) {
return 2;
}
- if (*sysnum >= 0) {
+ if (*sysnum>=0) {
return 1;
}
}
return 0;
}
-long gimme_arg(enum tof type, struct process *proc, int arg_num)
-{
- if (arg_num == -1) { /* return value */
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * EAX, 0);
+long
+gimme_arg(enum tof type, struct process * proc, int arg_num) {
+ if (arg_num==-1) { /* return value */
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EAX, 0);
}
- if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) {
- return ptrace(PTRACE_PEEKTEXT, proc->pid,
- proc->stack_pointer + 4 * (arg_num + 1), 0);
- } else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) {
+ if (type==LT_TOF_FUNCTION || type==LT_TOF_FUNCTIONR) {
+ return ptrace(PTRACE_PEEKTEXT, proc->pid, proc->stack_pointer+4*(arg_num+1), 0);
+ } else if (type==LT_TOF_SYSCALL || type==LT_TOF_SYSCALLR) {
#if 0
- switch (arg_num) {
- case 0:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * EBX, 0);
- case 1:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * ECX, 0);
- case 2:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * EDX, 0);
- case 3:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * ESI, 0);
- case 4:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * EDI, 0);
- default:
- fprintf(stderr,
- "gimme_arg called with wrong arguments\n");
- exit(2);
+ switch(arg_num) {
+ case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EBX, 0);
+ case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*ECX, 0);
+ case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EDX, 0);
+ case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*ESI, 0);
+ case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EDI, 0);
+ default:
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ exit(2);
}
#else
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num, 0);
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4*arg_num, 0);
#endif
} else {
fprintf(stderr, "gimme_arg called with wrong arguments\n");
@@ -80,6 +73,6 @@ long gimme_arg(enum tof type, struct process *proc, int arg_num)
return 0;
}
-void save_register_args(enum tof type, struct process *proc)
-{
+void
+save_register_args(enum tof type, struct process * proc) {
}
diff --git a/sysdeps/linux-gnu/ia64/arch.h b/sysdeps/linux-gnu/ia64/arch.h
index b5f141f..6efef3d 100644
--- a/sysdeps/linux-gnu/ia64/arch.h
+++ b/sysdeps/linux-gnu/ia64/arch.h
@@ -1,10 +1,12 @@
#define ARCH_HAVE_DISABLE_BREAKPOINT 1
#define ARCH_HAVE_ENABLE_BREAKPOINT 1
-
#define BREAKPOINT_LENGTH 16
#define BREAKPOINT_VALUE {0}
#define DECR_PC_AFTER_BREAK 0
#define LT_ELFCLASS ELFCLASS64
#define LT_ELF_MACHINE EM_IA_64
+
+#define PLTs_INIT_BY_HERE NULL
+#define E_ENTRY_NAME "_start"
diff --git a/sysdeps/linux-gnu/ia64/plt.c b/sysdeps/linux-gnu/ia64/plt.c
index 05a1a24..b4ee017 100644
--- a/sysdeps/linux-gnu/ia64/plt.c
+++ b/sysdeps/linux-gnu/ia64/plt.c
@@ -40,3 +40,8 @@ arch_plt_sym_val (struct ltelf *lte, size_t ndx, GElf_Rela *rela)
return addr;
}
+
+void * plt2addr(struct process *proc, void ** plt)
+{
+ return (void *) plt;
+}
diff --git a/sysdeps/linux-gnu/ia64/syscallent.h b/sysdeps/linux-gnu/ia64/syscallent.h
index 1a5b505..88545d4 100644
--- a/sysdeps/linux-gnu/ia64/syscallent.h
+++ b/sysdeps/linux-gnu/ia64/syscallent.h
@@ -1257,3 +1257,24 @@
"clock_nanosleep", /* 1256 */
"fstatfs64", /* 1257 */
"statfs64", /* 1258 */
+ "mbind", /* 1259 */
+ "get_mempolicy", /* 1260 */
+ "set_mempolicy", /* 1261 */
+ "mq_open", /* 1262 */
+ "mq_unlink", /* 1263 */
+ "mq_timedsend", /* 1264 */
+ "mq_timedreceive", /* 1265 */
+ "mq_notify", /* 1266 */
+ "mq_getsetattr", /* 1267 */
+ "kexec_load", /* 1268 */
+ "vserver", /* 1269 */
+ "waitid", /* 1270 */
+ "add_key", /* 1271 */
+ "request_key", /* 1272 */
+ "keyctl", /* 1273 */
+ "ioprio_set", /* 1274 */
+ "ioprio_get", /* 1275 */
+ "set_zone_reclaim", /* 1276 */
+ "inotify_init", /* 1277 */
+ "inotify_add_watch", /* 1278 */
+ "inotify_rm_watch", /* 1279 */
diff --git a/sysdeps/linux-gnu/ia64/trace.c b/sysdeps/linux-gnu/ia64/trace.c
index 46e8771..7fa6c1e 100644
--- a/sysdeps/linux-gnu/ia64/trace.c
+++ b/sysdeps/linux-gnu/ia64/trace.c
@@ -37,8 +37,7 @@ union bundle_t {
int
syscall_p(struct process * proc, int status, int * sysnum) {
- if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP)
- {
+ if (WIFSTOPPED(status) && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
unsigned long slot = (ptrace (PTRACE_PEEKUSER, proc->pid, PT_CR_IPSR, 0) >> 41) & 0x3;
unsigned long ip = ptrace(PTRACE_PEEKUSER, proc->pid, PT_CR_IIP, 0);
diff --git a/sysdeps/linux-gnu/m68k/arch.h b/sysdeps/linux-gnu/m68k/arch.h
index 1790d09..438545f 100644
--- a/sysdeps/linux-gnu/m68k/arch.h
+++ b/sysdeps/linux-gnu/m68k/arch.h
@@ -4,3 +4,6 @@
#define LT_ELFCLASS ELFCLASS32
#define LT_ELF_MACHINE EM_68K
+
+#define PLTs_INIT_BY_HERE NULL
+#define E_ENTRY_NAME "_start"
diff --git a/sysdeps/linux-gnu/m68k/plt.c b/sysdeps/linux-gnu/m68k/plt.c
index 09168e9..54cc920 100644
--- a/sysdeps/linux-gnu/m68k/plt.c
+++ b/sysdeps/linux-gnu/m68k/plt.c
@@ -2,8 +2,14 @@
#include "ltrace.h"
#include "elf.h"
-GElf_Addr arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela)
+GElf_Addr
+arch_plt_sym_val (struct ltelf *lte, size_t ndx, GElf_Rela *rela)
{
- return lte->plt_addr + (ndx + 1)
- * ((lte->ehdr.e_flags & EF_CPU32) ? 24 : 12);
+ return lte->plt_addr + (ndx + 1)
+ * ((lte->ehdr.e_flags & EF_CPU32) ? 24 : 12);
+}
+
+void * plt2addr(struct process *proc, void ** plt)
+{
+ return (void *) plt;
}
diff --git a/sysdeps/linux-gnu/m68k/regs.c b/sysdeps/linux-gnu/m68k/regs.c
index d953d28..187cef5 100644
--- a/sysdeps/linux-gnu/m68k/regs.c
+++ b/sysdeps/linux-gnu/m68k/regs.c
@@ -16,22 +16,22 @@
# define PTRACE_POKEUSER PTRACE_POKEUSR
#endif
-void *get_instruction_pointer(struct process *proc)
-{
- return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_PC, 0);
+void *
+get_instruction_pointer(struct process * proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4*PT_PC, 0);
}
-void set_instruction_pointer(struct process *proc, void *addr)
-{
- ptrace(PTRACE_POKEUSER, proc->pid, 4 * PT_PC, addr);
+void
+set_instruction_pointer(struct process * proc, void * addr) {
+ ptrace(PTRACE_POKEUSER, proc->pid, 4*PT_PC, addr);
}
-void *get_stack_pointer(struct process *proc)
-{
- return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_USP, 0);
+void *
+get_stack_pointer(struct process * proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4*PT_USP, 0);
}
-void *get_return_addr(struct process *proc, void *stack_pointer)
-{
+void *
+get_return_addr(struct process * proc, void * stack_pointer) {
return (void *)ptrace(PTRACE_PEEKTEXT, proc->pid, stack_pointer, 0);
}
diff --git a/sysdeps/linux-gnu/m68k/trace.c b/sysdeps/linux-gnu/m68k/trace.c
index b4e1b88..fac5fbe 100644
--- a/sysdeps/linux-gnu/m68k/trace.c
+++ b/sysdeps/linux-gnu/m68k/trace.c
@@ -18,26 +18,24 @@
# define PTRACE_POKEUSER PTRACE_POKEUSR
#endif
-void get_arch_dep(struct process *proc)
-{
+void
+get_arch_dep(struct process * proc) {
}
/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
*/
-int syscall_p(struct process *proc, int status, int *sysnum)
-{
+int
+syscall_p(struct process * proc, int status, int * sysnum) {
int depth;
- if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) {
- *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_ORIG_D0, 0);
- if (*sysnum == -1)
- return 0;
- if (*sysnum >= 0) {
+ if (WIFSTOPPED(status) && WSTOPSIG(status)==(SIGTRAP | proc->tracesysgood)) {
+ *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 4*PT_ORIG_D0, 0);
+ if (*sysnum == -1) return 0;
+ if (*sysnum>=0) {
depth = proc->callstack_depth;
- if (depth > 0 &&
- proc->callstack[depth - 1].is_syscall &&
- proc->callstack[depth - 1].c_un.syscall ==
- *sysnum) {
+ if (depth>0 &&
+ proc->callstack[depth-1].is_syscall &&
+ proc->callstack[depth-1].c_un.syscall==*sysnum) {
return 2;
} else {
return 1;
@@ -47,36 +45,29 @@ int syscall_p(struct process *proc, int status, int *sysnum)
return 0;
}
-long gimme_arg(enum tof type, struct process *proc, int arg_num)
-{
- if (arg_num == -1) { /* return value */
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_D0, 0);
+long
+gimme_arg(enum tof type, struct process * proc, int arg_num) {
+ if (arg_num==-1) { /* return value */
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4*PT_D0, 0);
}
- if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) {
- return ptrace(PTRACE_PEEKTEXT, proc->pid,
- proc->stack_pointer + 4 * (arg_num + 1), 0);
- } else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) {
+ if (type==LT_TOF_FUNCTION || type==LT_TOF_FUNCTIONR) {
+ return ptrace(PTRACE_PEEKTEXT, proc->pid, proc->stack_pointer+4*(arg_num+1), 0);
+ } else if (type==LT_TOF_SYSCALL || type==LT_TOF_SYSCALLR) {
#if 0
- switch (arg_num) {
- case 0:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_D1, 0);
- case 1:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_D2, 0);
- case 2:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_D3, 0);
- case 3:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_D4, 0);
- case 4:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_D5, 0);
- default:
- fprintf(stderr,
- "gimme_arg called with wrong arguments\n");
- exit(2);
+ switch(arg_num) {
+ case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*PT_D1, 0);
+ case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*PT_D2, 0);
+ case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*PT_D3, 0);
+ case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*PT_D4, 0);
+ case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*PT_D5, 0);
+ default:
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ exit(2);
}
#else
/* That hack works on m68k, too */
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num, 0);
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 4*arg_num, 0);
#endif
} else {
fprintf(stderr, "gimme_arg called with wrong arguments\n");
@@ -86,6 +77,6 @@ long gimme_arg(enum tof type, struct process *proc, int arg_num)
return 0;
}
-void save_register_args(enum tof type, struct process *proc)
-{
+void
+save_register_args(enum tof type, struct process * proc) {
}
diff --git a/sysdeps/linux-gnu/ppc/arch.h b/sysdeps/linux-gnu/ppc/arch.h
index e04e885..37634bf 100644
--- a/sysdeps/linux-gnu/ppc/arch.h
+++ b/sysdeps/linux-gnu/ppc/arch.h
@@ -1,6 +1,18 @@
#define BREAKPOINT_VALUE { 0x7f, 0xe0, 0x00, 0x08 }
#define BREAKPOINT_LENGTH 4
#define DECR_PC_AFTER_BREAK 0
+#define E_ENTRY_NAME "_start"
#define LT_ELFCLASS ELFCLASS32
#define LT_ELF_MACHINE EM_PPC
+#ifdef __powerpc64__
+#define LT_ELFCLASS2 ELFCLASS64
+#define LT_ELF_MACHINE2 EM_PPC64
+
+#define PLTs_INIT_BY_HERE E_ENTRY_NAME
+
+#else
+
+#define PLTs_INIT_BY_HERE NULL
+
+#endif
diff --git a/sysdeps/linux-gnu/ppc/plt.c b/sysdeps/linux-gnu/ppc/plt.c
index 19991b5..c85ea92 100644
--- a/sysdeps/linux-gnu/ppc/plt.c
+++ b/sysdeps/linux-gnu/ppc/plt.c
@@ -1,8 +1,42 @@
#include <gelf.h>
#include "ltrace.h"
#include "elf.h"
+#include "debug.h"
+#include "ptrace.h"
+#include "options.h"
-GElf_Addr arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela)
+GElf_Addr
+arch_plt_sym_val (struct ltelf *lte, size_t ndx, GElf_Rela *rela)
{
- return rela->r_offset;
+ return rela->r_offset;
}
+
+void * plt2addr(struct process *proc, void ** plt)
+{
+ long addr;
+
+ debug(3, 0);
+
+ if (proc->e_machine == EM_PPC || plt == 0)
+ return (void *)plt;
+
+ if (proc->pid == 0)
+ return (void *)0;
+
+ // On a PowerPC-64 system, a plt is three 64-bit words: the first is the
+ // 64-bit address of the routine. Before the PLT has been initialized, this
+ // will be 0x0. In fact, the symbol table won't have the plt's address even.
+ // Ater the PLT has been initialized, but before it has been resolved, the
+ // first word will be the address of the function in the dynamic linker that
+ // will reslove the PLT. After the PLT is resolved, this will will be the
+ // address of the routine whose symbol is in the symbol table.
+
+ addr = ptrace(PTRACE_PEEKTEXT, proc->pid, plt);
+
+ if (opt_d >= 3) {
+ xinfdump(proc->pid, plt, sizeof(void*)*3);
+ }
+
+ return (void *)addr;
+}
+
diff --git a/sysdeps/linux-gnu/ppc/regs.c b/sysdeps/linux-gnu/ppc/regs.c
index d0d51e3..a14e8d6 100644
--- a/sysdeps/linux-gnu/ppc/regs.c
+++ b/sysdeps/linux-gnu/ppc/regs.c
@@ -16,22 +16,22 @@
# define PTRACE_POKEUSER PTRACE_POKEUSR
#endif
-void *get_instruction_pointer(struct process *proc)
-{
- return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_NIP, 0);
+void *
+get_instruction_pointer(struct process * proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long)*PT_NIP, 0);
}
-void set_instruction_pointer(struct process *proc, void *addr)
-{
- ptrace(PTRACE_POKEUSER, proc->pid, 4 * PT_NIP, addr);
+void
+set_instruction_pointer(struct process * proc, void * addr) {
+ ptrace(PTRACE_POKEUSER, proc->pid, sizeof(long)*PT_NIP, addr);
}
-void *get_stack_pointer(struct process *proc)
-{
- return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_R1, 0);
+void *
+get_stack_pointer(struct process * proc) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long)*PT_R1, 0);
}
-void *get_return_addr(struct process *proc, void *stack_pointer)
-{
- return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_LNK, 0);
+void *
+get_return_addr(struct process * proc, void * stack_pointer) {
+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long)*PT_LNK, 0);
}
diff --git a/sysdeps/linux-gnu/ppc/syscallent.h b/sysdeps/linux-gnu/ppc/syscallent.h
index 2bbba38..205fc4a 100644
--- a/sysdeps/linux-gnu/ppc/syscallent.h
+++ b/sysdeps/linux-gnu/ppc/syscallent.h
@@ -261,3 +261,12 @@
"mq_notify", /* 266 */
"mq_getsetattr", /* 267 */
"kexec_load", /* 268 */
+ "add_key", /* 269 */
+ "request_key", /* 270 */
+ "keyctl", /* 271 */
+ "waitid", /* 272 */
+ "ioprio_set", /* 273 */
+ "ioprio_get", /* 274 */
+ "inotify_init", /* 275 */
+ "inotify_add_watch", /* 276 */
+ "inotify_rm_watch", /* 277 */
diff --git a/sysdeps/linux-gnu/ppc/trace.c b/sysdeps/linux-gnu/ppc/trace.c
index 6670be1..f31fb35 100644
--- a/sysdeps/linux-gnu/ppc/trace.c
+++ b/sysdeps/linux-gnu/ppc/trace.c
@@ -7,6 +7,7 @@
#include <signal.h>
#include <sys/ptrace.h>
#include <asm/ptrace.h>
+#include <elf.h>
#include "ltrace.h"
@@ -20,23 +21,28 @@
void get_arch_dep(struct process *proc)
{
+#ifdef __powerpc64__
+ if (proc->arch_ptr)
+ return;
+ proc->mask_32bit = (proc->e_machine == EM_PPC);
+ proc->arch_ptr = (void *) 1;
+#endif
}
+
/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
*/
#define SYSCALL_INSN 0x44000002
-int syscall_p(struct process *proc, int status, int *sysnum)
-{
- if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) {
- int pc = ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_NIP, 0);
- int insn = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 4, 0);
+int
+syscall_p(struct process * proc, int status, int * sysnum) {
+ if (WIFSTOPPED(status) && WSTOPSIG(status)==(SIGTRAP | proc->tracesysgood)) {
+ long pc = (long)get_instruction_pointer(proc);
+ int insn = (int)ptrace(PTRACE_PEEKTEXT, proc->pid, pc-sizeof(long), 0);
if (insn == SYSCALL_INSN) {
- *sysnum =
- ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_R0, 0);
- if (proc->callstack_depth > 0
- && proc->callstack[proc->callstack_depth -
- 1].is_syscall) {
+ *sysnum = (int)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long)*PT_R0, 0);
+ if (proc->callstack_depth > 0 &&
+ proc->callstack[proc->callstack_depth-1].is_syscall) {
return 2;
}
return 1;
@@ -45,20 +51,18 @@ int syscall_p(struct process *proc, int status, int *sysnum)
return 0;
}
-long gimme_arg(enum tof type, struct process *proc, int arg_num)
-{
- if (arg_num == -1) { /* return value */
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_R3, 0);
+long
+gimme_arg(enum tof type, struct process * proc, int arg_num) {
+ if (arg_num==-1) { /* return value */
+ return ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long)*PT_R3, 0);
} else if (arg_num < 8) {
- return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * (arg_num + PT_R3),
- 0);
+ return ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long)*(arg_num+PT_R3), 0);
} else {
- return ptrace(PTRACE_PEEKDATA, proc->pid,
- proc->stack_pointer + 8 * (arg_num - 8), 0);
+ return ptrace(PTRACE_PEEKDATA, proc->pid, proc->stack_pointer+8*(arg_num-8), 0);
}
return 0;
}
-void save_register_args(enum tof type, struct process *proc)
-{
+void
+save_register_args(enum tof type, struct process * proc) {
}
diff --git a/sysdeps/linux-gnu/proc.c b/sysdeps/linux-gnu/proc.c
index 201fb6d..a5c18f6 100644
--- a/sysdeps/linux-gnu/proc.c
+++ b/sysdeps/linux-gnu/proc.c
@@ -13,21 +13,21 @@
* have a bit delay
*/
-#define MAX_DELAY 100000 /* 100000 microseconds = 0.1 seconds */
+#define MAX_DELAY 100000 /* 100000 microseconds = 0.1 seconds */
/*
* Returns a file name corresponding to a running pid
*/
-char *pid2name(pid_t pid)
-{
+char *
+pid2name(pid_t pid) {
char proc_exe[1024];
if (!kill(pid, 0)) {
- int delay = 0;
+ int delay=0;
sprintf(proc_exe, "/proc/%d/exe", pid);
- while (delay < MAX_DELAY) {
+ while(delay<MAX_DELAY) {
if (!access(proc_exe, F_OK)) {
return strdup(proc_exe);
}
diff --git a/sysdeps/linux-gnu/s390/arch.h b/sysdeps/linux-gnu/s390/arch.h
index bb61ca7..18a1c89 100644
--- a/sysdeps/linux-gnu/s390/arch.h
+++ b/sysdeps/linux-gnu/s390/arch.h
@@ -7,5 +7,15 @@
#define BREAKPOINT_LENGTH 2
#define DECR_PC_AFTER_BREAK 2
+#ifdef __s390x__
+#define LT_ELFCLASS ELFCLASS64
+#define LT_ELF_MACHINE EM_S390
+#define LT_ELFCLASS2 ELFCLASS32
+#define LT_ELF_MACHINE2 EM_S390
+#else
#define LT_ELFCLASS ELFCLASS32
#define LT_ELF_MACHINE EM_S390
+#endif
+
+#define PLTs_INIT_BY_HERE NULL
+#define E_ENTRY_NAME "_start"
diff --git a/sysdeps/linux-gnu/s390/plt.c b/sysdeps/linux-gnu/s390/plt.c
index deb612e..99c524d 100644
--- a/sysdeps/linux-gnu/s390/plt.c
+++ b/sysdeps/linux-gnu/s390/plt.c
@@ -2,7 +2,14 @@
#include "ltrace.h"
#include "elf.h"
-GElf_Addr arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela)
+GElf_Addr
+arch_plt_sym_val (struct ltelf *lte, size_t ndx, GElf_Rela *rela)
{
- return lte->plt_addr + (ndx + 1) * 32;
+ return lte->plt_addr + (ndx + 1) * 32;
+}
+
+
+void * plt2addr(struct process *proc, void ** plt)
+{
+ return (void *) plt;
}
diff --git a/sysdeps/linux-gnu/s390/regs.c b/sysdeps/linux-gnu/s390/regs.c
index efba7f8..3f14115 100644
--- a/sysdeps/linux-gnu/s390/regs.c
+++ b/sysdeps/linux-gnu/s390/regs.c
@@ -21,24 +21,48 @@
# define PTRACE_POKEUSER PTRACE_POKEUSR
#endif
-void *get_instruction_pointer(struct process *proc)
-{
- return (void *)(ptrace(PTRACE_PEEKUSER, proc->pid, PT_PSWADDR, 0) &
- 0x7fffffff);
+#ifdef __s390x__
+#define PSW_MASK 0xffffffffffffffff
+#define PSW_MASK31 0x7fffffff
+#else
+#define PSW_MASK 0x7fffffff
+#endif
+
+void *
+get_instruction_pointer(struct process * proc) {
+ long ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_PSWADDR, 0) & PSW_MASK;
+#ifdef __s390x__
+ if (proc->mask_32bit)
+ ret &= PSW_MASK31;
+#endif
+ return (void *) ret;
}
-void set_instruction_pointer(struct process *proc, void *addr)
-{
+void
+set_instruction_pointer(struct process * proc, void * addr) {
+#ifdef __s390x__
+ if (proc->mask_32bit)
+ addr = (void *) ((long) addr & PSW_MASK31);
+#endif
ptrace(PTRACE_POKEUSER, proc->pid, PT_PSWADDR, addr);
}
-void *get_stack_pointer(struct process *proc)
-{
- return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR15, 0);
+void *
+get_stack_pointer(struct process * proc) {
+ long ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR15, 0) & PSW_MASK;
+#ifdef __s390x__
+ if (proc->mask_32bit)
+ ret &= PSW_MASK31;
+#endif
+ return (void *) ret;
}
-void *get_return_addr(struct process *proc, void *stack_pointer)
-{
- return (void *)(ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR14, 0) &
- 0x7fffffff);
+void *
+get_return_addr(struct process * proc, void * stack_pointer) {
+ long ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR14, 0) & PSW_MASK;
+#ifdef __s390x__
+ if (proc->mask_32bit)
+ ret &= PSW_MASK31;
+#endif
+ return (void *) ret;
}
diff --git a/sysdeps/linux-gnu/s390/signalent.h b/sysdeps/linux-gnu/s390/signalent.h
index 5395f82..714d56d 100644
--- a/sysdeps/linux-gnu/s390/signalent.h
+++ b/sysdeps/linux-gnu/s390/signalent.h
@@ -29,4 +29,5 @@
"SIGWINCH", /* 28 */
"SIGIO", /* 29 */
"SIGPWR", /* 30 */
- "SIGSYS", /* 31 */
+ "SIGUNUSED", /* 31 */
+ "SIGRTMIN", /* 32 */
diff --git a/sysdeps/linux-gnu/s390/signalent1.h b/sysdeps/linux-gnu/s390/signalent1.h
new file mode 100644
index 0000000..b5b6ca8
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/signalent1.h
@@ -0,0 +1 @@
+#include "s390/signalent.h"
diff --git a/sysdeps/linux-gnu/s390/syscallent.h b/sysdeps/linux-gnu/s390/syscallent.h
index 13bd3c2..5a35d93 100644
--- a/sysdeps/linux-gnu/s390/syscallent.h
+++ b/sysdeps/linux-gnu/s390/syscallent.h
@@ -1,277 +1,5 @@
- "0", /* 0 */
- "exit", /* 1 */
- "fork", /* 2 */
- "read", /* 3 */
- "write", /* 4 */
- "open", /* 5 */
- "close", /* 6 */
- "7", /* 7 */
- "creat", /* 8 */
- "link", /* 9 */
- "unlink", /* 10 */
- "execve", /* 11 */
- "chdir", /* 12 */
- "time", /* 13 */
- "mknod", /* 14 */
- "chmod", /* 15 */
- "lchown", /* 16 */
- "17", /* 17 */
- "18", /* 18 */
- "lseek", /* 19 */
- "getpid", /* 20 */
- "mount", /* 21 */
- "umount", /* 22 */
- "setuid", /* 23 */
- "getuid", /* 24 */
- "stime", /* 25 */
- "ptrace", /* 26 */
- "alarm", /* 27 */
- "28", /* 28 */
- "pause", /* 29 */
- "utime", /* 30 */
- "31", /* 31 */
- "32", /* 32 */
- "access", /* 33 */
- "nice", /* 34 */
- "35", /* 35 */
- "sync", /* 36 */
- "kill", /* 37 */
- "rename", /* 38 */
- "mkdir", /* 39 */
- "rmdir", /* 40 */
- "dup", /* 41 */
- "pipe", /* 42 */
- "times", /* 43 */
- "44", /* 44 */
- "brk", /* 45 */
- "setgid", /* 46 */
- "getgid", /* 47 */
- "signal", /* 48 */
- "geteuid", /* 49 */
- "getegid", /* 50 */
- "acct", /* 51 */
- "umount2", /* 52 */
- "53", /* 53 */
- "ioctl", /* 54 */
- "fcntl", /* 55 */
- "56", /* 56 */
- "setpgid", /* 57 */
- "58", /* 58 */
- "59", /* 59 */
- "umask", /* 60 */
- "chroot", /* 61 */
- "ustat", /* 62 */
- "dup2", /* 63 */
- "getppid", /* 64 */
- "getpgrp", /* 65 */
- "setsid", /* 66 */
- "sigaction", /* 67 */
- "68", /* 68 */
- "69", /* 69 */
- "setreuid", /* 70 */
- "setregid", /* 71 */
- "sigsuspend", /* 72 */
- "sigpending", /* 73 */
- "sethostname", /* 74 */
- "setrlimit", /* 75 */
- "getrlimit", /* 76 */
- "getrusage", /* 77 */
- "gettimeofday", /* 78 */
- "settimeofday", /* 79 */
- "getgroups", /* 80 */
- "setgroups", /* 81 */
- "82", /* 82 */
- "symlink", /* 83 */
- "84", /* 84 */
- "readlink", /* 85 */
- "uselib", /* 86 */
- "swapon", /* 87 */
- "reboot", /* 88 */
- "readdir", /* 89 */
- "mmap", /* 90 */
- "munmap", /* 91 */
- "truncate", /* 92 */
- "ftruncate", /* 93 */
- "fchmod", /* 94 */
- "fchown", /* 95 */
- "getpriority", /* 96 */
- "setpriority", /* 97 */
- "98", /* 98 */
- "statfs", /* 99 */
- "fstatfs", /* 100 */
- "ioperm", /* 101 */
- "socketcall", /* 102 */
- "syslog", /* 103 */
- "setitimer", /* 104 */
- "getitimer", /* 105 */
- "stat", /* 106 */
- "lstat", /* 107 */
- "fstat", /* 108 */
- "109", /* 109 */
- "110", /* 110 */
- "vhangup", /* 111 */
- "idle", /* 112 */
- "113", /* 113 */
- "wait4", /* 114 */
- "swapoff", /* 115 */
- "sysinfo", /* 116 */
- "ipc", /* 117 */
- "fsync", /* 118 */
- "sigreturn", /* 119 */
- "clone", /* 120 */
- "setdomainname", /* 121 */
- "uname", /* 122 */
- "123", /* 123 */
- "adjtimex", /* 124 */
- "mprotect", /* 125 */
- "sigprocmask", /* 126 */
- "create_module", /* 127 */
- "init_module", /* 128 */
- "delete_module", /* 129 */
- "get_kernel_syms", /* 130 */
- "quotactl", /* 131 */
- "getpgid", /* 132 */
- "fchdir", /* 133 */
- "bdflush", /* 134 */
- "sysfs", /* 135 */
- "personality", /* 136 */
- "afs_syscall", /* 137 */
- "setfsuid", /* 138 */
- "setfsgid", /* 139 */
- "_llseek", /* 140 */
- "getdents", /* 141 */
- "_newselect", /* 142 */
- "flock", /* 143 */
- "msync", /* 144 */
- "readv", /* 145 */
- "writev", /* 146 */
- "getsid", /* 147 */
- "fdatasync", /* 148 */
- "_sysctl", /* 149 */
- "mlock", /* 150 */
- "munlock", /* 151 */
- "mlockall", /* 152 */
- "munlockall", /* 153 */
- "sched_setparam", /* 154 */
- "sched_getparam", /* 155 */
- "sched_setscheduler", /* 156 */
- "sched_getscheduler", /* 157 */
- "sched_yield", /* 158 */
- "sched_get_priority_max", /* 159 */
- "sched_get_priority_min", /* 160 */
- "sched_rr_get_interval", /* 161 */
- "nanosleep", /* 162 */
- "mremap", /* 163 */
- "setresuid", /* 164 */
- "getresuid", /* 165 */
- "166", /* 166 */
- "query_module", /* 167 */
- "poll", /* 168 */
- "nfsservctl", /* 169 */
- "setresgid", /* 170 */
- "getresgid", /* 171 */
- "prctl", /* 172 */
- "rt_sigreturn", /* 173 */
- "rt_sigaction", /* 174 */
- "rt_sigprocmask", /* 175 */
- "rt_sigpending", /* 176 */
- "rt_sigtimedwait", /* 177 */
- "rt_sigqueueinfo", /* 178 */
- "rt_sigsuspend", /* 179 */
- "pread", /* 180 */
- "pwrite", /* 181 */
- "chown", /* 182 */
- "getcwd", /* 183 */
- "capget", /* 184 */
- "capset", /* 185 */
- "sigaltstack", /* 186 */
- "sendfile", /* 187 */
- "getpmsg", /* 188 */
- "putpmsg", /* 189 */
- "vfork", /* 190 */
- "ugetrlimit", /* 191 */
- "mmap2", /* 192 */
- "truncate64", /* 193 */
- "ftruncate64", /* 194 */
- "stat64", /* 195 */
- "lstat64", /* 196 */
- "fstat64", /* 197 */
- "lchown32", /* 198 */
- "getuid32", /* 199 */
- "getgid32", /* 200 */
- "geteuid32", /* 201 */
- "getegid32", /* 202 */
- "setreuid32", /* 203 */
- "setregid32", /* 204 */
- "getgroups32", /* 205 */
- "setgroups32", /* 206 */
- "fchown32", /* 207 */
- "setresuid32", /* 208 */
- "getresuid32", /* 209 */
- "setresgid32", /* 210 */
- "getresgid32", /* 211 */
- "chown32", /* 212 */
- "setuid32", /* 213 */
- "setgid32", /* 214 */
- "setfsuid32", /* 215 */
- "setfsgid32", /* 216 */
- "pivot_root", /* 217 */
- "mincore", /* 218 */
- "madvise", /* 219 */
- "getdents64", /* 220 */
- "fcntl64", /* 221 */
- "readahead", /* 222 */
- "sendfile64", /* 223 */
- "setxattr", /* 224 */
- "lsetxattr", /* 225 */
- "fsetxattr", /* 226 */
- "getxattr", /* 227 */
- "lgetxattr", /* 228 */
- "fgetxattr", /* 229 */
- "listxattr", /* 230 */
- "llistxattr", /* 231 */
- "flistxattr", /* 232 */
- "removexattr", /* 233 */
- "lremovexattr", /* 234 */
- "fremovexattr", /* 235 */
- "gettid", /* 236 */
- "tkill", /* 237 */
- "futex", /* 238 */
- "sched_setaffinity", /* 239 */
- "sched_getaffinity", /* 240 */
- "241", /* 241 */
- "242", /* 242 */
- "io_setup", /* 243 */
- "io_destroy", /* 244 */
- "io_getevents", /* 245 */
- "io_submit", /* 246 */
- "io_cancel", /* 247 */
- "exit_group", /* 248 */
- "epoll_create", /* 249 */
- "epoll_ctl", /* 250 */
- "epoll_wait", /* 251 */
- "set_tid_address", /* 252 */
- "fadvise64", /* 253 */
- "timer_create", /* 254 */
- "timer_settime", /* 255 */
- "timer_gettime", /* 256 */
- "timer_getoverrun", /* 257 */
- "timer_delete", /* 258 */
- "clock_settime", /* 259 */
- "clock_gettime", /* 260 */
- "clock_getres", /* 261 */
- "clock_nanosleep", /* 262 */
- "263", /* 263 */
- "fadvise64_64", /* 264 */
- "statfs64", /* 265 */
- "fstatfs64", /* 266 */
- "267", /* 267 */
- "268", /* 268 */
- "269", /* 269 */
- "270", /* 270 */
- "mq_open", /* 271 */
- "mq_unlink", /* 272 */
- "mq_timedsend", /* 273 */
- "mq_timedreceive", /* 274 */
- "mq_notify", /* 275 */
- "mq_getsetattr", /* 276 */
+#ifdef __s390x__
+#include "s390/syscalls64.h"
+#else
+#include "s390/syscalls31.h"
+#endif
diff --git a/sysdeps/linux-gnu/s390/syscallent1.h b/sysdeps/linux-gnu/s390/syscallent1.h
new file mode 100644
index 0000000..c9fdc81
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/syscallent1.h
@@ -0,0 +1 @@
+#include "s390/syscalls31.h"
diff --git a/sysdeps/linux-gnu/s390/syscalls31.h b/sysdeps/linux-gnu/s390/syscalls31.h
new file mode 100644
index 0000000..6f5876b
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/syscalls31.h
@@ -0,0 +1,287 @@
+"0",
+"exit",
+"fork",
+"read",
+"write",
+"open",
+"close",
+"7",
+"creat",
+"link",
+"unlink",
+"execve",
+"chdir",
+"time",
+"mknod",
+"chmod",
+"lchown16",
+"17",
+"18",
+"lseek",
+"getpid",
+"mount",
+"oldumount",
+"setuid16",
+"getuid16",
+"stime",
+"ptrace",
+"alarm",
+"28",
+"pause",
+"utime",
+"31",
+"32",
+"access",
+"nice",
+"35",
+"sync",
+"kill",
+"rename",
+"mkdir",
+"rmdir",
+"dup",
+"pipe",
+"times",
+"44",
+"brk",
+"setgid16",
+"getgid16",
+"signal",
+"geteuid16",
+"getegid16",
+"acct",
+"umount",
+"53",
+"ioctl",
+"fcntl",
+"56",
+"setpgid",
+"58",
+"59",
+"umask",
+"chroot",
+"ustat",
+"dup2",
+"getppid",
+"getpgrp",
+"setsid",
+"sigaction",
+"68",
+"69",
+"setreuid16",
+"setregid16",
+"sigsuspend",
+"sigpending",
+"sethostname",
+"setrlimit",
+"old_getrlimit",
+"getrusage",
+"gettimeofday",
+"settimeofday",
+"getgroups16",
+"setgroups16",
+"82",
+"symlink",
+"84",
+"readlink",
+"uselib",
+"swapon",
+"reboot",
+"89",
+"old_mmap",
+"munmap",
+"truncate",
+"ftruncate",
+"fchmod",
+"fchown16",
+"getpriority",
+"setpriority",
+"98",
+"statfs",
+"fstatfs",
+"101",
+"socketcall",
+"syslog",
+"setitimer",
+"getitimer",
+"newstat",
+"newlstat",
+"newfstat",
+"109",
+"lookup_dcookie",
+"vhangup",
+"112",
+"113",
+"wait4",
+"swapoff",
+"sysinfo",
+"ipc",
+"fsync",
+"sigreturn",
+"clone",
+"setdomainname",
+"newuname",
+"123",
+"adjtimex",
+"mprotect",
+"sigprocmask",
+"127",
+"init_module",
+"delete_module",
+"130",
+"quotactl",
+"getpgid",
+"fchdir",
+"bdflush",
+"sysfs",
+"personality",
+"137",
+"setfsuid16",
+"setfsgid16",
+"llseek",
+"getdents",
+"select",
+"flock",
+"msync",
+"readv",
+"writev",
+"getsid",
+"fdatasync",
+"sysctl",
+"mlock",
+"munlock",
+"mlockall",
+"munlockall",
+"sched_setparam",
+"sched_getparam",
+"sched_setscheduler",
+"sched_getscheduler",
+"sched_yield",
+"sched_get_priority_max",
+"sched_get_priority_min",
+"sched_rr_get_interval",
+"nanosleep",
+"mremap",
+"setresuid16",
+"getresuid16",
+"166",
+"167",
+"poll",
+"nfsservctl",
+"setresgid16",
+"getresgid16",
+"prctl",
+"rt_sigreturn",
+"rt_sigaction",
+"rt_sigprocmask",
+"rt_sigpending",
+"rt_sigtimedwait",
+"rt_sigqueueinfo",
+"rt_sigsuspend",
+"pread64",
+"pwrite64",
+"chown16",
+"getcwd",
+"capget",
+"capset",
+"sigaltstack",
+"sendfile",
+"188",
+"189",
+"vfork",
+"getrlimit",
+"mmap2",
+"truncate64",
+"ftruncate64",
+"stat64",
+"lstat64",
+"fstat64",
+"lchown",
+"getuid",
+"getgid",
+"geteuid",
+"getegid",
+"setreuid",
+"setregid",
+"getgroups",
+"setgroups",
+"fchown",
+"setresuid",
+"getresuid",
+"setresgid",
+"getresgid",
+"chown",
+"setuid",
+"setgid",
+"setfsuid",
+"setfsgid",
+"pivot_root",
+"mincore",
+"madvise",
+"getdents64",
+"fcntl64",
+"readahead",
+"sendfile64",
+"setxattr",
+"lsetxattr",
+"fsetxattr",
+"getxattr",
+"lgetxattr",
+"fgetxattr",
+"listxattr",
+"llistxattr",
+"flistxattr",
+"removexattr",
+"lremovexattr",
+"fremovexattr",
+"gettid",
+"tkill",
+"futex",
+"sched_setaffinity",
+"sched_getaffinity",
+"tgkill",
+"242",
+"io_setup",
+"io_destroy",
+"io_getevents",
+"io_submit",
+"io_cancel",
+"exit_group",
+"epoll_create",
+"epoll_ctl",
+"epoll_wait",
+"set_tid_address",
+"fadvise64",
+"timer_create",
+"timer_settime",
+"timer_gettime",
+"timer_getoverrun",
+"timer_delete",
+"clock_settime",
+"clock_gettime",
+"clock_getres",
+"clock_nanosleep",
+"263",
+"fadvise64_64",
+"statfs64",
+"fstatfs64",
+"remap_file_pages",
+"268",
+"269",
+"270",
+"mq_open",
+"mq_unlink",
+"mq_timedsend",
+"mq_timedreceive",
+"mq_notify",
+"mq_getsetattr",
+"kexec_load",
+"add_key",
+"request_key",
+"keyctl",
+"waitid",
+"ioprio_set",
+"ioprio_get",
+"inotify_init",
+"inotify_add_watch",
+"inotify_rm_watch",
diff --git a/sysdeps/linux-gnu/s390/syscalls64.h b/sysdeps/linux-gnu/s390/syscalls64.h
new file mode 100644
index 0000000..8d48c71
--- /dev/null
+++ b/sysdeps/linux-gnu/s390/syscalls64.h
@@ -0,0 +1,287 @@
+"0",
+"exit",
+"fork",
+"read",
+"write",
+"open",
+"close",
+"7",
+"creat",
+"link",
+"unlink",
+"execve",
+"chdir",
+"13",
+"mknod",
+"chmod",
+"16",
+"17",
+"18",
+"lseek",
+"getpid",
+"mount",
+"oldumount",
+"23",
+"24",
+"25",
+"ptrace",
+"alarm",
+"28",
+"pause",
+"utime",
+"31",
+"32",
+"access",
+"nice",
+"35",
+"sync",
+"kill",
+"rename",
+"mkdir",
+"rmdir",
+"dup",
+"pipe",
+"times",
+"44",
+"brk",
+"46",
+"47",
+"signal",
+"49",
+"50",
+"acct",
+"umount",
+"53",
+"ioctl",
+"fcntl",
+"56",
+"setpgid",
+"58",
+"59",
+"umask",
+"chroot",
+"ustat",
+"dup2",
+"getppid",
+"getpgrp",
+"setsid",
+"sigaction",
+"68",
+"69",
+"70",
+"71",
+"sigsuspend",
+"sigpending",
+"sethostname",
+"setrlimit",
+"getrlimit",
+"getrusage",
+"gettimeofday",
+"settimeofday",
+"80",
+"81",
+"82",
+"symlink",
+"84",
+"readlink",
+"uselib",
+"swapon",
+"reboot",
+"89",
+"old_mmap",
+"munmap",
+"truncate",
+"ftruncate",
+"fchmod",
+"95",
+"getpriority",
+"setpriority",
+"98",
+"statfs",
+"fstatfs",
+"101",
+"socketcall",
+"syslog",
+"setitimer",
+"getitimer",
+"newstat",
+"newlstat",
+"newfstat",
+"109",
+"lookup_dcookie",
+"vhangup",
+"112",
+"113",
+"wait4",
+"swapoff",
+"sysinfo",
+"ipc",
+"fsync",
+"sigreturn",
+"clone",
+"setdomainname",
+"newuname",
+"123",
+"adjtimex",
+"mprotect",
+"sigprocmask",
+"127",
+"init_module",
+"delete_module",
+"130",
+"quotactl",
+"getpgid",
+"fchdir",
+"bdflush",
+"sysfs",
+"personality",
+"137",
+"138",
+"139",
+"llseek",
+"getdents",
+"select",
+"flock",
+"msync",
+"readv",
+"writev",
+"getsid",
+"fdatasync",
+"sysctl",
+"mlock",
+"munlock",
+"mlockall",
+"munlockall",
+"sched_setparam",
+"sched_getparam",
+"sched_setscheduler",
+"sched_getscheduler",
+"sched_yield",
+"sched_get_priority_max",
+"sched_get_priority_min",
+"sched_rr_get_interval",
+"nanosleep",
+"mremap",
+"164",
+"165",
+"166",
+"167",
+"poll",
+"nfsservctl",
+"170",
+"171",
+"prctl",
+"rt_sigreturn",
+"rt_sigaction",
+"rt_sigprocmask",
+"rt_sigpending",
+"rt_sigtimedwait",
+"rt_sigqueueinfo",
+"rt_sigsuspend",
+"pread64",
+"pwrite64",
+"182",
+"getcwd",
+"capget",
+"capset",
+"sigaltstack",
+"sendfile64",
+"188",
+"189",
+"vfork",
+"getrlimit",
+"mmap2",
+"193",
+"194",
+"195",
+"196",
+"197",
+"lchown",
+"getuid",
+"getgid",
+"geteuid",
+"getegid",
+"setreuid",
+"setregid",
+"getgroups",
+"setgroups",
+"fchown",
+"setresuid",
+"getresuid",
+"setresgid",
+"getresgid",
+"chown",
+"setuid",
+"setgid",
+"setfsuid",
+"setfsgid",
+"pivot_root",
+"mincore",
+"madvise",
+"getdents64",
+"221",
+"readahead",
+"223",
+"setxattr",
+"lsetxattr",
+"fsetxattr",
+"getxattr",
+"lgetxattr",
+"fgetxattr",
+"listxattr",
+"llistxattr",
+"flistxattr",
+"removexattr",
+"lremovexattr",
+"fremovexattr",
+"gettid",
+"tkill",
+"futex",
+"sched_setaffinity",
+"sched_getaffinity",
+"tgkill",
+"242",
+"io_setup",
+"io_destroy",
+"io_getevents",
+"io_submit",
+"io_cancel",
+"exit_group",
+"epoll_create",
+"epoll_ctl",
+"epoll_wait",
+"set_tid_address",
+"fadvise64_64",
+"timer_create",
+"timer_settime",
+"timer_gettime",
+"timer_getoverrun",
+"timer_delete",
+"clock_settime",
+"clock_gettime",
+"clock_getres",
+"clock_nanosleep",
+"263",
+"264",
+"statfs64",
+"fstatfs64",
+"remap_file_pages",
+"268",
+"269",
+"270",
+"mq_open",
+"mq_unlink",
+"mq_timedsend",
+"mq_timedreceive",
+"mq_notify",
+"mq_getsetattr",
+"kexec_load",
+"add_key",
+"request_key",
+"keyctl",
+"waitid",
+"ioprio_set",
+"ioprio_get",
+"inotify_init",
+"inotify_add_watch",
+"inotify_rm_watch",
diff --git a/sysdeps/linux-gnu/s390/trace.c b/sysdeps/linux-gnu/s390/trace.c
index 2208555..e0e55a4 100644
--- a/sysdeps/linux-gnu/s390/trace.c
+++ b/sysdeps/linux-gnu/s390/trace.c
@@ -4,14 +4,15 @@
** Other routines are in ../trace.c and need to be combined
** at link time with this code.
**
-** S/390 version
-** Copyright (C) 2001 IBM Poughkeepsie, IBM Corporation
+** Copyright (C) 2001,2005 IBM Corp.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
+#include <errno.h>
+#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
@@ -28,75 +29,165 @@
# define PTRACE_POKEUSER PTRACE_POKEUSR
#endif
-void get_arch_dep(struct process *proc)
-{
+void
+get_arch_dep(struct process * proc) {
+#ifdef __s390x__
+ unsigned long psw;
+
+ if (proc->arch_ptr)
+ return;
+
+ psw = ptrace(PTRACE_PEEKUSER, proc->pid, PT_PSWMASK, 0);
+
+ if ((psw & 0x000000180000000) == 0x000000080000000) {
+ proc->mask_32bit = 1;
+ proc->personality = 1;
+ }
+
+ proc->arch_ptr = (void *) 1;
+#endif
}
/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
*/
-int syscall_p(struct process *proc, int status, int *sysnum)
-{
- long pswa;
- long svcinst;
- long svcno;
- long svcop;
+int
+syscall_p(struct process * proc, int status, int * sysnum) {
+ long pc, opcode, offset_reg, scno, tmp;
+ void *svc_addr;
+ int gpr_offset[16] = {PT_GPR0, PT_GPR1, PT_ORIGGPR2, PT_GPR3,
+ PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7,
+ PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11,
+ PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15};
- if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) {
+ if (WIFSTOPPED(status) && WSTOPSIG(status)==(SIGTRAP | proc->tracesysgood)) {
- pswa = ptrace(PTRACE_PEEKUSER, proc->pid, PT_PSWADDR, 0);
- svcinst =
- ptrace(PTRACE_PEEKTEXT, proc->pid, (char *)(pswa - 4), 0);
- svcop = (svcinst >> 8) & 0xFF;
- svcno = svcinst & 0xFF;
+ /*
+ * If we have PTRACE_O_TRACESYSGOOD and we have the new style
+ * of passing the system call number to user space via PT_GPR2
+ * then the task is quite easy.
+ */
- *sysnum = svcno;
+ *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR2, 0);
- if (*sysnum == -1) {
- return 0;
- }
- if (svcop == 0 && svcno == 1) {
- /* Breakpoint was hit... */
- return 0;
- }
- if (svcop == 10 && *sysnum >= 0) {
+ if (proc->tracesysgood) {
/* System call was encountered... */
if (proc->callstack_depth > 0 &&
- proc->callstack[proc->callstack_depth -
- 1].is_syscall) {
+ proc->callstack[proc->callstack_depth-1].is_syscall) {
+ /* syscall exit */
+ *sysnum = proc->callstack[proc->callstack_depth-1].c_un.syscall;
return 2;
} else {
- return 1;
+ /* syscall enter */
+ if (*sysnum != -ENOSYS)
+ return 1;
}
- } else {
- /* Unknown trap was encountered... */
+ }
+
+ /*
+ * At least one of the two requirements mentioned above is not
+ * met. Therefore the fun part starts here:
+ * We try to do some instruction decoding without even knowing
+ * the instruction code length of the last instruction executed.
+ * Needs to be done to get the system call number or to decide
+ * if we reached a breakpoint or even checking for a completely
+ * unrelated instruction.
+ * Just a heuristic that most of the time appears to work...
+ */
+
+ pc = ptrace(PTRACE_PEEKUSER, proc->pid, PT_PSWADDR, 0);
+ opcode = ptrace(PTRACE_PEEKTEXT, proc->pid,
+ (char *)(pc-sizeof(long)),0);
+
+ if ((opcode & 0xffff) == 0x0001) {
+ /* Breakpoint */
return 0;
}
+ else if ((opcode & 0xff00) == 0x0a00) {
+ /* SVC opcode */
+ scno = opcode & 0xff;
+ }
+ else if ((opcode & 0xff000000) == 0x44000000) {
+ /* Instruction decoding of EXECUTE... */
+ svc_addr = (void *) (opcode & 0xfff);
+
+ offset_reg = (opcode & 0x000f0000) >> 16;
+ if (offset_reg)
+ svc_addr += ptrace(PTRACE_PEEKUSER, proc->pid,
+ gpr_offset[offset_reg], 0);
+
+ offset_reg = (opcode & 0x0000f000) >> 12;
+ if (offset_reg)
+ svc_addr += ptrace(PTRACE_PEEKUSER, proc->pid,
+ gpr_offset[offset_reg], 0);
+
+ scno = ptrace(PTRACE_PEEKTEXT, proc->pid, svc_addr, 0);
+#ifdef __s390x__
+ scno >>= 48;
+#else
+ scno >>= 16;
+#endif
+ if ((scno & 0xff00) != 0x0a000)
+ return 0;
+
+ tmp = 0;
+ offset_reg = (opcode & 0x00f00000) >> 20;
+ if (offset_reg)
+ tmp = ptrace(PTRACE_PEEKUSER, proc->pid,
+ gpr_offset[offset_reg], 0);
+
+ scno = (scno | tmp) & 0xff;
+ }
+ else {
+ /* No opcode related to syscall handling */
+ return 0;
+ }
+
+ if (scno == 0)
+ scno = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR1, 0);
+
+ *sysnum = scno;
+
+ /* System call was encountered... */
+ if (proc->callstack_depth > 0 &&
+ proc->callstack[proc->callstack_depth-1].is_syscall) {
+ return 2;
+ } else {
+ return 1;
+ }
}
/* Unknown status... */
return 0;
}
-long gimme_arg(enum tof type, struct process *proc, int arg_num)
-{
- switch (arg_num) {
- case -1: /* return value */
- return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR2, 0);
- case 0:
- return ptrace(PTRACE_PEEKUSER, proc->pid, PT_ORIGGPR2, 0);
- case 1:
- return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR3, 0);
- case 2:
- return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR4, 0);
- case 3:
- return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR5, 0);
- case 4:
- return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR6, 0);
- default:
- fprintf(stderr, "gimme_arg called with wrong arguments\n");
- exit(2);
+long
+gimme_arg(enum tof type, struct process * proc, int arg_num) {
+ long ret;
+
+ switch(arg_num) {
+ case -1: /* return value */
+ ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR2, 0);
+ break;
+ case 0: ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_ORIGGPR2, 0);
+ break;
+ case 1: ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR3, 0);
+ break;
+ case 2: ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR4, 0);
+ break;
+ case 3: ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR5, 0);
+ break;
+ case 4: ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR6, 0);
+ break;
+ default:
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ exit(2);
}
+#ifdef __s390x__
+ if (proc->mask_32bit)
+ ret &= 0xffffffff;
+#endif
+ return ret;
}
-void save_register_args(enum tof type, struct process *proc)
-{
+void
+save_register_args(enum tof type, struct process * proc) {
}
diff --git a/sysdeps/linux-gnu/sparc/arch.h b/sysdeps/linux-gnu/sparc/arch.h
index d2f85d2..b3d3006 100644
--- a/sysdeps/linux-gnu/sparc/arch.h
+++ b/sysdeps/linux-gnu/sparc/arch.h
@@ -4,4 +4,8 @@
#define LT_ELFCLASS ELFCLASS32
#define LT_ELF_MACHINE EM_SPARC
+#define LT_ELFCLASS2 ELFCLASS32
#define LT_ELF_MACHINE2 EM_SPARC32PLUS
+
+#define PLTs_INIT_BY_HERE NULL
+#define E_ENTRY_NAME "_start"
diff --git a/sysdeps/linux-gnu/sparc/plt.c b/sysdeps/linux-gnu/sparc/plt.c
index 5a2edac..e39bb58 100644
--- a/sysdeps/linux-gnu/sparc/plt.c
+++ b/sysdeps/linux-gnu/sparc/plt.c
@@ -2,7 +2,13 @@
#include "ltrace.h"
#include "elf.h"
-GElf_Addr arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela)
+GElf_Addr
+arch_plt_sym_val (struct ltelf *lte, size_t ndx, GElf_Rela *rela)
{
- return rela->r_offset + 4;
+ return rela->r_offset + 4;
+}
+
+void * plt2addr(struct process *proc, void ** plt)
+{
+ return (void *) plt;
}
diff --git a/sysdeps/linux-gnu/sparc/regs.c b/sysdeps/linux-gnu/sparc/regs.c
index 1f2861a..78efec3 100644
--- a/sysdeps/linux-gnu/sparc/regs.c
+++ b/sysdeps/linux-gnu/sparc/regs.c
@@ -6,32 +6,32 @@
#include "ptrace.h"
#include "ltrace.h"
-void *get_instruction_pointer(struct process *proc)
-{
- proc_archdep *a = (proc_archdep *) (proc->arch_ptr);
+void *
+get_instruction_pointer(struct process * proc) {
+ proc_archdep *a = (proc_archdep *)(proc->arch_ptr);
if (a->valid)
return (void *)a->regs.r_pc;
return (void *)-1;
}
-void set_instruction_pointer(struct process *proc, void *addr)
-{
- proc_archdep *a = (proc_archdep *) (proc->arch_ptr);
+void
+set_instruction_pointer(struct process * proc, void * addr) {
+ proc_archdep *a = (proc_archdep *)(proc->arch_ptr);
if (a->valid)
a->regs.r_pc = (long)addr;
}
-void *get_stack_pointer(struct process *proc)
-{
- proc_archdep *a = (proc_archdep *) (proc->arch_ptr);
+void *
+get_stack_pointer(struct process * proc) {
+ proc_archdep *a = (proc_archdep *)(proc->arch_ptr);
if (a->valid)
return (void *)a->regs.r_o6;
return (void *)-1;
}
-void *get_return_addr(struct process *proc, void *stack_pointer)
-{
- proc_archdep *a = (proc_archdep *) (proc->arch_ptr);
+void *
+get_return_addr(struct process * proc, void * stack_pointer) {
+ proc_archdep *a = (proc_archdep *)(proc->arch_ptr);
unsigned int t;
if (!a->valid)
return (void *)-1;
diff --git a/sysdeps/linux-gnu/sparc/syscallent.h b/sysdeps/linux-gnu/sparc/syscallent.h
index c7ddc4f..3b6f7fe 100644
--- a/sysdeps/linux-gnu/sparc/syscallent.h
+++ b/sysdeps/linux-gnu/sparc/syscallent.h
@@ -149,12 +149,12 @@
"pciconfig_read", /* 148 */
"pciconfig_write", /* 149 */
"getsockname", /* 150 */
- "151", /* 151 */
- "152", /* 152 */
+ "inotify_init", /* 151 */
+ "inotify_add_watch", /* 152 */
"poll", /* 153 */
"getdents64", /* 154 */
"fcntl64", /* 155 */
- "156", /* 156 */
+ "inotify_rm_watch", /* 156 */
"statfs", /* 157 */
"fstatfs", /* 158 */
"umount", /* 159 */
@@ -194,7 +194,7 @@
"epoll_create", /* 193 */
"epoll_ctl", /* 194 */
"epoll_wait", /* 195 */
- "196", /* 196 */
+ "ioprio_set", /* 196 */
"getppid", /* 197 */
"sigaction", /* 198 */
"sgetmask", /* 199 */
@@ -216,7 +216,7 @@
"ipc", /* 215 */
"sigreturn", /* 216 */
"clone", /* 217 */
- "218", /* 218 */
+ "ioprio_get", /* 218 */
"adjtimex", /* 219 */
"sigprocmask", /* 220 */
"create_module", /* 221 */
@@ -278,3 +278,7 @@
"mq_notify", /* 277 */
"mq_getsetattr", /* 278 */
"waitid", /* 279 */
+ "setaltroot", /* 280 */
+ "add_key", /* 281 */
+ "request_key", /* 282 */
+ "keyctl", /* 283 */
diff --git a/sysdeps/linux-gnu/sparc/trace.c b/sysdeps/linux-gnu/sparc/trace.c
index 1f407e5..c39de44 100644
--- a/sysdeps/linux-gnu/sparc/trace.c
+++ b/sysdeps/linux-gnu/sparc/trace.c
@@ -18,8 +18,8 @@ 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);
+ 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.
@@ -27,19 +27,16 @@ void get_arch_dep(struct process *proc)
*/
int syscall_p(struct process *proc, int status, int *sysnum)
{
- if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) {
+ if (WIFSTOPPED(status) && WSTOPSIG(status)==(SIGTRAP | proc->tracesysgood)) {
void *ip = get_instruction_pointer(proc);
unsigned int insn;
- if (ip == (void *)-1)
- return 0;
+ 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) {
+ *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) {
+ } else if(*sysnum>=0) {
return 1;
}
}
@@ -47,24 +44,23 @@ int syscall_p(struct process *proc, int status, int *sysnum)
return 0;
}
-long gimme_arg(enum tof type, struct process *proc, int arg_num)
+long gimme_arg(enum tof type, struct process * proc, int arg_num)
{
- proc_archdep *a = (proc_archdep *) proc->arch_ptr;
+ 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 */
+ if (arg_num==-1) /* return value */
return a->regs.r_o0;
- if (type == LT_TOF_FUNCTION || type == LT_TOF_SYSCALL || arg_num >= 6) {
+ 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 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)
+ else if (type==LT_TOF_SYSCALLR)
return a->sysc_arg[arg_num];
else {
fprintf(stderr, "gimme_arg called with wrong arguments\n");
@@ -73,9 +69,9 @@ long gimme_arg(enum tof type, struct process *proc, int arg_num)
return 0;
}
-void save_register_args(enum tof type, struct process *proc)
+void save_register_args(enum tof type, struct process * proc)
{
- proc_archdep *a = (proc_archdep *) proc->arch_ptr;
+ 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));
diff --git a/sysdeps/linux-gnu/trace.c b/sysdeps/linux-gnu/trace.c
index bbf40e6..cbcce4d 100644
--- a/sysdeps/linux-gnu/trace.c
+++ b/sysdeps/linux-gnu/trace.c
@@ -9,87 +9,140 @@
#include "ltrace.h"
#include "options.h"
+#include "sysdep.h"
-/* Returns 1 if the sysnum may make a new child to be created
- * (ie, with fork() or clone())
- * Returns 0 otherwise.
- */
-int fork_p(int sysnum)
+static int fork_exec_syscalls[][5] = {
{
- return 0
-#if defined(__NR_fork)
- || (sysnum == __NR_fork)
+#ifdef __NR_fork
+ __NR_fork,
+#else
+ -1,
#endif
-#if defined(__NR_clone)
- || (sysnum == __NR_clone)
+#ifdef __NR_clone
+ __NR_clone,
+#else
+ -1,
#endif
-#if defined(__NR_vfork)
- || (sysnum == __NR_vfork)
+#ifdef __NR_clone2
+ __NR_clone2,
+#else
+ -1,
#endif
-#if defined(__NR_clone2)
- || (sysnum == __NR_clone2)
+#ifdef __NR_vfork
+ __NR_vfork,
+#else
+ -1,
+#endif
+#ifdef __NR_execve
+ __NR_execve,
+#else
+ -1,
#endif
- ;
+}
+#ifdef FORK_EXEC_SYSCALLS
+FORK_EXEC_SYSCALLS
+#endif
+};
+
+/* Returns 1 if the sysnum may make a new child to be created
+ * (ie, with fork() or clone())
+ * Returns 0 otherwise.
+ */
+int
+fork_p(struct process * proc, int sysnum) {
+ int i;
+ if (proc->personality
+ >= sizeof fork_exec_syscalls / sizeof (fork_exec_syscalls [0]))
+ return 0;
+ for (i = 0; i < sizeof (fork_exec_syscalls[0]) / sizeof (int) - 1; ++i)
+ if (sysnum == fork_exec_syscalls[proc->personality][i])
+ return 1;
+ return 0;
}
/* Returns 1 if the sysnum may make the process exec other program
*/
-int exec_p(int sysnum)
-{
- return (sysnum == __NR_execve);
+int
+exec_p(struct process * proc, int sysnum) {
+ int i;
+ if (proc->personality
+ >= sizeof fork_exec_syscalls / sizeof (fork_exec_syscalls [0]))
+ return 0;
+ i = sizeof (fork_exec_syscalls[0]) / sizeof (int) - 1;
+ if (sysnum == fork_exec_syscalls[proc->personality][i])
+ return 1;
+ return 0;
}
-void trace_me(void)
-{
- if (ptrace(PTRACE_TRACEME, 0, 1, 0) < 0) {
+void
+trace_me(void) {
+ if (ptrace(PTRACE_TRACEME, 0, 1, 0)<0) {
perror("PTRACE_TRACEME");
exit(1);
}
}
-int trace_pid(pid_t pid)
-{
+int
+trace_pid(pid_t pid) {
if (ptrace(PTRACE_ATTACH, pid, 1, 0) < 0) {
return -1;
}
return 0;
}
-void untrace_pid(pid_t pid)
-{
+void
+trace_set_options(struct process * proc, pid_t pid) {
+#ifndef PTRACE_SETOPTIONS
+ #define PTRACE_SETOPTIONS 0x4200
+#endif
+#ifndef PTRACE_OLDSETOPTIONS
+ #define PTRACE_OLDSETOPTIONS 21
+#endif
+#ifndef PTRACE_O_TRACESYSGOOD
+ #define PTRACE_O_TRACESYSGOOD 0x00000001
+#endif
+ if (proc->tracesysgood & 0x80)
+ return;
+ if (ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACESYSGOOD) < 0 &&
+ ptrace(PTRACE_OLDSETOPTIONS, pid, 0, PTRACE_O_TRACESYSGOOD) < 0) {
+ perror("PTRACE_SETOPTIONS");
+ return;
+ }
+ proc->tracesysgood |= 0x80;
+}
+
+void
+untrace_pid(pid_t pid) {
ptrace(PTRACE_DETACH, pid, 1, 0);
}
-void continue_after_signal(pid_t pid, int signum)
-{
+void
+continue_after_signal(pid_t pid, int signum) {
/* We should always trace syscalls to be able to control fork(), clone(), execve()... */
ptrace(PTRACE_SYSCALL, pid, 0, signum);
}
-void continue_process(pid_t pid)
-{
+void
+continue_process(pid_t pid) {
continue_after_signal(pid, 0);
}
-void continue_enabling_breakpoint(pid_t pid, struct breakpoint *sbp)
-{
+void
+continue_enabling_breakpoint(pid_t pid, struct breakpoint * sbp) {
enable_breakpoint(pid, sbp);
continue_process(pid);
}
-void continue_after_breakpoint(struct process *proc, struct breakpoint *sbp)
-{
- if (sbp->enabled)
- disable_breakpoint(proc->pid, sbp);
-
+void
+continue_after_breakpoint(struct process *proc, struct breakpoint * sbp) {
+ if (sbp->enabled) disable_breakpoint(proc->pid, sbp);
set_instruction_pointer(proc, sbp->addr);
-
if (sbp->enabled == 0) {
continue_process(proc->pid);
} else {
proc->breakpoint_being_enabled = sbp;
-#ifdef __sparc__ || defined __ia64__
- /* we don't want to single step here */
+#if defined __sparc__ || defined __ia64___
+ /* we don't want to singlestep here */
continue_process(proc->pid);
#else
ptrace(PTRACE_SINGLESTEP, proc->pid, 0, 0);
@@ -97,27 +150,24 @@ void continue_after_breakpoint(struct process *proc, struct breakpoint *sbp)
}
}
-int umovestr(struct process *proc, void *addr, int len, void *laddr)
-{
- union {
- long a;
- char c[sizeof(long)];
- } a;
+int
+umovestr(struct process * proc, void * addr, int len, void * laddr) {
+ union { long a; char c[sizeof(long)]; } a;
int i;
- int offset = 0;
+ int offset=0;
- while (offset < len) {
- a.a = ptrace(PTRACE_PEEKTEXT, proc->pid, addr + offset, 0);
- for (i = 0; i < sizeof(long); i++) {
- if (a.c[i] && offset + i < len) {
- *(char *)(laddr + offset + i) = a.c[i];
+ while(offset<len) {
+ a.a = ptrace(PTRACE_PEEKTEXT, proc->pid, addr+offset, 0);
+ for(i=0; i<sizeof(long); i++) {
+ if (a.c[i] && offset+i < len) {
+ *(char *)(laddr+offset+i) = a.c[i];
} else {
- *(char *)(laddr + offset + i) = '\0';
+ *(char *)(laddr+offset+i) = '\0';
return 0;
}
}
offset += sizeof(long);
}
- *(char *)(laddr + offset) = '\0';
+ *(char *)(laddr+offset) = '\0';
return 0;
}
diff --git a/sysdeps/linux-gnu/x86_64/arch.h b/sysdeps/linux-gnu/x86_64/arch.h
index a7c8816..e819d2c 100644
--- a/sysdeps/linux-gnu/x86_64/arch.h
+++ b/sysdeps/linux-gnu/x86_64/arch.h
@@ -4,3 +4,12 @@
#define LT_ELFCLASS ELFCLASS64
#define LT_ELF_MACHINE EM_X86_64
+#define LT_ELFCLASS2 ELFCLASS32
+#define LT_ELF_MACHINE2 EM_386
+
+#define PLTs_INIT_BY_HERE NULL
+#define E_ENTRY_NAME "_start"
+
+/* __NR_fork, __NR_clone, __NR_clone2, __NR_vfork and __NR_execve
+ from asm-i386/unistd.h. */
+#define FORK_EXEC_SYSCALLS , { 2, 120, -1, 190, 11 }
diff --git a/sysdeps/linux-gnu/x86_64/plt.c b/sysdeps/linux-gnu/x86_64/plt.c
index 939bc4e..36d0ecd 100644
--- a/sysdeps/linux-gnu/x86_64/plt.c
+++ b/sysdeps/linux-gnu/x86_64/plt.c
@@ -2,7 +2,13 @@
#include "ltrace.h"
#include "elf.h"
-GElf_Addr arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela)
+GElf_Addr
+arch_plt_sym_val (struct ltelf *lte, size_t ndx, GElf_Rela *rela)
{
- return lte->plt_addr + (ndx + 1) * 16;
+ return lte->plt_addr + (ndx + 1) * 16;
+}
+
+void * plt2addr(struct process *proc, void ** plt)
+{
+ return (void *) plt;
}
diff --git a/sysdeps/linux-gnu/x86_64/regs.c b/sysdeps/linux-gnu/x86_64/regs.c
index a2a27a9..29160b3 100644
--- a/sysdeps/linux-gnu/x86_64/regs.c
+++ b/sysdeps/linux-gnu/x86_64/regs.c
@@ -16,22 +16,34 @@
# define PTRACE_POKEUSER PTRACE_POKEUSR
#endif
-void *get_instruction_pointer(struct process *proc)
-{
- return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RIP, 0);
+void *
+get_instruction_pointer(struct process * proc) {
+ long int ret = ptrace(PTRACE_PEEKUSER, proc->pid, 8*RIP, 0);
+ if (proc->mask_32bit)
+ ret &= 0xffffffff;
+ return (void *)ret;
}
-void set_instruction_pointer(struct process *proc, void *addr)
-{
- ptrace(PTRACE_POKEUSER, proc->pid, 8 * RIP, addr);
+void
+set_instruction_pointer(struct process * proc, void * addr) {
+ if (proc->mask_32bit)
+ addr = (void *)((long int) addr & 0xffffffff);
+ ptrace(PTRACE_POKEUSER, proc->pid, 8*RIP, addr);
}
-void *get_stack_pointer(struct process *proc)
-{
- return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RSP, 0);
+void *
+get_stack_pointer(struct process * proc) {
+ long int ret = ptrace(PTRACE_PEEKUSER, proc->pid, 8*RSP, 0);
+ if (proc->mask_32bit)
+ ret &= 0xffffffff;
+ return (void *)ret;
}
-void *get_return_addr(struct process *proc, void *stack_pointer)
-{
- return (void *)ptrace(PTRACE_PEEKTEXT, proc->pid, stack_pointer, 0);
+void *
+get_return_addr(struct process * proc, void * stack_pointer) {
+ unsigned long int ret;
+ ret = ptrace(PTRACE_PEEKTEXT, proc->pid, stack_pointer, 0);
+ if (proc->mask_32bit)
+ ret &= 0xffffffff;
+ return (void *)ret;
}
diff --git a/sysdeps/linux-gnu/x86_64/signalent1.h b/sysdeps/linux-gnu/x86_64/signalent1.h
new file mode 100644
index 0000000..5ead946
--- /dev/null
+++ b/sysdeps/linux-gnu/x86_64/signalent1.h
@@ -0,0 +1 @@
+#include "i386/signalent.h"
diff --git a/sysdeps/linux-gnu/x86_64/syscallent.h b/sysdeps/linux-gnu/x86_64/syscallent.h
index 31aa74a..e98f98c 100644
--- a/sysdeps/linux-gnu/x86_64/syscallent.h
+++ b/sysdeps/linux-gnu/x86_64/syscallent.h
@@ -246,3 +246,11 @@
"mq_getsetattr", /* 245 */
"kexec_load", /* 246 */
"waitid", /* 247 */
+ "add_key", /* 248 */
+ "request_key", /* 249 */
+ "keyctl", /* 250 */
+ "ioprio_set", /* 251 */
+ "ioprio_get", /* 252 */
+ "inotify_init", /* 253 */
+ "inotify_add_watch", /* 254 */
+ "inotify_rm_watch", /* 255 */
diff --git a/sysdeps/linux-gnu/x86_64/syscallent1.h b/sysdeps/linux-gnu/x86_64/syscallent1.h
new file mode 100644
index 0000000..d8dd9f7
--- /dev/null
+++ b/sysdeps/linux-gnu/x86_64/syscallent1.h
@@ -0,0 +1 @@
+#include "i386/syscallent.h"
diff --git a/sysdeps/linux-gnu/x86_64/trace.c b/sysdeps/linux-gnu/x86_64/trace.c
index 3232afd..f08583d 100644
--- a/sysdeps/linux-gnu/x86_64/trace.c
+++ b/sysdeps/linux-gnu/x86_64/trace.c
@@ -21,73 +21,93 @@
void get_arch_dep(struct process *proc)
{
+ unsigned long cs;
+ if (proc->arch_ptr)
+ return;
+ cs = ptrace(PTRACE_PEEKUSER, proc->pid, 8*CS, 0);
+ if (cs == 0x23) {
+ proc->mask_32bit = 1;
+ proc->personality = 1;
+ }
+ proc->arch_ptr = (void *) 1;
}
/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
*/
-int syscall_p(struct process *proc, int status, int *sysnum)
-{
- if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) {
- *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 8 * ORIG_RAX, 0);
+int
+syscall_p(struct process * proc, int status, int * sysnum) {
+ if (WIFSTOPPED(status) && WSTOPSIG(status)==(SIGTRAP | proc->tracesysgood)) {
+ *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 8*ORIG_RAX, 0);
if (proc->callstack_depth > 0 &&
- proc->callstack[proc->callstack_depth - 1].is_syscall) {
+ proc->callstack[proc->callstack_depth-1].is_syscall) {
return 2;
}
- if (*sysnum >= 0) {
+ if (*sysnum>=0) {
return 1;
}
}
return 0;
}
-long gimme_arg(enum tof type, struct process *proc, int arg_num)
-{
- if (arg_num == -1) { /* return value */
- return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RAX, 0);
+static unsigned int
+gimme_arg32(enum tof type, struct process * proc, int arg_num) {
+ if (arg_num==-1) { /* return value */
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8*RAX, 0);
+ }
+
+ if (type==LT_TOF_FUNCTION || type==LT_TOF_FUNCTIONR) {
+ return ptrace(PTRACE_PEEKTEXT, proc->pid, proc->stack_pointer+4*(arg_num+1), 0);
+ } else if (type==LT_TOF_SYSCALL || type==LT_TOF_SYSCALLR) {
+ switch(arg_num) {
+ case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, 8*RBX, 0);
+ case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, 8*RCX, 0);
+ case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, 8*RDX, 0);
+ case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, 8*RSI, 0);
+ case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, 8*RDI, 0);
+ case 5: return ptrace(PTRACE_PEEKUSER, proc->pid, 8*RBP, 0);
+ default:
+ fprintf(stderr, "gimme_arg32 called with wrong arguments\n");
+ exit(2);
+ }
+ }
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ exit(1);
+}
+
+long
+gimme_arg(enum tof type, struct process * proc, int arg_num) {
+ if (proc->mask_32bit)
+ return (unsigned int)gimme_arg32(type, proc, arg_num);
+
+ if (arg_num==-1) { /* return value */
+ return ptrace(PTRACE_PEEKUSER, proc->pid, 8*RAX, 0);
}
- if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) {
- switch (arg_num) {
- case 0:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RDI, 0);
- case 1:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RSI, 0);
- case 2:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RDX, 0);
- case 3:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RCX, 0);
- case 4:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * R8, 0);
- case 5:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * R9, 0);
- default:
- return ptrace(PTRACE_PEEKTEXT, proc->pid,
- proc->stack_pointer + 8 * (arg_num - 6 +
- 1), 0);
- fprintf(stderr,
- "gimme_arg called with wrong arguments\n");
- exit(2);
+ if (type==LT_TOF_FUNCTION || type==LT_TOF_FUNCTIONR) {
+ switch(arg_num) {
+ case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, 8*RDI, 0);
+ case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, 8*RSI, 0);
+ case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, 8*RDX, 0);
+ case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, 8*RCX, 0);
+ case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, 8*R8, 0);
+ case 5: return ptrace(PTRACE_PEEKUSER, proc->pid, 8*R9, 0);
+ default:
+ return ptrace(PTRACE_PEEKTEXT, proc->pid,
+ proc->stack_pointer + 8 * (arg_num - 6 + 1), 0);
}
- } else if (type == LT_TOF_SYSCALL || LT_TOF_SYSCALLR) {
- switch (arg_num) {
- case 0:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RDI, 0);
- case 1:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RSI, 0);
- case 2:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * RDX, 0);
- case 3:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * R10, 0);
- case 4:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * R8, 0);
- case 5:
- return ptrace(PTRACE_PEEKUSER, proc->pid, 8 * R9, 0);
- default:
- fprintf(stderr,
- "gimme_arg called with wrong arguments\n");
- exit(2);
+ } else if (type==LT_TOF_SYSCALL || LT_TOF_SYSCALLR) {
+ switch(arg_num) {
+ case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, 8*RDI, 0);
+ case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, 8*RSI, 0);
+ case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, 8*RDX, 0);
+ case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, 8*R10, 0);
+ case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, 8*R8, 0);
+ case 5: return ptrace(PTRACE_PEEKUSER, proc->pid, 8*R9, 0);
+ default:
+ fprintf(stderr, "gimme_arg called with wrong arguments\n");
+ exit(2);
}
} else {
fprintf(stderr, "gimme_arg called with wrong arguments\n");
@@ -97,6 +117,6 @@ long gimme_arg(enum tof type, struct process *proc, int arg_num)
return 0;
}
-void save_register_args(enum tof type, struct process *proc)
+void save_register_args(enum tof type, struct process * proc)
{
}