From 332a32619c5e66bca75fbb28d81dd35e7ebf77fa Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Sun, 5 Jul 2015 22:09:29 +0000 Subject: [PATCH] Add address printing functions printaddr is a simple function implementing "print NULL or address" idiom. umoven_or_printaddr is a wrapper around umoven that has the same return value semantics as umoven but also prints the address when the data is not going to be fetched (in case of exiting(tcp) && syserror(tcp)) or cannot be fetched (umoven fails). umove_or_printaddr is a macro wrapper around umoven_or_printaddr that mirrors umove wrapper around umoven. * defs.h (printaddr, umoven_or_printaddr): New prototypes. (umove_or_printaddr): New macro. * util.c (printaddr, umoven_or_printaddr): New functions. --- defs.h | 4 ++++ util.c | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/defs.h b/defs.h index 29b98efe..9afba0d4 100644 --- a/defs.h +++ b/defs.h @@ -469,6 +469,9 @@ extern int get_scno(struct tcb *tcp); extern int umoven(struct tcb *, long, unsigned int, void *); #define umove(pid, addr, objp) \ umoven((pid), (addr), sizeof(*(objp)), (void *) (objp)) +extern int umoven_or_printaddr(struct tcb *, long, unsigned int, void *); +#define umove_or_printaddr(pid, addr, objp) \ + umoven_or_printaddr((pid), (addr), sizeof(*(objp)), (void *) (objp)) extern int umovestr(struct tcb *, long, unsigned int, char *); extern int upeek(int pid, long, long *); @@ -511,6 +514,7 @@ extern int getllval(struct tcb *, unsigned long long *, int); extern int printllval(struct tcb *, const char *, int) ATTRIBUTE_FORMAT((printf, 2, 0)); +extern void printaddr(long); extern void printxval(const struct xlat *, const unsigned int, const char *); extern int printargs(struct tcb *); extern int printargs_lu(struct tcb *); diff --git a/util.c b/util.c index 8e9d1d0c..04d13cb0 100644 --- a/util.c +++ b/util.c @@ -375,6 +375,15 @@ printflags(const struct xlat *xlat, int flags, const char *dflt) return n; } +void +printaddr(const long addr) +{ + if (!addr) + tprints("NULL"); + else + tprintf("%#lx", addr); +} + void printnum_long(struct tcb *tcp, long addr, const char *fmt) { @@ -1085,6 +1094,22 @@ umoven(struct tcb *tcp, long addr, unsigned int len, void *our_addr) return 0; } +int +umoven_or_printaddr(struct tcb *tcp, const long addr, const unsigned int len, + void *our_addr) +{ + if (!addr) { + tprints("NULL"); + return -1; + } + if ((exiting(tcp) && syserror(tcp)) || + umoven(tcp, addr, len, our_addr) < 0) { + tprintf("%#lx", addr); + return -1; + } + return 0; +} + /* * Like `umove' but make the additional effort of looking * for a terminating zero byte. -- 2.50.1