3 * Copyright 2011 Daniel Borkmann <dborkma@tik.ee.ethz.ch>
6 * Faculty of Computer Science, Mathematics and Natural Sciences,
7 * Leipzig University of Applied Sciences (HTWK Leipzig)
15 #include <sys/types.h>
19 #define ADDRESSLISTSIZ 20
24 #include "stacktrace.h"
27 unsigned long real_addr
;
28 unsigned long closest_addr
;
33 static void kill_pipe(int fd
, int pid
)
39 static int spawn_pipe(const char *cmd
, pid_t
*pid
)
59 dup2(pipefd
[1], STDOUT_FILENO
);
60 dup2(pipefd
[1], STDERR_FILENO
);
63 * The System() call assumes that /bin/sh is
64 * always available, and so will we.
66 execl("/bin/sh", "/bin/sh", "-c", cmd
, NULL
);
78 static int pull_from_pipe(int fd
, char *buffer
, int max
)
84 if (read(fd
, &c
, 1) < 1)
98 char buffer
[TMPBUFSIZ
], type
;
100 struct faddress syms
[ADDRESSLISTSIZ
+ 1];
101 unsigned long addr
, hi_addr
, lo_addr
;
104 for (i
= 0, p
= &p
; p
; ++i
) {
106 * This is based on code by Steve Coleman
107 * <steve.colemanjhuapl.edu> __builtin_return_address()
108 * only accepts a constant as argument.
112 if (__builtin_frame_address(0))
113 p
= __builtin_return_address(0);
117 if (__builtin_frame_address(1))
118 p
= __builtin_return_address(1);
122 if (__builtin_frame_address(2))
123 p
= __builtin_return_address(2);
127 if (__builtin_frame_address(3))
128 p
= __builtin_return_address(3);
132 if (__builtin_frame_address(4))
133 p
= __builtin_return_address(4);
137 if (__builtin_frame_address(5))
138 p
= __builtin_return_address(5);
142 if (__builtin_frame_address(6))
143 p
= __builtin_return_address(6);
147 if (__builtin_frame_address(7))
148 p
= __builtin_return_address(7);
152 if (__builtin_frame_address(8))
153 p
= __builtin_return_address(8);
157 if (__builtin_frame_address(9))
158 p
= __builtin_return_address(9);
162 if (__builtin_frame_address(10))
163 p
= __builtin_return_address(10);
167 if (__builtin_frame_address(11))
168 p
= __builtin_return_address(11);
172 if (__builtin_frame_address(12))
173 p
= __builtin_return_address(12);
177 if (__builtin_frame_address(13))
178 p
= __builtin_return_address(13);
182 if (__builtin_frame_address(14))
183 p
= __builtin_return_address(14);
187 if (__builtin_frame_address(15))
188 p
= __builtin_return_address(15);
192 if (__builtin_frame_address(16))
193 p
= __builtin_return_address(16);
197 if (__builtin_frame_address(17))
198 p
= __builtin_return_address(17);
202 if (__builtin_frame_address(18))
203 p
= __builtin_return_address(18);
207 if (__builtin_frame_address(19))
208 p
= __builtin_return_address(19);
216 if (p
&& i
< ADDRESSLISTSIZ
) {
217 syms
[i
].real_addr
= (unsigned long) p
;
218 syms
[i
].closest_addr
= 0;
222 syms
[i
].real_addr
= 0;
227 strcpy(buffer
, "nm -B ");
228 strcat(buffer
, TARGETNAME
);
233 fd
= spawn_pipe(buffer
, &pid
);
235 panic("Cannot spawn pipe to shell!\n");
237 while (pull_from_pipe(fd
, buffer
, sizeof(buffer
))) {
238 if (buffer
[0] == '\n')
240 ret
= sscanf(buffer
, "%lx %c %s", &addr
, &type
, name
);
243 if (type
!= 't' && type
!= 'T')
251 for (i
= 0; syms
[i
].real_addr
!= 0; ++i
) {
252 if (addr
<= syms
[i
].real_addr
&&
253 addr
> syms
[i
].closest_addr
) {
254 syms
[i
].closest_addr
= addr
;
255 strlcpy(syms
[i
].name
, name
, SYMNAMSIZ
);
263 for (i
= 0; syms
[i
].real_addr
!= 0; ++i
) {
264 if (syms
[i
].name
[0] == 0 ||
265 syms
[i
].real_addr
<= lo_addr
||
266 syms
[i
].real_addr
>= hi_addr
)
267 sprintf(buffer
, "[%d] 0x%08lx ???\n",
268 i
, syms
[i
].real_addr
);
270 sprintf(buffer
, "[%d] 0x%08lx <%s+0x%lx> %c\n",
271 i
, syms
[i
].real_addr
, syms
[i
].name
,
272 syms
[i
].real_addr
- syms
[i
].closest_addr
,