Imported Upstream version 0.7.2
[platform/upstream/ltrace.git] / debug.c
1 /*
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
22 #include <stdio.h>
23 #include <stdarg.h>
24
25 #include "common.h"
26
27 void
28 debug_(int level, const char *file, int line, const char *fmt, ...) {
29         char buf[1024];
30         va_list args;
31
32         if (!(options.debug & level)) {
33                 return;
34         }
35         va_start(args, fmt);
36         vsnprintf(buf, 1024, fmt, args);
37         va_end(args);
38
39         output_line(NULL, "DEBUG: %s:%d: %s", file, line, buf);
40         fflush(options.output);
41 }
42
43 /*
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  */
47
48 #include <stdio.h>
49 #include <errno.h>
50 #include <unistd.h>
51 #include <stdlib.h>
52 #include <sys/ptrace.h>
53
54 static int
55 xwritehexl(long i) {
56         int rc = 0;
57         char text[17];
58         int j;
59         unsigned long temp = (unsigned long)i;
60
61         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         }
70
71         rc = write(1, text, 16);
72         return rc;
73 }
74
75 static int
76 xwritec(char c) {
77         char temp = c;
78         char *text = &temp;
79         int rc = 0;
80         rc = write(1, text, 1);
81         return rc;
82 }
83
84 static int
85 xwritecr(void) {
86         return xwritec('\n');
87 }
88
89 static int
90 xwritedump(void *ptr, long addr, int len) {
91         int rc = 0;
92         long *tprt = (long *)ptr;
93         int i;
94
95         for (i = 0; i < len; i += 8) {
96                 xwritehexl(addr);
97                 xwritec('-');
98                 xwritec('>');
99                 xwritehexl(*tprt++);
100                 xwritecr();
101                 addr += sizeof(long);
102         }
103
104         return rc;
105 }
106
107 int
108 xinfdump(long pid, void *ptr, int len) {
109         int rc;
110         int i;
111         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;
122
123         addr = ((addr + sizeof(long) - 1) / sizeof(long)) * sizeof(long);
124
125         for (i = 0; i < wrdcnt; ++i) {
126                 infwords[i] = ptrace(PTRACE_PEEKTEXT, pid, (void *)addr, NULL);
127                 addr += sizeof(long);
128         }
129
130         rc = xwritedump(infwords, (long)ptr, len);
131
132         free(infwords);
133         return rc;
134 }