diff --git a/Makefile.am b/Makefile.am index 3b678b7c..66111cee 100644 --- a/Makefile.am +++ b/Makefile.am @@ -248,6 +248,7 @@ strace_SOURCES = \ print_group_req.c \ print_fields.h \ print_ifindex.c \ + print_instruction_pointer.c \ print_mac.c \ print_mq_attr.c \ print_msgbuf.c \ diff --git a/defs.h b/defs.h index 9f1754c1..3003a556 100644 --- a/defs.h +++ b/defs.h @@ -441,7 +441,9 @@ extern int read_int_from_file(struct tcb *, const char *, int *); extern void set_sortby(const char *); extern void set_overhead(int); -extern void print_pc(struct tcb *); + +extern bool get_instruction_pointer(struct tcb *, kernel_ulong_t *); +extern void print_instruction_pointer(struct tcb *); extern int syscall_entering_decode(struct tcb *); extern int syscall_entering_trace(struct tcb *, unsigned int *); diff --git a/print_instruction_pointer.c b/print_instruction_pointer.c new file mode 100644 index 00000000..ede52811 --- /dev/null +++ b/print_instruction_pointer.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 1999-2018 The strace developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "defs.h" + +void +print_instruction_pointer(struct tcb *tcp) +{ + kernel_ulong_t ip; + + if (get_instruction_pointer(tcp, &ip)) { + tprintf(current_wordsize == 4 + ? "[%08" PRI_klx "] " + : "[%016" PRI_klx "] ", ip); + } else { + tprints(current_wordsize == 4 + ? "[????????] " + : "[????????????????] "); + } +} diff --git a/strace.c b/strace.c index 1710c371..6f51c00e 100644 --- a/strace.c +++ b/strace.c @@ -692,7 +692,7 @@ printleader(struct tcb *tcp) } if (iflag) - print_pc(tcp); + print_instruction_pointer(tcp); } void diff --git a/syscall.c b/syscall.c index 2c80258d..e1b2f20e 100644 --- a/syscall.c +++ b/syscall.c @@ -998,27 +998,6 @@ restore_cleared_syserror(struct tcb *tcp) # include "arch_getrval2.c" #endif -void -print_pc(struct tcb *tcp) -{ -#if defined ARCH_PC_REG -# define ARCH_GET_PC 0 -#elif defined ARCH_PC_PEEK_ADDR - kernel_ulong_t pc; -# define ARCH_PC_REG pc -# define ARCH_GET_PC upeek(tcp, ARCH_PC_PEEK_ADDR, &pc) -#else -# error Neither ARCH_PC_REG nor ARCH_PC_PEEK_ADDR is defined -#endif - if (get_regs(tcp) < 0 || ARCH_GET_PC) - tprints(current_wordsize == 4 ? "[????????] " - : "[????????????????] "); - else - tprintf(current_wordsize == 4 - ? "[%08" PRI_klx "] " : "[%016" PRI_klx "] ", - (kernel_ulong_t) ARCH_PC_REG); -} - #include "getregs_old.h" #undef ptrace_getregset_or_getregs @@ -1199,6 +1178,23 @@ free_sysent_buf(void *ptr) free(ptr); } +bool +get_instruction_pointer(struct tcb *tcp, kernel_ulong_t *ip) +{ +#if defined ARCH_PC_REG + if (get_regs(tcp) < 0) + return false; + *ip = (kernel_ulong_t) ARCH_PC_REG; + return true; +#elif defined ARCH_PC_PEEK_ADDR + if (upeek(tcp, ARCH_PC_PEEK_ADDR, ip) < 0) + return false; + return true; +#else +# error Neither ARCH_PC_REG nor ARCH_PC_PEEK_ADDR is defined +#endif +} + /* * Returns: * 0: "ignore this ptrace stop", syscall_entering_decode() should return a "bail