yann@1036
|
1 |
This patch was vampirised from the 0.5-3.1 Debian-packaged version of ltrace,
|
yann@1036
|
2 |
and contains the following fixes (exerpt from the Debian changelog). Moreover,
|
yann@1036
|
3 |
you will also find an exerpt of the Debian copyright file with proper
|
yann@1036
|
4 |
attribution.
|
yann@1036
|
5 |
|
yann@1036
|
6 |
================ Debian changelog exerpt ================
|
yann@1036
|
7 |
ltrace (0.5-3.1) unstable; urgency=low
|
yann@1036
|
8 |
|
yann@1036
|
9 |
* Non-maintainer upload.
|
yann@1036
|
10 |
* Big thanks for Anderson Lizardo for providing patches!
|
yann@1036
|
11 |
* Add generic support for arm targets, Closes: #176413
|
yann@1036
|
12 |
* Save funtion arguments on arm, Closes: #462530
|
yann@1036
|
13 |
* Add thumb instruction support, Closes: #462531
|
yann@1036
|
14 |
* Add basic arm/eabi support, Closes: #450931
|
yann@1036
|
15 |
* fix exec() testcase cleanup, Closes: #462532
|
yann@1036
|
16 |
* fix memory corruption in clone() test, Closes: #462533
|
yann@1036
|
17 |
* fix tracing child with "-p" option, Closes: #462535
|
yann@1036
|
18 |
* Update standard, no changes
|
yann@1036
|
19 |
|
yann@1036
|
20 |
-- Riku Voipio <riku.voipio@iki.fi> Tue, 29 Jan 2008 00:26:50 +0200
|
yann@1036
|
21 |
|
yann@1036
|
22 |
ltrace (0.5-3) unstable; urgency=low
|
yann@1036
|
23 |
|
yann@1036
|
24 |
* Really fix compilation problems in ppc (!)
|
yann@1036
|
25 |
|
yann@1036
|
26 |
-- Juan Cespedes <cespedes@debian.org> Fri, 31 Aug 2007 19:04:03 +0200
|
yann@1036
|
27 |
|
yann@1036
|
28 |
ltrace (0.5-2) unstable; urgency=low
|
yann@1036
|
29 |
|
yann@1036
|
30 |
* Fixed compilation issue in ppc
|
yann@1036
|
31 |
|
yann@1036
|
32 |
-- Juan Cespedes <cespedes@debian.org> Fri, 31 Aug 2007 13:53:27 +0200
|
yann@1036
|
33 |
|
yann@1036
|
34 |
ltrace (0.5-1) unstable; urgency=low
|
yann@1036
|
35 |
|
yann@1036
|
36 |
* New upstream version
|
yann@1036
|
37 |
* Remove some unneeded files in /usr/share/doc (ChangeLog, COPYING...)
|
yann@1036
|
38 |
* Fix several typos (closes: Bug#372928)
|
yann@1036
|
39 |
* Added more system calls to ltrace.conf
|
yann@1036
|
40 |
|
yann@1036
|
41 |
-- Juan Cespedes <cespedes@debian.org> Thu, 30 Aug 2007 14:54:44 +0200
|
yann@1036
|
42 |
============== End Debian changelog exerpt ==============
|
yann@1036
|
43 |
|
yann@1036
|
44 |
================ Debian copyright exerpt ================
|
yann@1036
|
45 |
Copyrights
|
yann@1036
|
46 |
----------
|
yann@1036
|
47 |
Copyright (C) 1997-2007 Juan Cespedes <cespedes@debian.org>
|
yann@1036
|
48 |
|
yann@1036
|
49 |
ARMLinux port: Copyright (C) 1998 Pat Beirne <pbeirne@home.com>
|
yann@1036
|
50 |
m68k port: Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
|
yann@1036
|
51 |
Misc fixes: Copyright (C) 1999 Morten Eriksen <mortene@sim.no>
|
yann@1036
|
52 |
s390 port: Copyright (C) 2001 IBM Poughkeepsie, IBM Cororation <slate@us.ibm.com>
|
yann@1036
|
53 |
ELF hacking: Copyright (C) 1999 Silvio Cesare <silvio@big.net.au>
|
yann@1036
|
54 |
PowerPC port: Copyright (C) 2001-2002 Anton Blanchard <anton@samba.org>
|
yann@1036
|
55 |
SPARC port: Copyright (C) 1999 Jakub Jelinek <jakub@redhat.com>
|
yann@1036
|
56 |
|
yann@1036
|
57 |
Autoconf stuff: Copyright 1992-1996 Free Software Foundation, Inc.
|
yann@1036
|
58 |
install-sh: Copyright 1991 by the Massachusetts Institute of Technology
|
yann@1036
|
59 |
C++ demangle: Copyright 1989-1997 Free Software Foundation, Inc.
|
yann@1036
|
60 |
============== End Debian copyright exerpt ==============
|
yann@1036
|
61 |
|
yann@1036
|
62 |
diff -durN ltrace-0.5.orig/breakpoints.c ltrace-0.5/breakpoints.c
|
yann@1036
|
63 |
--- ltrace-0.5.orig/breakpoints.c 2006-06-14 06:55:21.000000000 +0200
|
yann@1036
|
64 |
+++ ltrace-0.5/breakpoints.c 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
65 |
@@ -53,6 +53,10 @@
|
yann@1036
|
66 |
if (libsym)
|
yann@1036
|
67 |
libsym->brkpnt = sbp;
|
yann@1036
|
68 |
}
|
yann@1036
|
69 |
+#ifdef __arm__
|
yann@1036
|
70 |
+ sbp->thumb_mode = proc->thumb_mode;
|
yann@1036
|
71 |
+ proc->thumb_mode = 0;
|
yann@1036
|
72 |
+#endif
|
yann@1036
|
73 |
sbp->enabled++;
|
yann@1036
|
74 |
if (sbp->enabled == 1 && proc->pid)
|
yann@1036
|
75 |
enable_breakpoint(proc->pid, sbp);
|
yann@1036
|
76 |
diff -durN ltrace-0.5.orig/elf.c ltrace-0.5/elf.c
|
yann@1036
|
77 |
--- ltrace-0.5.orig/elf.c 2006-06-14 06:55:21.000000000 +0200
|
yann@1036
|
78 |
+++ ltrace-0.5/elf.c 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
79 |
@@ -464,8 +464,7 @@
|
yann@1036
|
80 |
if (strcmp(xptr->name, PLTs_initialized_by_here) == 0) {
|
yann@1036
|
81 |
if (lte->ehdr.e_entry) {
|
yann@1036
|
82 |
add_library_symbol (
|
yann@1036
|
83 |
- elf_plt2addr (lte, (void*)(long)
|
yann@1036
|
84 |
- lte->ehdr.e_entry),
|
yann@1036
|
85 |
+ opd2addr (lte, lte->ehdr.e_entry),
|
yann@1036
|
86 |
PLTs_initialized_by_here,
|
yann@1036
|
87 |
lib_tail, 1, 0);
|
yann@1036
|
88 |
fprintf (stderr, "WARNING: Using e_ent"
|
yann@1036
|
89 |
diff -durN ltrace-0.5.orig/etc/ltrace.conf ltrace-0.5/etc/ltrace.conf
|
yann@1036
|
90 |
--- ltrace-0.5.orig/etc/ltrace.conf 2006-02-20 22:55:47.000000000 +0100
|
yann@1036
|
91 |
+++ ltrace-0.5/etc/ltrace.conf 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
92 |
@@ -444,3 +444,81 @@
|
yann@1036
|
93 |
int SYS_removexattr(string,string);
|
yann@1036
|
94 |
int SYS_lremovexattr(string,string);
|
yann@1036
|
95 |
int SYS_fremovexattr(int,string);
|
yann@1036
|
96 |
+int SYS_chdir(string);
|
yann@1036
|
97 |
+int SYS_fchdir(int);
|
yann@1036
|
98 |
+int SYS_chmod(string,octal);
|
yann@1036
|
99 |
+int SYS_fchmod(int,octal);
|
yann@1036
|
100 |
+int SYS_chown(string,int,int);
|
yann@1036
|
101 |
+int SYS_fchown(int,int,int);
|
yann@1036
|
102 |
+int SYS_lchown(string,int,int);
|
yann@1036
|
103 |
+int SYS_chroot(string);
|
yann@1036
|
104 |
+int SYS_dup(int);
|
yann@1036
|
105 |
+int SYS_dup2(int,int);
|
yann@1036
|
106 |
+int SYS_fdatasync(int);
|
yann@1036
|
107 |
+int SYS_fsync(int);
|
yann@1036
|
108 |
+int SYS_getpriority(int,int);
|
yann@1036
|
109 |
+int SYS_setpriority(int,int,int);
|
yann@1036
|
110 |
+int SYS_getrlimit(int,addr);
|
yann@1036
|
111 |
+int SYS_setrlimit(int,addr);
|
yann@1036
|
112 |
+int SYS_gettimeofday(addr,addr);
|
yann@1036
|
113 |
+int SYS_settimeofday(addr,addr);
|
yann@1036
|
114 |
+int SYS_setfsgid(int);
|
yann@1036
|
115 |
+int SYS_setfsuid(int);
|
yann@1036
|
116 |
+int SYS_getuid(void);
|
yann@1036
|
117 |
+int SYS_setuid(int);
|
yann@1036
|
118 |
+int SYS_getgid(void);
|
yann@1036
|
119 |
+int SYS_setgid(int);
|
yann@1036
|
120 |
+int SYS_getsid(int);
|
yann@1036
|
121 |
+int SYS_setsid(int);
|
yann@1036
|
122 |
+int SYS_setreuid(int,int);
|
yann@1036
|
123 |
+int SYS_setregid(int,int);
|
yann@1036
|
124 |
+int SYS_geteuid(void);
|
yann@1036
|
125 |
+int SYS_getegid(void);
|
yann@1036
|
126 |
+int SYS_setpgid(int,int);
|
yann@1036
|
127 |
+int SYS_getresuid(addr,addr,addr);
|
yann@1036
|
128 |
+int SYS_setresuid(int,int,int);
|
yann@1036
|
129 |
+int SYS_getresgid(addr,addr,addr);
|
yann@1036
|
130 |
+int SYS_setresgid(int,int,int);
|
yann@1036
|
131 |
+int SYS_kill(int,int);
|
yann@1036
|
132 |
+int SYS_link(string,string);
|
yann@1036
|
133 |
+int SYS_madvise(addr,ulong,int);
|
yann@1036
|
134 |
+int SYS_mkdir(string,octal);
|
yann@1036
|
135 |
+int SYS_mknod(string,octal,int);
|
yann@1036
|
136 |
+int SYS_msync(addr,ulong,int);
|
yann@1036
|
137 |
+int SYS_nice(int);
|
yann@1036
|
138 |
+int SYS_poll(addr,uint,int);
|
yann@1036
|
139 |
+int SYS_readdir(uint,addr,uint);
|
yann@1036
|
140 |
+int SYS_readlink(string,string,ulong);
|
yann@1036
|
141 |
+int SYS_reboot(int,int,int,addr);
|
yann@1036
|
142 |
+int SYS_rename(string,string);
|
yann@1036
|
143 |
+int SYS_rmdir(string);
|
yann@1036
|
144 |
+int SYS_sigaltstack(addr,addr);
|
yann@1036
|
145 |
+int SYS_statfs(string,addr);
|
yann@1036
|
146 |
+int SYS_fstatfs(int,addr);
|
yann@1036
|
147 |
+int SYS_fstat(int,addr);
|
yann@1036
|
148 |
+int SYS_lstat(string,addr);
|
yann@1036
|
149 |
+int SYS_stime(addr);
|
yann@1036
|
150 |
+int SYS_symlink(string, string);
|
yann@1036
|
151 |
+int SYS_sysinfo(addr);
|
yann@1036
|
152 |
+int SYS_syslog(int,string,int);
|
yann@1036
|
153 |
+int SYS_truncate(string,long);
|
yann@1036
|
154 |
+int SYS_ftruncate(int,long);
|
yann@1036
|
155 |
+int SYS_mount(string,string,string,ulong,addr);
|
yann@1036
|
156 |
+int SYS_umount(string);
|
yann@1036
|
157 |
+int SYS_umount2(string,int);
|
yann@1036
|
158 |
+int SYS_unlink(string);
|
yann@1036
|
159 |
+int SYS_utime(string,addr);
|
yann@1036
|
160 |
+long SYS_lseek(int,long,int);
|
yann@1036
|
161 |
+addr SYS_signal(int,addr);
|
yann@1036
|
162 |
+int SYS_sigaction(int,addr,addr);
|
yann@1036
|
163 |
+int SYS_pause(void);
|
yann@1036
|
164 |
+int SYS_sigpending(addr);
|
yann@1036
|
165 |
+int SYS_sigprocmask(int,addr,addr);
|
yann@1036
|
166 |
+int SYS_sigqueue(int,int,addr);
|
yann@1036
|
167 |
+int SYS_sigsuspend(addr);
|
yann@1036
|
168 |
+int SYS_wait(addr);
|
yann@1036
|
169 |
+int SYS_waitpid(int,addr,int);
|
yann@1036
|
170 |
+ulong SYS_readv(int,addr,int);
|
yann@1036
|
171 |
+ulong SYS_writev(int,addr,int);
|
yann@1036
|
172 |
+int SYS_mprotect(addr,int,int);
|
yann@1036
|
173 |
+int SYS_access(string,octal);
|
yann@1036
|
174 |
diff -durN ltrace-0.5.orig/ltrace.1 ltrace-0.5/ltrace.1
|
yann@1036
|
175 |
--- ltrace-0.5.orig/ltrace.1 2006-06-16 03:15:18.000000000 +0200
|
yann@1036
|
176 |
+++ ltrace-0.5/ltrace.1 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
177 |
@@ -30,7 +30,7 @@
|
yann@1036
|
178 |
.TP
|
yann@1036
|
179 |
.I \-C, \-\-demangle
|
yann@1036
|
180 |
Decode (demangle) low-level symbol names into user-level names.
|
yann@1036
|
181 |
-Besides removing any initial underscore prepended by the system,
|
yann@1036
|
182 |
+Besides removing any initial underscore prefix used by the system,
|
yann@1036
|
183 |
this makes C++ function names readable.
|
yann@1036
|
184 |
.TP
|
yann@1036
|
185 |
.I \-d, \-\-debug
|
yann@1036
|
186 |
diff -durN ltrace-0.5.orig/ltrace.c ltrace-0.5/ltrace.c
|
yann@1036
|
187 |
--- ltrace-0.5.orig/ltrace.c 2006-02-20 22:48:07.000000000 +0100
|
yann@1036
|
188 |
+++ ltrace-0.5/ltrace.c 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
189 |
@@ -54,6 +54,9 @@
|
yann@1036
|
190 |
{
|
yann@1036
|
191 |
exiting = 1;
|
yann@1036
|
192 |
debug(1, "Received interrupt signal; exiting...");
|
yann@1036
|
193 |
+ if (opt_o) {
|
yann@1036
|
194 |
+ fclose(output);
|
yann@1036
|
195 |
+ }
|
yann@1036
|
196 |
signal(SIGINT, SIG_IGN);
|
yann@1036
|
197 |
signal(SIGTERM, SIG_IGN);
|
yann@1036
|
198 |
signal(SIGALRM, signal_alarm);
|
yann@1036
|
199 |
@@ -74,6 +77,9 @@
|
yann@1036
|
200 |
if (opt_c) {
|
yann@1036
|
201 |
show_summary();
|
yann@1036
|
202 |
}
|
yann@1036
|
203 |
+ if (opt_o) {
|
yann@1036
|
204 |
+ fclose(output);
|
yann@1036
|
205 |
+ }
|
yann@1036
|
206 |
}
|
yann@1036
|
207 |
|
yann@1036
|
208 |
static void guess_cols(void)
|
yann@1036
|
209 |
diff -durN ltrace-0.5.orig/ltrace.h ltrace-0.5/ltrace.h
|
yann@1036
|
210 |
--- ltrace-0.5.orig/ltrace.h 2006-06-14 06:55:21.000000000 +0200
|
yann@1036
|
211 |
+++ ltrace-0.5/ltrace.h 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
212 |
@@ -26,6 +26,9 @@
|
yann@1036
|
213 |
unsigned char orig_value[BREAKPOINT_LENGTH];
|
yann@1036
|
214 |
int enabled;
|
yann@1036
|
215 |
struct library_symbol *libsym;
|
yann@1036
|
216 |
+#ifdef __arm__
|
yann@1036
|
217 |
+ int thumb_mode;
|
yann@1036
|
218 |
+#endif
|
yann@1036
|
219 |
};
|
yann@1036
|
220 |
|
yann@1036
|
221 |
enum arg_type {
|
yann@1036
|
222 |
@@ -119,6 +122,9 @@
|
yann@1036
|
223 |
void *arch_ptr;
|
yann@1036
|
224 |
short e_machine;
|
yann@1036
|
225 |
short need_to_reinitialize_breakpoints;
|
yann@1036
|
226 |
+#ifdef __arm__
|
yann@1036
|
227 |
+ int thumb_mode; /* ARM execution mode: 0: ARM mode, 1: Thumb mode */
|
yann@1036
|
228 |
+#endif
|
yann@1036
|
229 |
|
yann@1036
|
230 |
/* output: */
|
yann@1036
|
231 |
enum tof type_being_displayed;
|
yann@1036
|
232 |
@@ -136,12 +142,14 @@
|
yann@1036
|
233 |
LT_EV_EXIT_SIGNAL,
|
yann@1036
|
234 |
LT_EV_SYSCALL,
|
yann@1036
|
235 |
LT_EV_SYSRET,
|
yann@1036
|
236 |
+ LT_EV_ARCH_SYSCALL,
|
yann@1036
|
237 |
+ LT_EV_ARCH_SYSRET,
|
yann@1036
|
238 |
LT_EV_BREAKPOINT
|
yann@1036
|
239 |
} thing;
|
yann@1036
|
240 |
union {
|
yann@1036
|
241 |
int ret_val; /* _EV_EXIT */
|
yann@1036
|
242 |
int signum; /* _EV_SIGNAL, _EV_EXIT_SIGNAL */
|
yann@1036
|
243 |
- int sysnum; /* _EV_SYSCALL, _EV_SYSRET */
|
yann@1036
|
244 |
+ int sysnum; /* _EV_SYSCALL, _EV_SYSRET, _EV_ARCH_SYSCALL, _EV_ARCH_SYSRET */
|
yann@1036
|
245 |
void *brk_addr; /* _EV_BREAKPOINT */
|
yann@1036
|
246 |
} e_un;
|
yann@1036
|
247 |
};
|
yann@1036
|
248 |
diff -durN ltrace-0.5.orig/options.c ltrace-0.5/options.c
|
yann@1036
|
249 |
--- ltrace-0.5.orig/options.c 2006-04-24 22:06:23.000000000 +0200
|
yann@1036
|
250 |
+++ ltrace-0.5/options.c 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
251 |
@@ -42,6 +42,7 @@
|
yann@1036
|
252 |
#endif
|
yann@1036
|
253 |
int opt_n = 0; /* indent trace output according to program flow */
|
yann@1036
|
254 |
int opt_T = 0; /* show the time spent inside each call */
|
yann@1036
|
255 |
+int opt_o = 0; /* output to a specific file */
|
yann@1036
|
256 |
|
yann@1036
|
257 |
/* List of pids given to option -p: */
|
yann@1036
|
258 |
struct opt_p_t *opt_p = NULL; /* attach to process with a given pid */
|
yann@1036
|
259 |
@@ -274,6 +275,7 @@
|
yann@1036
|
260 |
opt_n = atoi(optarg);
|
yann@1036
|
261 |
break;
|
yann@1036
|
262 |
case 'o':
|
yann@1036
|
263 |
+ opt_o++;
|
yann@1036
|
264 |
output = fopen(optarg, "w");
|
yann@1036
|
265 |
if (!output) {
|
yann@1036
|
266 |
fprintf(stderr,
|
yann@1036
|
267 |
diff -durN ltrace-0.5.orig/options.h ltrace-0.5/options.h
|
yann@1036
|
268 |
--- ltrace-0.5.orig/options.h 2006-03-13 18:43:13.000000000 +0100
|
yann@1036
|
269 |
+++ ltrace-0.5/options.h 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
270 |
@@ -20,6 +20,7 @@
|
yann@1036
|
271 |
extern int opt_C; /* Demanglelow-level symbol names into user-level names */
|
yann@1036
|
272 |
extern int opt_n; /* indent trace output according to program flow */
|
yann@1036
|
273 |
extern int opt_T; /* show the time spent inside each call */
|
yann@1036
|
274 |
+extern int opt_o; /* output to a specific file */
|
yann@1036
|
275 |
|
yann@1036
|
276 |
struct opt_p_t {
|
yann@1036
|
277 |
pid_t pid;
|
yann@1036
|
278 |
diff -durN ltrace-0.5.orig/process_event.c ltrace-0.5/process_event.c
|
yann@1036
|
279 |
--- ltrace-0.5.orig/process_event.c 2006-06-14 06:55:21.000000000 +0200
|
yann@1036
|
280 |
+++ ltrace-0.5/process_event.c 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
281 |
@@ -24,7 +24,9 @@
|
yann@1036
|
282 |
static void process_exit(struct event *event);
|
yann@1036
|
283 |
static void process_exit_signal(struct event *event);
|
yann@1036
|
284 |
static void process_syscall(struct event *event);
|
yann@1036
|
285 |
+static void process_arch_syscall(struct event *event);
|
yann@1036
|
286 |
static void process_sysret(struct event *event);
|
yann@1036
|
287 |
+static void process_arch_sysret(struct event *event);
|
yann@1036
|
288 |
static void process_breakpoint(struct event *event);
|
yann@1036
|
289 |
static void remove_proc(struct process *proc);
|
yann@1036
|
290 |
|
yann@1036
|
291 |
@@ -81,6 +83,24 @@
|
yann@1036
|
292 |
}
|
yann@1036
|
293 |
}
|
yann@1036
|
294 |
|
yann@1036
|
295 |
+static char *arch_sysname(struct process *proc, int sysnum)
|
yann@1036
|
296 |
+{
|
yann@1036
|
297 |
+ static char result[128];
|
yann@1036
|
298 |
+ static char *arch_syscalent[] = {
|
yann@1036
|
299 |
+#include "arch_syscallent.h"
|
yann@1036
|
300 |
+ };
|
yann@1036
|
301 |
+ int nsyscals = sizeof arch_syscalent / sizeof arch_syscalent[0];
|
yann@1036
|
302 |
+
|
yann@1036
|
303 |
+ if (sysnum < 0 || sysnum >= nsyscals) {
|
yann@1036
|
304 |
+ sprintf(result, "ARCH_%d", sysnum);
|
yann@1036
|
305 |
+ return result;
|
yann@1036
|
306 |
+ } else {
|
yann@1036
|
307 |
+ sprintf(result, "ARCH_%s",
|
yann@1036
|
308 |
+ arch_syscalent[sysnum]);
|
yann@1036
|
309 |
+ return result;
|
yann@1036
|
310 |
+ }
|
yann@1036
|
311 |
+}
|
yann@1036
|
312 |
+
|
yann@1036
|
313 |
void process_event(struct event *event)
|
yann@1036
|
314 |
{
|
yann@1036
|
315 |
switch (event->thing) {
|
yann@1036
|
316 |
@@ -115,6 +135,18 @@
|
yann@1036
|
317 |
event->e_un.sysnum);
|
yann@1036
|
318 |
process_sysret(event);
|
yann@1036
|
319 |
return;
|
yann@1036
|
320 |
+ case LT_EV_ARCH_SYSCALL:
|
yann@1036
|
321 |
+ debug(1, "event: arch_syscall (%s [%d])",
|
yann@1036
|
322 |
+ arch_sysname(event->proc, event->e_un.sysnum),
|
yann@1036
|
323 |
+ event->e_un.sysnum);
|
yann@1036
|
324 |
+ process_arch_syscall(event);
|
yann@1036
|
325 |
+ return;
|
yann@1036
|
326 |
+ case LT_EV_ARCH_SYSRET:
|
yann@1036
|
327 |
+ debug(1, "event: arch_sysret (%s [%d])",
|
yann@1036
|
328 |
+ arch_sysname(event->proc, event->e_un.sysnum),
|
yann@1036
|
329 |
+ event->e_un.sysnum);
|
yann@1036
|
330 |
+ process_arch_sysret(event);
|
yann@1036
|
331 |
+ return;
|
yann@1036
|
332 |
case LT_EV_BREAKPOINT:
|
yann@1036
|
333 |
debug(1, "event: breakpoint");
|
yann@1036
|
334 |
process_breakpoint(event);
|
yann@1036
|
335 |
@@ -195,6 +227,19 @@
|
yann@1036
|
336 |
continue_process(event->proc->pid);
|
yann@1036
|
337 |
}
|
yann@1036
|
338 |
|
yann@1036
|
339 |
+static void process_arch_syscall(struct event *event)
|
yann@1036
|
340 |
+{
|
yann@1036
|
341 |
+ if (opt_S) {
|
yann@1036
|
342 |
+ output_left(LT_TOF_SYSCALL, event->proc,
|
yann@1036
|
343 |
+ arch_sysname(event->proc, event->e_un.sysnum));
|
yann@1036
|
344 |
+ }
|
yann@1036
|
345 |
+ if (event->proc->breakpoints_enabled == 0) {
|
yann@1036
|
346 |
+ enable_all_breakpoints(event->proc);
|
yann@1036
|
347 |
+ }
|
yann@1036
|
348 |
+ callstack_push_syscall(event->proc, 0xf0000 + event->e_un.sysnum);
|
yann@1036
|
349 |
+ continue_process(event->proc->pid);
|
yann@1036
|
350 |
+}
|
yann@1036
|
351 |
+
|
yann@1036
|
352 |
struct timeval current_time_spent;
|
yann@1036
|
353 |
|
yann@1036
|
354 |
static void calc_time_spent(struct process *proc)
|
yann@1036
|
355 |
@@ -257,6 +302,19 @@
|
yann@1036
|
356 |
continue_process(event->proc->pid);
|
yann@1036
|
357 |
}
|
yann@1036
|
358 |
|
yann@1036
|
359 |
+static void process_arch_sysret(struct event *event)
|
yann@1036
|
360 |
+{
|
yann@1036
|
361 |
+ if (opt_T || opt_c) {
|
yann@1036
|
362 |
+ calc_time_spent(event->proc);
|
yann@1036
|
363 |
+ }
|
yann@1036
|
364 |
+ callstack_pop(event->proc);
|
yann@1036
|
365 |
+ if (opt_S) {
|
yann@1036
|
366 |
+ output_right(LT_TOF_SYSCALLR, event->proc,
|
yann@1036
|
367 |
+ arch_sysname(event->proc, event->e_un.sysnum));
|
yann@1036
|
368 |
+ }
|
yann@1036
|
369 |
+ continue_process(event->proc->pid);
|
yann@1036
|
370 |
+}
|
yann@1036
|
371 |
+
|
yann@1036
|
372 |
static void process_breakpoint(struct event *event)
|
yann@1036
|
373 |
{
|
yann@1036
|
374 |
int i, j;
|
yann@1036
|
375 |
diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/Makefile ltrace-0.5/sysdeps/linux-gnu/Makefile
|
yann@1036
|
376 |
--- ltrace-0.5.orig/sysdeps/linux-gnu/Makefile 2008-11-04 19:25:11.000000000 +0100
|
yann@1036
|
377 |
+++ ltrace-0.5/sysdeps/linux-gnu/Makefile 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
378 |
@@ -2,7 +2,7 @@
|
yann@1036
|
379 |
|
yann@1036
|
380 |
OBJ = trace.o proc.o breakpoint.o
|
yann@1036
|
381 |
|
yann@1036
|
382 |
-all: sysdep.h signalent.h syscallent.h signalent1.h syscallent1.h ../sysdep.o
|
yann@1036
|
383 |
+all: sysdep.h signalent.h syscallent.h arch_syscallent.h signalent1.h syscallent1.h ../sysdep.o
|
yann@1036
|
384 |
|
yann@1036
|
385 |
sysdep.h: $(ARCH)/arch.h
|
yann@1036
|
386 |
cat $(ARCH)/arch.h > sysdep.h
|
yann@1036
|
387 |
@@ -26,6 +26,13 @@
|
yann@1036
|
388 |
> syscallent1.h; \
|
yann@1036
|
389 |
fi
|
yann@1036
|
390 |
|
yann@1036
|
391 |
+arch_syscallent.h:
|
yann@1036
|
392 |
+ if [ -f $(ARCH)/arch_syscallent.h ]; then \
|
yann@1036
|
393 |
+ cp $(ARCH)/arch_syscallent.h arch_syscallent.h; \
|
yann@1036
|
394 |
+ else \
|
yann@1036
|
395 |
+ > arch_syscallent.h; \
|
yann@1036
|
396 |
+ fi
|
yann@1036
|
397 |
+
|
yann@1036
|
398 |
../sysdep.o: os.o $(ARCH)/arch.o
|
yann@1036
|
399 |
$(CC) -nostdlib -r -o ../sysdep.o os.o $(ARCH)/arch.o
|
yann@1036
|
400 |
|
yann@1036
|
401 |
@@ -37,7 +44,7 @@
|
yann@1036
|
402 |
|
yann@1036
|
403 |
clean:
|
yann@1036
|
404 |
$(MAKE) -C $(ARCH) clean
|
yann@1036
|
405 |
- rm -f $(OBJ) sysdep.h signalent.h signalent1.h syscallent.h
|
yann@1036
|
406 |
+ rm -f $(OBJ) sysdep.h signalent.h signalent1.h syscallent.h arch_syscallent.h
|
yann@1036
|
407 |
rm -f syscallent1.h os.o sysdep.o ../sysdep.o
|
yann@1036
|
408 |
|
yann@1036
|
409 |
dummy:
|
yann@1036
|
410 |
diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arch_mksyscallent ltrace-0.5/sysdeps/linux-gnu/arch_mksyscallent
|
yann@1036
|
411 |
--- ltrace-0.5.orig/sysdeps/linux-gnu/arch_mksyscallent 1970-01-01 01:00:00.000000000 +0100
|
yann@1036
|
412 |
+++ ltrace-0.5/sysdeps/linux-gnu/arch_mksyscallent 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
413 |
@@ -0,0 +1,43 @@
|
yann@1036
|
414 |
+#!/usr/bin/awk -f
|
yann@1036
|
415 |
+
|
yann@1036
|
416 |
+# hack expression to generate arch_syscallent.h from <asm/unistd.h>
|
yann@1036
|
417 |
+# It reads from stdin and writes to stdout
|
yann@1036
|
418 |
+# Currently (linux-2.6.16), it works OK on arm
|
yann@1036
|
419 |
+# It is untested in other architectures
|
yann@1036
|
420 |
+
|
yann@1036
|
421 |
+BEGIN {
|
yann@1036
|
422 |
+ max=0;
|
yann@1036
|
423 |
+ FS="[ \t\n()+]+";
|
yann@1036
|
424 |
+}
|
yann@1036
|
425 |
+
|
yann@1036
|
426 |
+{
|
yann@1036
|
427 |
+# printf("/%s/%s/%s/%s/\n", $1, $2, $3, $4);
|
yann@1036
|
428 |
+ if (($1 ~ /^#define$/) && ($2 ~ /^__[A-Z]+_NR_/)) {
|
yann@1036
|
429 |
+ sub(/^__[A-Z]+_NR_/,"",$2);
|
yann@1036
|
430 |
+ if (($3>=0) && ($3<=1000)) {
|
yann@1036
|
431 |
+ SYSCALL[$3]=$2;
|
yann@1036
|
432 |
+ if ($3 > max) {
|
yann@1036
|
433 |
+ max=$3;
|
yann@1036
|
434 |
+ }
|
yann@1036
|
435 |
+ } else if (($3 ~ /^__[A-Z]+_NR_BASE$/) && ($4>=0) && ($4<=1000)) {
|
yann@1036
|
436 |
+ SYSCALL[$4]=$2;
|
yann@1036
|
437 |
+ if ($4 > max) {
|
yann@1036
|
438 |
+ max=$4;
|
yann@1036
|
439 |
+ }
|
yann@1036
|
440 |
+ }
|
yann@1036
|
441 |
+ }
|
yann@1036
|
442 |
+}
|
yann@1036
|
443 |
+
|
yann@1036
|
444 |
+END {
|
yann@1036
|
445 |
+ for(i=0; i<=max; i++) {
|
yann@1036
|
446 |
+ if (!SYSCALL[i]) {
|
yann@1036
|
447 |
+ SYSCALL[i] = i;
|
yann@1036
|
448 |
+ }
|
yann@1036
|
449 |
+ pad = 32 - length(SYSCALL[i]);
|
yann@1036
|
450 |
+ if (pad<1) {
|
yann@1036
|
451 |
+ pad=1;
|
yann@1036
|
452 |
+ }
|
yann@1036
|
453 |
+ printf("\t\"%s\",%*s/* %d */\n", SYSCALL[i], pad, "", i);
|
yann@1036
|
454 |
+ }
|
yann@1036
|
455 |
+}
|
yann@1036
|
456 |
+
|
yann@1036
|
457 |
diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/Makefile ltrace-0.5/sysdeps/linux-gnu/arm/Makefile
|
yann@1036
|
458 |
--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/Makefile 2006-02-20 22:44:45.000000000 +0100
|
yann@1036
|
459 |
+++ ltrace-0.5/sysdeps/linux-gnu/arm/Makefile 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
460 |
@@ -1,4 +1,4 @@
|
yann@1036
|
461 |
-OBJ = trace.o regs.o plt.o
|
yann@1036
|
462 |
+OBJ = trace.o regs.o plt.o breakpoint.o
|
yann@1036
|
463 |
|
yann@1036
|
464 |
all: arch.o
|
yann@1036
|
465 |
|
yann@1036
|
466 |
diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/arch.h ltrace-0.5/sysdeps/linux-gnu/arm/arch.h
|
yann@1036
|
467 |
--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/arch.h 2006-04-24 22:06:23.000000000 +0200
|
yann@1036
|
468 |
+++ ltrace-0.5/sysdeps/linux-gnu/arm/arch.h 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
469 |
@@ -1,5 +1,10 @@
|
yann@1036
|
470 |
-#define BREAKPOINT_VALUE { 0x01, 0x00, 0x9f, 0xef }
|
yann@1036
|
471 |
+#define ARCH_HAVE_ENABLE_BREAKPOINT 1
|
yann@1036
|
472 |
+#define ARCH_HAVE_DISABLE_BREAKPOINT 1
|
yann@1036
|
473 |
+
|
yann@1036
|
474 |
+#define BREAKPOINT_VALUE { 0xf0, 0x01, 0xf0, 0xe7 }
|
yann@1036
|
475 |
#define BREAKPOINT_LENGTH 4
|
yann@1036
|
476 |
+#define THUMB_BREAKPOINT_VALUE { 0x01, 0xde }
|
yann@1036
|
477 |
+#define THUMB_BREAKPOINT_LENGTH 2
|
yann@1036
|
478 |
#define DECR_PC_AFTER_BREAK 0
|
yann@1036
|
479 |
|
yann@1036
|
480 |
#define LT_ELFCLASS ELFCLASS32
|
yann@1036
|
481 |
diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/arch_syscallent.h ltrace-0.5/sysdeps/linux-gnu/arm/arch_syscallent.h
|
yann@1036
|
482 |
--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/arch_syscallent.h 1970-01-01 01:00:00.000000000 +0100
|
yann@1036
|
483 |
+++ ltrace-0.5/sysdeps/linux-gnu/arm/arch_syscallent.h 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
484 |
@@ -0,0 +1,6 @@
|
yann@1036
|
485 |
+ "0", /* 0 */
|
yann@1036
|
486 |
+ "breakpoint", /* 1 */
|
yann@1036
|
487 |
+ "cacheflush", /* 2 */
|
yann@1036
|
488 |
+ "usr26", /* 3 */
|
yann@1036
|
489 |
+ "usr32", /* 4 */
|
yann@1036
|
490 |
+ "set_tls", /* 5 */
|
yann@1036
|
491 |
diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/breakpoint.c ltrace-0.5/sysdeps/linux-gnu/arm/breakpoint.c
|
yann@1036
|
492 |
--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/breakpoint.c 1970-01-01 01:00:00.000000000 +0100
|
yann@1036
|
493 |
+++ ltrace-0.5/sysdeps/linux-gnu/arm/breakpoint.c 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
494 |
@@ -0,0 +1,86 @@
|
yann@1036
|
495 |
+/*
|
yann@1036
|
496 |
+ * This file is part of ltrace.
|
yann@1036
|
497 |
+ *
|
yann@1036
|
498 |
+ * Copyright (C) 2007 by Instituto Nokia de Tecnologia (INdT)
|
yann@1036
|
499 |
+ *
|
yann@1036
|
500 |
+ * Author: Anderson Lizardo <anderson.lizardo@indt.org.br>
|
yann@1036
|
501 |
+ *
|
yann@1036
|
502 |
+ * This program is free software; you can redistribute it and/or
|
yann@1036
|
503 |
+ * modify it under the terms of the GNU General Public License
|
yann@1036
|
504 |
+ * version 2 as published by the Free Software Foundation.
|
yann@1036
|
505 |
+ *
|
yann@1036
|
506 |
+ * This program is distributed in the hope that it will be useful, but
|
yann@1036
|
507 |
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
yann@1036
|
508 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yann@1036
|
509 |
+ * General Public License for more details.
|
yann@1036
|
510 |
+ *
|
yann@1036
|
511 |
+ * You should have received a copy of the GNU General Public License
|
yann@1036
|
512 |
+ * along with this program; if not, write to the Free Software
|
yann@1036
|
513 |
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
yann@1036
|
514 |
+ * 02110-1301 USA
|
yann@1036
|
515 |
+ *
|
yann@1036
|
516 |
+ * Modified from sysdeps/linux-gnu/breakpoint.c and added ARM Thumb support.
|
yann@1036
|
517 |
+*/
|
yann@1036
|
518 |
+
|
yann@1036
|
519 |
+#include <sys/ptrace.h>
|
yann@1036
|
520 |
+#include "config.h"
|
yann@1036
|
521 |
+#include "arch.h"
|
yann@1036
|
522 |
+#include "options.h"
|
yann@1036
|
523 |
+#include "output.h"
|
yann@1036
|
524 |
+#include "debug.h"
|
yann@1036
|
525 |
+
|
yann@1036
|
526 |
+void arch_enable_breakpoint(pid_t pid, struct breakpoint *sbp)
|
yann@1036
|
527 |
+{
|
yann@1036
|
528 |
+ unsigned int i, j;
|
yann@1036
|
529 |
+ const unsigned char break_insn[] = BREAKPOINT_VALUE;
|
yann@1036
|
530 |
+ const unsigned char thumb_break_insn[] = THUMB_BREAKPOINT_VALUE;
|
yann@1036
|
531 |
+
|
yann@1036
|
532 |
+ debug(1, "arch_enable_breakpoint(%d,%p)", pid, sbp->addr);
|
yann@1036
|
533 |
+
|
yann@1036
|
534 |
+ for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
|
yann@1036
|
535 |
+ long a =
|
yann@1036
|
536 |
+ ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
|
yann@1036
|
537 |
+ 0);
|
yann@1036
|
538 |
+ unsigned char *bytes = (unsigned char *)&a;
|
yann@1036
|
539 |
+
|
yann@1036
|
540 |
+ debug(2, "current = 0x%lx, orig_value = 0x%lx, thumb_mode = %d", a, *(long *)&sbp->orig_value, sbp->thumb_mode);
|
yann@1036
|
541 |
+ for (j = 0;
|
yann@1036
|
542 |
+ j < sizeof(long)
|
yann@1036
|
543 |
+ && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
|
yann@1036
|
544 |
+
|
yann@1036
|
545 |
+ sbp->orig_value[i * sizeof(long) + j] = bytes[j];
|
yann@1036
|
546 |
+ if (!sbp->thumb_mode) {
|
yann@1036
|
547 |
+ bytes[j] = break_insn[i * sizeof(long) + j];
|
yann@1036
|
548 |
+ }
|
yann@1036
|
549 |
+ else if (j < THUMB_BREAKPOINT_LENGTH) {
|
yann@1036
|
550 |
+ bytes[j] = thumb_break_insn[i * sizeof(long) + j];
|
yann@1036
|
551 |
+ }
|
yann@1036
|
552 |
+ }
|
yann@1036
|
553 |
+ ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
|
yann@1036
|
554 |
+ }
|
yann@1036
|
555 |
+}
|
yann@1036
|
556 |
+
|
yann@1036
|
557 |
+void arch_disable_breakpoint(pid_t pid, const struct breakpoint *sbp)
|
yann@1036
|
558 |
+{
|
yann@1036
|
559 |
+ unsigned int i, j;
|
yann@1036
|
560 |
+ const unsigned char break_insn[] = BREAKPOINT_VALUE;
|
yann@1036
|
561 |
+ const unsigned char thumb_break_insn[] = THUMB_BREAKPOINT_VALUE;
|
yann@1036
|
562 |
+
|
yann@1036
|
563 |
+ debug(1, "arch_disable_breakpoint(%d,%p)", pid, sbp->addr);
|
yann@1036
|
564 |
+
|
yann@1036
|
565 |
+ for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
|
yann@1036
|
566 |
+ long a =
|
yann@1036
|
567 |
+ ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
|
yann@1036
|
568 |
+ 0);
|
yann@1036
|
569 |
+ unsigned char *bytes = (unsigned char *)&a;
|
yann@1036
|
570 |
+
|
yann@1036
|
571 |
+ debug(2, "current = 0x%lx, orig_value = 0x%lx, thumb_mode = %d", a, *(long *)&sbp->orig_value, sbp->thumb_mode);
|
yann@1036
|
572 |
+ for (j = 0;
|
yann@1036
|
573 |
+ j < sizeof(long)
|
yann@1036
|
574 |
+ && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
|
yann@1036
|
575 |
+
|
yann@1036
|
576 |
+ bytes[j] = sbp->orig_value[i * sizeof(long) + j];
|
yann@1036
|
577 |
+ }
|
yann@1036
|
578 |
+ ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
|
yann@1036
|
579 |
+ }
|
yann@1036
|
580 |
+}
|
yann@1036
|
581 |
diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/ptrace.h ltrace-0.5/sysdeps/linux-gnu/arm/ptrace.h
|
yann@1036
|
582 |
--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/ptrace.h 2006-02-20 22:44:45.000000000 +0100
|
yann@1036
|
583 |
+++ ltrace-0.5/sysdeps/linux-gnu/arm/ptrace.h 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
584 |
@@ -1 +1,9 @@
|
yann@1036
|
585 |
#include <sys/ptrace.h>
|
yann@1036
|
586 |
+#include <asm/ptrace.h>
|
yann@1036
|
587 |
+
|
yann@1036
|
588 |
+typedef struct {
|
yann@1036
|
589 |
+ int valid;
|
yann@1036
|
590 |
+ struct pt_regs regs;
|
yann@1036
|
591 |
+ long func_arg[5];
|
yann@1036
|
592 |
+ long sysc_arg[5];
|
yann@1036
|
593 |
+} proc_archdep;
|
yann@1036
|
594 |
diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/regs.c ltrace-0.5/sysdeps/linux-gnu/arm/regs.c
|
yann@1036
|
595 |
--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/regs.c 2006-02-20 22:48:07.000000000 +0100
|
yann@1036
|
596 |
+++ ltrace-0.5/sysdeps/linux-gnu/arm/regs.c 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
597 |
@@ -39,5 +39,10 @@
|
yann@1036
|
598 |
* a CISC architecture; in our case, we don't need that */
|
yann@1036
|
599 |
void *get_return_addr(struct process *proc, void *stack_pointer)
|
yann@1036
|
600 |
{
|
yann@1036
|
601 |
- return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_lr, 0);
|
yann@1036
|
602 |
+ long addr = ptrace(PTRACE_PEEKUSER, proc->pid, off_lr, 0);
|
yann@1036
|
603 |
+
|
yann@1036
|
604 |
+ proc->thumb_mode = addr & 1;
|
yann@1036
|
605 |
+ if (proc->thumb_mode)
|
yann@1036
|
606 |
+ addr &= ~1;
|
yann@1036
|
607 |
+ return (void *)addr;
|
yann@1036
|
608 |
}
|
yann@1036
|
609 |
diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/arm/trace.c ltrace-0.5/sysdeps/linux-gnu/arm/trace.c
|
yann@1036
|
610 |
--- ltrace-0.5.orig/sysdeps/linux-gnu/arm/trace.c 2006-02-20 22:48:07.000000000 +0100
|
yann@1036
|
611 |
+++ ltrace-0.5/sysdeps/linux-gnu/arm/trace.c 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
612 |
@@ -2,6 +2,7 @@
|
yann@1036
|
613 |
#include "config.h"
|
yann@1036
|
614 |
#endif
|
yann@1036
|
615 |
|
yann@1036
|
616 |
+#include <string.h>
|
yann@1036
|
617 |
#include <sys/types.h>
|
yann@1036
|
618 |
#include <sys/wait.h>
|
yann@1036
|
619 |
#include <signal.h>
|
yann@1036
|
620 |
@@ -9,6 +10,8 @@
|
yann@1036
|
621 |
#include <asm/ptrace.h>
|
yann@1036
|
622 |
|
yann@1036
|
623 |
#include "ltrace.h"
|
yann@1036
|
624 |
+#include "output.h"
|
yann@1036
|
625 |
+#include "ptrace.h"
|
yann@1036
|
626 |
|
yann@1036
|
627 |
#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
|
yann@1036
|
628 |
# define PTRACE_PEEKUSER PTRACE_PEEKUSR
|
yann@1036
|
629 |
@@ -18,19 +21,25 @@
|
yann@1036
|
630 |
# define PTRACE_POKEUSER PTRACE_POKEUSR
|
yann@1036
|
631 |
#endif
|
yann@1036
|
632 |
|
yann@1036
|
633 |
-/* syscall tracing protocol: ArmLinux
|
yann@1036
|
634 |
- on the way in, ip is 0
|
yann@1036
|
635 |
- on the way out, ip is non-zero
|
yann@1036
|
636 |
-*/
|
yann@1036
|
637 |
#define off_r0 0
|
yann@1036
|
638 |
+#define off_r7 28
|
yann@1036
|
639 |
#define off_ip 48
|
yann@1036
|
640 |
#define off_pc 60
|
yann@1036
|
641 |
|
yann@1036
|
642 |
void get_arch_dep(struct process *proc)
|
yann@1036
|
643 |
{
|
yann@1036
|
644 |
+ proc_archdep *a;
|
yann@1036
|
645 |
+
|
yann@1036
|
646 |
+ if (!proc->arch_ptr)
|
yann@1036
|
647 |
+ proc->arch_ptr = (void *)malloc(sizeof(proc_archdep));
|
yann@1036
|
648 |
+ a = (proc_archdep *) (proc->arch_ptr);
|
yann@1036
|
649 |
+ a->valid = (ptrace(PTRACE_GETREGS, proc->pid, 0, &a->regs) >= 0);
|
yann@1036
|
650 |
}
|
yann@1036
|
651 |
|
yann@1036
|
652 |
-/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
|
yann@1036
|
653 |
+/* Returns 0 if not a syscall,
|
yann@1036
|
654 |
+ * 1 if syscall entry, 2 if syscall exit,
|
yann@1036
|
655 |
+ * 3 if arch-specific syscall entry, 4 if arch-specific syscall exit,
|
yann@1036
|
656 |
+ * -1 on error.
|
yann@1036
|
657 |
*/
|
yann@1036
|
658 |
int syscall_p(struct process *proc, int status, int *sysnum)
|
yann@1036
|
659 |
{
|
yann@1036
|
660 |
@@ -40,19 +49,39 @@
|
yann@1036
|
661 |
int pc = ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0);
|
yann@1036
|
662 |
/* fetch the SWI instruction */
|
yann@1036
|
663 |
int insn = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 4, 0);
|
yann@1036
|
664 |
+ int ip = ptrace(PTRACE_PEEKUSER, proc->pid, off_ip, 0);
|
yann@1036
|
665 |
|
yann@1036
|
666 |
- *sysnum = insn & 0xFFFF;
|
yann@1036
|
667 |
- /* if it is a syscall, return 1 or 2 */
|
yann@1036
|
668 |
- if ((insn & 0xFFFF0000) == 0xef900000) {
|
yann@1036
|
669 |
- return ptrace(PTRACE_PEEKUSER, proc->pid, off_ip,
|
yann@1036
|
670 |
- 0) ? 2 : 1;
|
yann@1036
|
671 |
+ if (insn == 0xef000000 || insn == 0x0f000000) {
|
yann@1036
|
672 |
+ /* EABI syscall */
|
yann@1036
|
673 |
+ *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, off_r7, 0);
|
yann@1036
|
674 |
+ } else if ((insn & 0xfff00000) == 0xef900000) {
|
yann@1036
|
675 |
+ /* old ABI syscall */
|
yann@1036
|
676 |
+ *sysnum = insn & 0xfffff;
|
yann@1036
|
677 |
+ } else {
|
yann@1036
|
678 |
+ /* TODO: handle swi<cond> variations */
|
yann@1036
|
679 |
+ /* one possible reason for getting in here is that we
|
yann@1036
|
680 |
+ * are coming from a signal handler, so the current
|
yann@1036
|
681 |
+ * PC does not point to the instruction just after the
|
yann@1036
|
682 |
+ * "swi" one. */
|
yann@1036
|
683 |
+ output_line(proc, "unexpected instruction 0x%x at %p", insn, pc - 4);
|
yann@1036
|
684 |
+ return -1;
|
yann@1036
|
685 |
+ }
|
yann@1036
|
686 |
+ if ((*sysnum & 0xf0000) == 0xf0000) {
|
yann@1036
|
687 |
+ /* arch-specific syscall */
|
yann@1036
|
688 |
+ *sysnum &= ~0xf0000;
|
yann@1036
|
689 |
+ return ip ? 4 : 3;
|
yann@1036
|
690 |
}
|
yann@1036
|
691 |
+ /* ARM syscall convention: on syscall entry, ip is zero;
|
yann@1036
|
692 |
+ * on syscall exit, ip is non-zero */
|
yann@1036
|
693 |
+ return ip ? 2 : 1;
|
yann@1036
|
694 |
}
|
yann@1036
|
695 |
return 0;
|
yann@1036
|
696 |
}
|
yann@1036
|
697 |
|
yann@1036
|
698 |
long gimme_arg(enum tof type, struct process *proc, int arg_num)
|
yann@1036
|
699 |
{
|
yann@1036
|
700 |
+ proc_archdep *a = (proc_archdep *) proc->arch_ptr;
|
yann@1036
|
701 |
+
|
yann@1036
|
702 |
if (arg_num == -1) { /* return value */
|
yann@1036
|
703 |
return ptrace(PTRACE_PEEKUSER, proc->pid, off_r0, 0);
|
yann@1036
|
704 |
}
|
yann@1036
|
705 |
@@ -60,6 +89,10 @@
|
yann@1036
|
706 |
/* deal with the ARM calling conventions */
|
yann@1036
|
707 |
if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) {
|
yann@1036
|
708 |
if (arg_num < 4) {
|
yann@1036
|
709 |
+ if (a->valid && type == LT_TOF_FUNCTION)
|
yann@1036
|
710 |
+ return a->regs.uregs[arg_num];
|
yann@1036
|
711 |
+ if (a->valid && type == LT_TOF_FUNCTIONR)
|
yann@1036
|
712 |
+ return a->func_arg[arg_num];
|
yann@1036
|
713 |
return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num,
|
yann@1036
|
714 |
0);
|
yann@1036
|
715 |
} else {
|
yann@1036
|
716 |
@@ -69,6 +102,10 @@
|
yann@1036
|
717 |
}
|
yann@1036
|
718 |
} else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) {
|
yann@1036
|
719 |
if (arg_num < 5) {
|
yann@1036
|
720 |
+ if (a->valid && type == LT_TOF_SYSCALL)
|
yann@1036
|
721 |
+ return a->regs.uregs[arg_num];
|
yann@1036
|
722 |
+ if (a->valid && type == LT_TOF_SYSCALLR)
|
yann@1036
|
723 |
+ return a->sysc_arg[arg_num];
|
yann@1036
|
724 |
return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num,
|
yann@1036
|
725 |
0);
|
yann@1036
|
726 |
} else {
|
yann@1036
|
727 |
@@ -86,4 +123,11 @@
|
yann@1036
|
728 |
|
yann@1036
|
729 |
void save_register_args(enum tof type, struct process *proc)
|
yann@1036
|
730 |
{
|
yann@1036
|
731 |
+ proc_archdep *a = (proc_archdep *) proc->arch_ptr;
|
yann@1036
|
732 |
+ if (a->valid) {
|
yann@1036
|
733 |
+ if (type == LT_TOF_FUNCTION)
|
yann@1036
|
734 |
+ memcpy(a->func_arg, a->regs.uregs, sizeof(a->func_arg));
|
yann@1036
|
735 |
+ else
|
yann@1036
|
736 |
+ memcpy(a->sysc_arg, a->regs.uregs, sizeof(a->sysc_arg));
|
yann@1036
|
737 |
+ }
|
yann@1036
|
738 |
}
|
yann@1036
|
739 |
diff -durN ltrace-0.5.orig/sysdeps/linux-gnu/ppc/arch.h ltrace-0.5/sysdeps/linux-gnu/ppc/arch.h
|
yann@1036
|
740 |
--- ltrace-0.5.orig/sysdeps/linux-gnu/ppc/arch.h 2006-06-14 06:55:21.000000000 +0200
|
yann@1036
|
741 |
+++ ltrace-0.5/sysdeps/linux-gnu/ppc/arch.h 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
742 |
@@ -4,9 +4,12 @@
|
yann@1036
|
743 |
|
yann@1036
|
744 |
#define LT_ELFCLASS ELFCLASS32
|
yann@1036
|
745 |
#define LT_ELF_MACHINE EM_PPC
|
yann@1036
|
746 |
+
|
yann@1036
|
747 |
#ifdef __powerpc64__ // Says 'ltrace' is 64 bits, says nothing about target.
|
yann@1036
|
748 |
#define LT_ELFCLASS2 ELFCLASS64
|
yann@1036
|
749 |
#define LT_ELF_MACHINE2 EM_PPC64
|
yann@1036
|
750 |
+#define ARCH_SUPPORTS_OPD
|
yann@1036
|
751 |
+#endif
|
yann@1036
|
752 |
|
yann@1036
|
753 |
#define PLT_REINITALISATION_BP "_start"
|
yann@1036
|
754 |
|
yann@1036
|
755 |
@@ -16,6 +19,3 @@
|
yann@1036
|
756 |
#if (PPC_NOP_LENGTH != BREAKPOINT_LENGTH)
|
yann@1036
|
757 |
#error "Length of the breakpoint value not equal to the length of a nop instruction"
|
yann@1036
|
758 |
#endif
|
yann@1036
|
759 |
-
|
yann@1036
|
760 |
-
|
yann@1036
|
761 |
-#endif
|
yann@1036
|
762 |
diff -durN ltrace-0.5.orig/testsuite/ltrace.minor/Makefile.in ltrace-0.5/testsuite/ltrace.minor/Makefile.in
|
yann@1036
|
763 |
--- ltrace-0.5.orig/testsuite/ltrace.minor/Makefile.in 2006-03-14 00:12:01.000000000 +0100
|
yann@1036
|
764 |
+++ ltrace-0.5/testsuite/ltrace.minor/Makefile.in 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
765 |
@@ -19,7 +19,7 @@
|
yann@1036
|
766 |
|
yann@1036
|
767 |
.SUFFIXES:
|
yann@1036
|
768 |
clean:
|
yann@1036
|
769 |
- -rm -f demangle trace-fork trace-clone
|
yann@1036
|
770 |
+ -rm -f demangle trace-fork trace-clone trace-exec trace-exec1
|
yann@1036
|
771 |
-rm -f time-record-tt time-record-ttt time-record-T
|
yann@1036
|
772 |
-rm -f attach-process count-record
|
yann@1036
|
773 |
-rm -f print-instruction-pointer
|
yann@1036
|
774 |
diff -durN ltrace-0.5.orig/testsuite/ltrace.minor/trace-clone.c ltrace-0.5/testsuite/ltrace.minor/trace-clone.c
|
yann@1036
|
775 |
--- ltrace-0.5.orig/testsuite/ltrace.minor/trace-clone.c 2006-03-16 01:38:47.000000000 +0100
|
yann@1036
|
776 |
+++ ltrace-0.5/testsuite/ltrace.minor/trace-clone.c 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
777 |
@@ -21,11 +21,11 @@
|
yann@1036
|
778 |
int main ()
|
yann@1036
|
779 |
{
|
yann@1036
|
780 |
pid_t pid;
|
yann@1036
|
781 |
- static char stack[STACK_SIZE];
|
yann@1036
|
782 |
+ char stack[STACK_SIZE];
|
yann@1036
|
783 |
#ifdef __ia64__
|
yann@1036
|
784 |
pid = __clone2((myfunc)&child, stack, STACK_SIZE, CLONE_FS, NULL);
|
yann@1036
|
785 |
#else
|
yann@1036
|
786 |
- pid = clone((myfunc)&child, stack,CLONE_FS, NULL );
|
yann@1036
|
787 |
+ pid = clone((myfunc)&child, stack + STACK_SIZE,CLONE_FS, NULL );
|
yann@1036
|
788 |
#endif
|
yann@1036
|
789 |
if (pid < 0)
|
yann@1036
|
790 |
{
|
yann@1036
|
791 |
diff -durN ltrace-0.5.orig/wait_for_something.c ltrace-0.5/wait_for_something.c
|
yann@1036
|
792 |
--- ltrace-0.5.orig/wait_for_something.c 2006-02-20 22:48:07.000000000 +0100
|
yann@1036
|
793 |
+++ ltrace-0.5/wait_for_something.c 2008-11-04 19:25:50.000000000 +0100
|
yann@1036
|
794 |
@@ -71,6 +71,18 @@
|
yann@1036
|
795 |
event.thing = LT_EV_SYSRET;
|
yann@1036
|
796 |
event.e_un.sysnum = tmp;
|
yann@1036
|
797 |
return &event;
|
yann@1036
|
798 |
+ case 3:
|
yann@1036
|
799 |
+ event.thing = LT_EV_ARCH_SYSCALL;
|
yann@1036
|
800 |
+ event.e_un.sysnum = tmp;
|
yann@1036
|
801 |
+ return &event;
|
yann@1036
|
802 |
+ case 4:
|
yann@1036
|
803 |
+ event.thing = LT_EV_ARCH_SYSRET;
|
yann@1036
|
804 |
+ event.e_un.sysnum = tmp;
|
yann@1036
|
805 |
+ return &event;
|
yann@1036
|
806 |
+ case -1:
|
yann@1036
|
807 |
+ event.thing = LT_EV_NONE;
|
yann@1036
|
808 |
+ continue_process(event.proc->pid);
|
yann@1036
|
809 |
+ return &event;
|
yann@1036
|
810 |
}
|
yann@1036
|
811 |
if (WIFEXITED(status)) {
|
yann@1036
|
812 |
event.thing = LT_EV_EXIT;
|