blob: 1b031892909a42cad05adbbbbfca464c8f9bbb16 [file] [log] [blame]
Petr Machatae99af272012-10-26 00:29:52 +02001/*
2 * This file is part of ltrace.
3 * Copyright (C) 2003,2008,2009 Juan Cespedes
4 * Copyright (C) 2006 Ian Wienand
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 */
21
Juan Cespedescac15c32003-01-31 18:58:58 +010022#include <stdio.h>
23#include <stdarg.h>
24
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020025#include "common.h"
Juan Cespedescac15c32003-01-31 18:58:58 +010026
Ian Wienand9a2ad352006-02-20 22:44:45 +010027void
Juan Cespedescd8976d2009-05-14 13:47:58 +020028debug_(int level, const char *file, int line, const char *fmt, ...) {
Juan Cespedescac15c32003-01-31 18:58:58 +010029 char buf[1024];
30 va_list args;
31
Juan Cespedescd8976d2009-05-14 13:47:58 +020032 if (!(options.debug & level)) {
Juan Cespedescac15c32003-01-31 18:58:58 +010033 return;
34 }
35 va_start(args, fmt);
36 vsnprintf(buf, 1024, fmt, args);
37 va_end(args);
38
Juan Cespedescd8976d2009-05-14 13:47:58 +020039 output_line(NULL, "DEBUG: %s:%d: %s", file, line, buf);
Petr Machata5d93a412012-04-13 18:44:26 +020040 fflush(options.output);
Juan Cespedescac15c32003-01-31 18:58:58 +010041}
Ian Wienand9a2ad352006-02-20 22:44:45 +010042
Juan Cespedes5c682042009-05-21 15:59:56 +020043/*
44 * The following section provides a way to print things, like hex dumps,
45 * with out using buffered output. This was written by Steve Munroe of IBM.
46 */
Ian Wienand9a2ad352006-02-20 22:44:45 +010047
48#include <stdio.h>
49#include <errno.h>
50#include <unistd.h>
51#include <stdlib.h>
52#include <sys/ptrace.h>
53
Juan Cespedesf1350522008-12-16 18:19:58 +010054static int
55xwritehexl(long i) {
Ian Wienand2d45b1a2006-02-20 22:48:07 +010056 int rc = 0;
57 char text[17];
58 int j;
59 unsigned long temp = (unsigned long)i;
Ian Wienand9a2ad352006-02-20 22:44:45 +010060
Ian Wienand2d45b1a2006-02-20 22:48:07 +010061 for (j = 15; j >= 0; j--) {
62 char c;
63 c = (char)((temp & 0x0f) + '0');
64 if (c > '9') {
65 c = (char)(c + ('a' - '9' - 1));
66 }
67 text[j] = c;
68 temp = temp >> 4;
69 }
Ian Wienand9a2ad352006-02-20 22:44:45 +010070
Ian Wienand2d45b1a2006-02-20 22:48:07 +010071 rc = write(1, text, 16);
72 return rc;
Ian Wienand9a2ad352006-02-20 22:44:45 +010073}
74
Juan Cespedesf1350522008-12-16 18:19:58 +010075static int
76xwritec(char c) {
Ian Wienand2d45b1a2006-02-20 22:48:07 +010077 char temp = c;
78 char *text = &temp;
79 int rc = 0;
80 rc = write(1, text, 1);
81 return rc;
Ian Wienand9a2ad352006-02-20 22:44:45 +010082}
83
Juan Cespedesf1350522008-12-16 18:19:58 +010084static int
85xwritecr(void) {
Ian Wienand2d45b1a2006-02-20 22:48:07 +010086 return xwritec('\n');
Ian Wienand9a2ad352006-02-20 22:44:45 +010087}
88
Juan Cespedesf1350522008-12-16 18:19:58 +010089static int
90xwritedump(void *ptr, long addr, int len) {
Ian Wienand2d45b1a2006-02-20 22:48:07 +010091 int rc = 0;
92 long *tprt = (long *)ptr;
93 int i;
Ian Wienand9a2ad352006-02-20 22:44:45 +010094
Ian Wienand2d45b1a2006-02-20 22:48:07 +010095 for (i = 0; i < len; i += 8) {
96 xwritehexl(addr);
97 xwritec('-');
98 xwritec('>');
99 xwritehexl(*tprt++);
100 xwritecr();
101 addr += sizeof(long);
102 }
Ian Wienand9a2ad352006-02-20 22:44:45 +0100103
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100104 return rc;
Ian Wienand9a2ad352006-02-20 22:44:45 +0100105}
106
Juan Cespedesf1350522008-12-16 18:19:58 +0100107int
108xinfdump(long pid, void *ptr, int len) {
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100109 int rc;
110 int i;
Juan Cespedese672ad12009-02-11 18:49:18 +0100111 long wrdcnt;
112 long *infwords;
113 long addr;
114
115 wrdcnt = len / sizeof(long) + 1;
116 infwords = malloc(wrdcnt * sizeof(long));
117 if (!infwords) {
118 perror("ltrace: malloc");
119 exit(1);
120 }
121 addr = (long)ptr;
Ian Wienand9a2ad352006-02-20 22:44:45 +0100122
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100123 addr = ((addr + sizeof(long) - 1) / sizeof(long)) * sizeof(long);
Ian Wienand9a2ad352006-02-20 22:44:45 +0100124
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100125 for (i = 0; i < wrdcnt; ++i) {
Petr Machataf4c56d42012-05-05 01:42:14 +0200126 infwords[i] = ptrace(PTRACE_PEEKTEXT, pid, (void *)addr, NULL);
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100127 addr += sizeof(long);
128 }
Ian Wienand9a2ad352006-02-20 22:44:45 +0100129
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100130 rc = xwritedump(infwords, (long)ptr, len);
Ian Wienand9a2ad352006-02-20 22:44:45 +0100131
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100132 free(infwords);
133 return rc;
Ian Wienand9a2ad352006-02-20 22:44:45 +0100134}