📄 util.c
字号:
/* * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl> * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl> * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com> * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl> * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation * Linux for s390 port by D.J. Barrow * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com> * 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. * * $Id: util.c,v 1.22 2001/03/27 12:17:17 wichert Exp $ */#include "defs.h"#include <sys/user.h>#include <sys/param.h>#include <fcntl.h>#ifdef SUNOS4#include <machine/reg.h>#include <a.out.h>#include <link.h>#endif /* SUNOS4 */#if defined(linux) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1))#include <linux/ptrace.h>#endif #if defined(LINUX) && defined(IA64)#include <asm/ptrace_offsets.h>#endif#ifdef HAVE_SYS_REG_H#include <sys/reg.h># define PTRACE_PEEKUSR PTRACE_PEEKUSER#elif defined(HAVE_LINUX_PTRACE_H)#undef PTRACE_SYSCALL#include <linux/ptrace.h>#endif#ifdef SUNOS4_KERNEL_ARCH_KLUDGE#include <sys/utsname.h>#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */#if defined(LINUX) && defined(SPARC)#include <asm/reg.h>#if !defined(__GLIBC__)#include <linux/unistd.h>#define _hack_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,\ type5,arg5,syscall) \type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \{ \ long __res; \\__asm__ volatile ("or %%g0, %1, %%o0\n\t" \ "or %%g0, %2, %%o1\n\t" \ "or %%g0, %3, %%o2\n\t" \ "or %%g0, %4, %%o3\n\t" \ "or %%g0, %5, %%o4\n\t" \ "or %%g0, %6, %%g1\n\t" \ "t 0x10\n\t" \ "bcc 1f\n\t" \ "or %%g0, %%o0, %0\n\t" \ "sub %%g0, %%o0, %0\n\t" \ "1:\n\t" \ : "=r" (__res) \ : "0" ((long)(arg1)),"1" ((long)(arg2)), \ "2" ((long)(arg3)),"3" ((long)(arg4)),"4" ((long)(arg5)), \ "i" (__NR_##syscall) \ : "g1", "o0", "o1", "o2", "o3", "o4"); \if (__res>=0) \ return (type) __res; \errno = -__res; \return -1; \}static _hack_syscall5(int,_ptrace,int,__request,int,__pid,int,__addr,int,__data,int,__addr2,ptrace)#define _ptrace#endif#endif/* macros */#ifndef MAX#define MAX(a,b) (((a) > (b)) ? (a) : (b))#endif#ifndef MIN#define MIN(a,b) (((a) < (b)) ? (a) : (b))#endifvoidtv_tv(tv, a, b)struct timeval *tv;int a;int b;{ tv->tv_sec = a; tv->tv_usec = b;}inttv_nz(a)struct timeval *a;{ return a->tv_sec || a->tv_usec;}inttv_cmp(a, b)struct timeval *a, *b;{ if (a->tv_sec < b->tv_sec || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec)) return -1; if (a->tv_sec > b->tv_sec || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec)) return 1; return 0;}doubletv_float(tv)struct timeval *tv;{ return tv->tv_sec + tv->tv_usec/1000000.0;}voidtv_add(tv, a, b)struct timeval *tv, *a, *b;{ tv->tv_sec = a->tv_sec + b->tv_sec; tv->tv_usec = a->tv_usec + b->tv_usec; if (tv->tv_usec > 1000000) { tv->tv_sec++; tv->tv_usec -= 1000000; }}voidtv_sub(tv, a, b)struct timeval *tv, *a, *b;{ tv->tv_sec = a->tv_sec - b->tv_sec; tv->tv_usec = a->tv_usec - b->tv_usec; if (((long) tv->tv_usec) < 0) { tv->tv_sec--; tv->tv_usec += 1000000; }}voidtv_div(tv, a, n)struct timeval *tv, *a;int n;{ tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n; tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000; tv->tv_usec %= 1000000;}voidtv_mul(tv, a, n)struct timeval *tv, *a;int n;{ tv->tv_usec = a->tv_usec * n; tv->tv_sec = a->tv_sec * n + a->tv_usec / 1000000; tv->tv_usec %= 1000000;}char *xlookup(xlat, val)struct xlat *xlat;int val;{ for (; xlat->str != NULL; xlat++) if (xlat->val == val) return xlat->str; return NULL;}/* * Print entry in struct xlat table, if there. */voidprintxval(xlat, val, dflt)struct xlat *xlat;int val;char *dflt;{ char *str = xlookup(xlat, val); if (str) tprintf("%s", str); else tprintf("%#x /* %s */", val, dflt);}/* * Interpret `xlat' as an array of flags * print the entries whose bits are on in `flags' * return # of flags printed. */intaddflags(xlat, flags)struct xlat *xlat;int flags;{ int n; for (n = 0; xlat->str; xlat++) { if (xlat->val && (flags & xlat->val) == xlat->val) { tprintf("|%s", xlat->str); flags &= ~xlat->val; n++; } } if (flags) { tprintf("|%#x", flags); n++; } return n;}intprintflags(xlat, flags)struct xlat *xlat;int flags;{ int n; char *sep; if (flags == 0 && xlat->val == 0) { tprintf("%s", xlat->str); return 1; } sep = ""; for (n = 0; xlat->str; xlat++) { if (xlat->val && (flags & xlat->val) == xlat->val) { tprintf("%s%s", sep, xlat->str); flags &= ~xlat->val; sep = "|"; n++; } } if (flags) { tprintf("%s%#x", sep, flags); n++; } return n;}voidprintnum(tcp, addr, fmt)struct tcb *tcp;long addr;char *fmt;{ int num; if (!addr) { tprintf("NULL"); return; } if (umove(tcp, addr, &num) < 0) { tprintf("%#lx", addr); return; } tprintf("["); tprintf(fmt, num); tprintf("]");}static char path[MAXPATHLEN + 1];voidstring_quote(str)char *str;{ char buf[2 * MAXPATHLEN + 1]; char *s; if (!strpbrk(str, "\"\'\\")) { tprintf("\"%s\"", str); return; } for (s = buf; *str; str++) { switch (*str) { case '\"': case '\'': case '\\': *s++ = '\\'; *s++ = *str; break; default: *s++ = *str; break; } } *s = '\0'; tprintf("\"%s\"", buf);}voidprintpath(tcp, addr)struct tcb *tcp;long addr;{ if (umovestr(tcp, addr, MAXPATHLEN, path) < 0) tprintf("%#lx", addr); else string_quote(path); return;}voidprintpathn(tcp, addr, n)struct tcb *tcp;long addr;int n;{ if (umovestr(tcp, addr, n, path) < 0) tprintf("%#lx", addr); else { path[n] = '\0'; string_quote(path); }}voidprintstr(tcp, addr, len)struct tcb *tcp;long addr;int len;{ static unsigned char *str = NULL; static char *outstr; int i, n, c, usehex; char *s, *outend; if (!addr) { tprintf("NULL"); return; } if (!str) { if ((str = malloc(max_strlen)) == NULL || (outstr = malloc(2*max_strlen)) == NULL) { fprintf(stderr, "printstr: no memory\n"); tprintf("%#lx", addr); return; } } outend = outstr + max_strlen * 2 - 10; if (len < 0) { n = max_strlen; if (umovestr(tcp, addr, n, (char *) str) < 0) { tprintf("%#lx", addr); return; } } else { n = MIN(len, max_strlen); if (umoven(tcp, addr, n, (char *) str) < 0) { tprintf("%#lx", addr); return; } } usehex = 0; if (xflag > 1) usehex = 1; else if (xflag) { for (i = 0; i < n; i++) { c = str[i]; if (len < 0 && c == '\0') break; if (!isprint(c) && !isspace(c)) { usehex = 1; break; } } } s = outstr; *s++ = '\"'; if (usehex) { for (i = 0; i < n; i++) { c = str[i]; if (len < 0 && c == '\0') break; sprintf(s, "\\x%02x", c); s += 4; if (s > outend) break; } } else { for (i = 0; i < n; i++) { c = str[i]; if (len < 0 && c == '\0') break; switch (c) { case '\"': case '\'': case '\\': *s++ = '\\'; *s++ = c; break; case '\f': *s++ = '\\'; *s++ = 'f'; break; case '\n': *s++ = '\\'; *s++ = 'n'; break; case '\r': *s++ = '\\'; *s++ = 'r'; break; case '\t': *s++ = '\\'; *s++ = 't'; break; case '\v': *s++ = '\\'; *s++ = 'v'; break; default: if (isprint(c)) *s++ = c; else if (i < n - 1 && isdigit(str[i + 1])) { sprintf(s, "\\%03o", c); s += 4; } else { sprintf(s, "\\%o", c); s += strlen(s); } break; } if (s > outend) break; } } *s++ = '\"'; if (i < len || (len < 0 && (i == n || s > outend))) { *s++ = '.'; *s++ = '.'; *s++ = '.'; } *s = '\0'; tprintf("%s", outstr);}voiddumpstr(tcp, addr, len)struct tcb *tcp;long addr;int len;{ static int strsize = -1; static unsigned char *str; static char outstr[80]; char *s; int i, j; if (strsize < len) { if (str) free(str); if ((str = malloc(len)) == NULL) { fprintf(stderr, "dump: no memory\n"); return; } strsize = len; } if (umoven(tcp, addr, len, (char *) str) < 0) return; for (i = 0; i < len; i += 16) { s = outstr; sprintf(s, " | %05x ", i); s += 9; for (j = 0; j < 16; j++) { if (j == 8) *s++ = ' '; if (i + j < len) { sprintf(s, " %02x", str[i + j]); s += 3; } else { *s++ = ' '; *s++ = ' '; *s++ = ' '; } } *s++ = ' '; *s++ = ' '; for (j = 0; j < 16; j++) { if (j == 8) *s++ = ' '; if (i + j < len) { if (isprint(str[i + j]))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -