aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetr Machata <pmachata@redhat.com>2013-10-24 14:45:30 +0200
committerPetr Machata <pmachata@redhat.com>2013-10-24 14:45:30 +0200
commit5069ef8f498e5189de0789d79485f39b76c621d4 (patch)
treeb81ecf454991e7a7da0839ed51c56602b2766627
parentac52f2660ec717b6b25c313f20e47a622d3357d8 (diff)
downloadltrace-5069ef8f498e5189de0789d79485f39b76c621d4.tar.gz
Fix fetching of system call arguments on i386
-rw-r--r--sysdeps/linux-gnu/x86/fetch.c56
-rw-r--r--testsuite/ltrace.main/system_call_params.exp12
-rw-r--r--testsuite/ltrace.main/system_calls.exp34
3 files changed, 71 insertions, 31 deletions
diff --git a/sysdeps/linux-gnu/x86/fetch.c b/sysdeps/linux-gnu/x86/fetch.c
index a3b9eb7..6868101 100644
--- a/sysdeps/linux-gnu/x86/fetch.c
+++ b/sysdeps/linux-gnu/x86/fetch.c
@@ -1,6 +1,6 @@
/*
* This file is part of ltrace.
- * Copyright (C) 2011,2012 Petr Machata
+ * Copyright (C) 2011,2012,2013 Petr Machata
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -61,6 +61,7 @@ struct fetch_context
arch_addr_t stack_pointer;
size_t ireg; /* Used-up integer registers. */
size_t freg; /* Used-up floating registers. */
+ int machine;
union {
struct {
@@ -238,21 +239,42 @@ allocate_integer(struct fetch_context *context, struct value *valuep,
case POOL_SYSCALL:
#ifdef __x86_64__
- switch (context->ireg) {
- HANDLE(0, rdi);
- HANDLE(1, rsi);
- HANDLE(2, rdx);
- HANDLE(3, r10);
- HANDLE(4, r8);
- HANDLE(5, r9);
- default:
- assert(!"More than six syscall arguments???");
- abort();
+ if (context->machine == EM_X86_64) {
+ switch (context->ireg) {
+ HANDLE(0, rdi);
+ HANDLE(1, rsi);
+ HANDLE(2, rdx);
+ HANDLE(3, r10);
+ HANDLE(4, r8);
+ HANDLE(5, r9);
+ default:
+ assert(!"More than six syscall arguments???");
+ abort();
+ }
}
+#endif
+ if (context->machine == EM_386) {
+
+#ifdef __x86_64__
+# define HANDLE32(NUM, WHICH) HANDLE(NUM, r##WHICH)
#else
- i386_unreachable();
+# define HANDLE32(NUM, WHICH) HANDLE(NUM, e##WHICH)
#endif
+ switch (context->ireg) {
+ HANDLE32(0, bx);
+ HANDLE32(1, cx);
+ HANDLE32(2, dx);
+ HANDLE32(3, si);
+ HANDLE32(4, di);
+ HANDLE32(5, bp);
+ default:
+ assert(!"More than six syscall arguments???");
+ abort();
+ }
+#undef HANDLE32
+ }
+
case POOL_RETVAL:
switch (context->ireg) {
#ifdef __x86_64__
@@ -572,6 +594,15 @@ arch_fetch_arg_next_32(struct fetch_context *context, enum tof type,
size_t sz = type_sizeof(proc, info);
if (sz == (size_t)-1)
return -1;
+ if (value_reserve(valuep, sz) == NULL)
+ return -1;
+
+ if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) {
+ int cls = allocate_integer(context, valuep,
+ sz, 0, POOL_SYSCALL);
+ assert(cls == CLASS_INTEGER);
+ return 0;
+ }
allocate_stack_slot(context, valuep, sz, 0, 4);
@@ -704,6 +735,7 @@ arch_fetch_arg_init(enum tof type, struct process *proc,
struct fetch_context *ctx = malloc(sizeof(*ctx));
if (ctx == NULL)
return NULL;
+ ctx->machine = proc->e_machine;
assert(type != LT_TOF_FUNCTIONR
&& type != LT_TOF_SYSCALLR);
diff --git a/testsuite/ltrace.main/system_call_params.exp b/testsuite/ltrace.main/system_call_params.exp
index e5bffce..787e342 100644
--- a/testsuite/ltrace.main/system_call_params.exp
+++ b/testsuite/ltrace.main/system_call_params.exp
@@ -22,12 +22,16 @@ set bin [ltraceCompile {} [ltraceSource c {
#include <fcntl.h>
int main(void) {
open("/some/path", O_RDONLY);
+ write(1, "something", 10);
+ mount("source", "target", "filesystemtype", 0, 0);
}
}]]
set dir [ltraceDir]
set conf [ltraceNamedSource "$dir/syscalls.conf" {
int open(string, int);
+ long write(int, string[arg3], ulong);
+ int mount(string, string, string, ulong, addr);
}]
# When given the file directly via -F, ltrace should not use it for
@@ -39,11 +43,15 @@ set conf [ltraceNamedSource "$dir/syscalls.conf" {
# doesn't list readdir, that would be taken from somelib.conf with a
# wrong prototype.
-ltraceMatch1 [ltraceRun -L -S -F $conf -- $bin] {open@SYS\("/some/path"} == 0
+ltraceMatch1 [ltraceRun -L -S -F $conf -- $bin] {^open@SYS\("/some/path"} == 0
# On the other hand, if -F somedir/ is given, we want to accept
# syscalls.conf found there.
-ltraceMatch1 [ltraceRun -L -S -F $dir -- $bin] {open@SYS\("/some/path"} == 1
+ltraceMatch [ltraceRun -L -S -F $dir -- $bin] {
+ {{^open@SYS\("/some/path"} == 1}
+ {{^write@SYS\(1, "something", 10\)} == 1}
+ {{^mount@SYS\("source", "target", "filesystemtype"} == 1}
+}
ltraceDone
diff --git a/testsuite/ltrace.main/system_calls.exp b/testsuite/ltrace.main/system_calls.exp
index 3200d40..a74fa04 100644
--- a/testsuite/ltrace.main/system_calls.exp
+++ b/testsuite/ltrace.main/system_calls.exp
@@ -29,39 +29,39 @@ if [regexp {ELF from incompatible architecture} $exec_output] {
}
-set pattern "munmap@SYS"
+set pattern "^munmap@SYS"
ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 2
-set pattern "write@SYS"
+set pattern "^write@SYS"
ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
-set pattern "unlink@SYS"
+set pattern "^unlink@SYS"
ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
-set pattern "brk@SYS"
+set pattern "^brk@SYS"
ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
-set pattern "open@SYS"
+set pattern "^open@SYS"
ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
-set pattern "(new)?fstat@SYS"
+set pattern "^(new)?fstat(64)?@SYS"
ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 egrep
-set pattern "(old_)?mmap@SYS"
+set pattern "^(old_)?mmap2?@SYS"
ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 egrep
-set pattern "close@SYS"
+set pattern "^close@SYS"
ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
-set pattern "getcwd@SYS"
+set pattern "^getcwd@SYS"
ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
-set pattern "chdir@SYS"
+set pattern "^chdir@SYS"
ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
-set pattern "symlink@SYS"
+set pattern "^symlink@SYS"
ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
-set pattern "unlink@SYS"
+set pattern "^unlink@SYS"
ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
-set pattern "(new)?stat@SYS"
+set pattern "^(new)?stat(64)?@SYS"
ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 egrep
-set pattern "access@SYS"
+set pattern "^access@SYS"
ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
-set pattern "rename@SYS"
+set pattern "^rename@SYS"
ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
-set pattern "mkdir@SYS"
+set pattern "^mkdir@SYS"
ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1
-set pattern "rmdir@SYS"
+set pattern "^rmdir@SYS"
ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1