diff options
author | Petr Machata <pmachata@redhat.com> | 2013-10-24 14:45:30 +0200 |
---|---|---|
committer | Petr Machata <pmachata@redhat.com> | 2013-10-24 14:45:30 +0200 |
commit | 5069ef8f498e5189de0789d79485f39b76c621d4 (patch) | |
tree | b81ecf454991e7a7da0839ed51c56602b2766627 | |
parent | ac52f2660ec717b6b25c313f20e47a622d3357d8 (diff) | |
download | ltrace-5069ef8f498e5189de0789d79485f39b76c621d4.tar.gz |
Fix fetching of system call arguments on i386
-rw-r--r-- | sysdeps/linux-gnu/x86/fetch.c | 56 | ||||
-rw-r--r-- | testsuite/ltrace.main/system_call_params.exp | 12 | ||||
-rw-r--r-- | testsuite/ltrace.main/system_calls.exp | 34 |
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 |