Imported Upstream version 0.7.2
[platform/upstream/ltrace.git] / breakpoints.c
1 /*
2  * This file is part of ltrace.
3  * Copyright (C) 2006,2007,2011,2012 Petr Machata, Red Hat Inc.
4  * Copyright (C) 2009 Juan Cespedes
5  * Copyright (C) 1998,2001,2002,2003,2007,2008,2009 Juan Cespedes
6  * Copyright (C) 2006 Ian Wienand
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of the
11  * License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  */
23
24 #include "config.h"
25
26 #include <assert.h>
27 #include <errno.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #ifdef __powerpc__
33 #include <sys/ptrace.h>
34 #endif
35
36 #include "backend.h"
37 #include "breakpoint.h"
38 #include "debug.h"
39 #include "library.h"
40 #include "ltrace-elf.h"
41 #include "proc.h"
42
43 #ifndef ARCH_HAVE_TRANSLATE_ADDRESS
44 int
45 arch_translate_address_dyn(struct Process *proc,
46                        arch_addr_t addr, arch_addr_t *ret)
47 {
48         *ret = addr;
49         return 0;
50 }
51
52 struct ltelf;
53 int
54 arch_translate_address(struct ltelf *lte,
55                        arch_addr_t addr, arch_addr_t *ret)
56 {
57         *ret = addr;
58         return 0;
59 }
60 #endif
61
62 void
63 breakpoint_on_hit(struct breakpoint *bp, struct Process *proc)
64 {
65         assert(bp != NULL);
66         if (bp->cbs != NULL && bp->cbs->on_hit != NULL)
67                 (bp->cbs->on_hit)(bp, proc);
68 }
69
70 void
71 breakpoint_on_continue(struct breakpoint *bp, struct Process *proc)
72 {
73         assert(bp != NULL);
74         if (bp->cbs != NULL && bp->cbs->on_continue != NULL)
75                 (bp->cbs->on_continue)(bp, proc);
76         else
77                 continue_after_breakpoint(proc, bp);
78 }
79
80 void
81 breakpoint_on_retract(struct breakpoint *bp, struct Process *proc)
82 {
83         assert(bp != NULL);
84         if (bp->cbs != NULL && bp->cbs->on_retract != NULL)
85                 (bp->cbs->on_retract)(bp, proc);
86 }
87
88 /*****************************************************************************/
89
90 struct breakpoint *
91 address2bpstruct(Process *proc, void *addr)
92 {
93         assert(proc != NULL);
94         assert(proc->breakpoints != NULL);
95         assert(proc->leader == proc);
96         debug(DEBUG_FUNCTION, "address2bpstruct(pid=%d, addr=%p)", proc->pid, addr);
97         return dict_find_entry(proc->breakpoints, addr);
98 }
99
100 #ifndef ARCH_HAVE_BREAKPOINT_DATA
101 int
102 arch_breakpoint_init(struct Process *proc, struct breakpoint *sbp)
103 {
104         return 0;
105 }
106
107 void
108 arch_breakpoint_destroy(struct breakpoint *sbp)
109 {
110 }
111
112 int
113 arch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp)
114 {
115         return 0;
116 }
117 #endif
118
119 static void
120 breakpoint_init_base(struct breakpoint *bp, struct Process *proc,
121                      arch_addr_t addr, struct library_symbol *libsym)
122 {
123         bp->cbs = NULL;
124         bp->addr = addr;
125         memset(bp->orig_value, 0, sizeof(bp->orig_value));
126         bp->enabled = 0;
127         bp->libsym = libsym;
128 }
129
130 /* On second thought, I don't think we need PROC.  All the translation
131  * (arch_translate_address in particular) should be doable using
132  * static lookups of various sections in the ELF file.  We shouldn't
133  * need process for anything.  */
134 int
135 breakpoint_init(struct breakpoint *bp, struct Process *proc,
136                 arch_addr_t addr, struct library_symbol *libsym)
137 {
138         breakpoint_init_base(bp, proc, addr, libsym);
139         return arch_breakpoint_init(proc, bp);
140 }
141
142 void
143 breakpoint_set_callbacks(struct breakpoint *bp, struct bp_callbacks *cbs)
144 {
145         if (bp->cbs != NULL)
146                 assert(bp->cbs == NULL);
147         bp->cbs = cbs;
148 }
149
150 void
151 breakpoint_destroy(struct breakpoint *bp)
152 {
153         if (bp == NULL)
154                 return;
155         arch_breakpoint_destroy(bp);
156 }
157
158 int
159 breakpoint_clone(struct breakpoint *retp, struct Process *new_proc,
160                  struct breakpoint *bp, struct Process *old_proc)
161 {
162         struct library_symbol *libsym = NULL;
163         if (bp->libsym != NULL) {
164                 int rc = proc_find_symbol(new_proc, bp->libsym, NULL, &libsym);
165                 assert(rc == 0);
166         }
167
168         breakpoint_init_base(retp, new_proc, bp->addr, libsym);
169         memcpy(retp->orig_value, bp->orig_value, sizeof(bp->orig_value));
170         retp->enabled = bp->enabled;
171         if (arch_breakpoint_clone(retp, bp) < 0)
172                 return -1;
173         breakpoint_set_callbacks(retp, bp->cbs);
174         return 0;
175 }
176
177 int
178 breakpoint_turn_on(struct breakpoint *bp, struct Process *proc)
179 {
180         bp->enabled++;
181         if (bp->enabled == 1) {
182                 assert(proc->pid != 0);
183                 enable_breakpoint(proc, bp);
184         }
185         return 0;
186 }
187
188 int
189 breakpoint_turn_off(struct breakpoint *bp, struct Process *proc)
190 {
191         bp->enabled--;
192         if (bp->enabled == 0)
193                 disable_breakpoint(proc, bp);
194         assert(bp->enabled >= 0);
195         return 0;
196 }
197
198 struct breakpoint *
199 insert_breakpoint(struct Process *proc, void *addr,
200                   struct library_symbol *libsym)
201 {
202         Process *leader = proc->leader;
203
204         /* Only the group leader should be getting the breakpoints and
205          * thus have ->breakpoint initialized.  */
206         assert(leader != NULL);
207         assert(leader->breakpoints != NULL);
208
209         debug(DEBUG_FUNCTION, "insert_breakpoint(pid=%d, addr=%p, symbol=%s)",
210               proc->pid, addr, libsym ? libsym->name : "NULL");
211
212         assert(addr != 0);
213
214         /* XXX what we need to do instead is have a list of
215          * breakpoints that are enabled at this address.  The
216          * following works if every breakpoint is the same and there's
217          * no extra data, but that doesn't hold anymore.  For now it
218          * will suffice, about the only realistic case where we need
219          * to have more than one breakpoint per address is return from
220          * a recursive library call.  */
221         struct breakpoint *sbp = dict_find_entry(leader->breakpoints, addr);
222         if (sbp == NULL) {
223                 sbp = malloc(sizeof(*sbp));
224                 if (sbp == NULL
225                     || breakpoint_init(sbp, proc, addr, libsym) < 0) {
226                         free(sbp);
227                         return NULL;
228                 }
229                 if (proc_add_breakpoint(leader, sbp) < 0) {
230                 fail:
231                         breakpoint_destroy(sbp);
232                         free(sbp);
233                         return NULL;
234                 }
235         }
236
237         if (breakpoint_turn_on(sbp, proc) < 0) {
238                 proc_remove_breakpoint(leader, sbp);
239                 goto fail;
240         }
241
242         return sbp;
243 }
244
245 void
246 delete_breakpoint(Process *proc, void *addr)
247 {
248         debug(DEBUG_FUNCTION, "delete_breakpoint(pid=%d, addr=%p)", proc->pid, addr);
249
250         Process * leader = proc->leader;
251         assert(leader != NULL);
252
253         struct breakpoint *sbp = dict_find_entry(leader->breakpoints, addr);
254         assert(sbp != NULL);
255         /* This should only happen on out-of-memory conditions. */
256         if (sbp == NULL)
257                 return;
258
259         if (breakpoint_turn_off(sbp, proc) < 0) {
260                 fprintf(stderr, "Couldn't turn off the breakpoint %s@%p\n",
261                         breakpoint_name(sbp), sbp->addr);
262                 return;
263         }
264         if (sbp->enabled == 0) {
265                 proc_remove_breakpoint(leader, sbp);
266                 breakpoint_destroy(sbp);
267                 free(sbp);
268         }
269 }
270
271 const char *
272 breakpoint_name(const struct breakpoint *bp)
273 {
274         assert(bp != NULL);
275         return bp->libsym != NULL ? bp->libsym->name : NULL;
276 }
277
278 struct library *
279 breakpoint_library(const struct breakpoint *bp)
280 {
281         assert(bp != NULL);
282         return bp->libsym != NULL ? bp->libsym->lib : NULL;
283 }
284
285 static void
286 enable_bp_cb(void *addr, void *sbp, void *proc)
287 {
288         debug(DEBUG_FUNCTION, "enable_bp_cb(pid=%d)", ((Process *)proc)->pid);
289         if (((struct breakpoint *)sbp)->enabled)
290                 enable_breakpoint(proc, sbp);
291 }
292
293 void
294 enable_all_breakpoints(Process *proc)
295 {
296         debug(DEBUG_FUNCTION, "enable_all_breakpoints(pid=%d)", proc->pid);
297
298         debug(1, "Enabling breakpoints for pid %u...", proc->pid);
299         if (proc->breakpoints) {
300                 dict_apply_to_all(proc->breakpoints, enable_bp_cb,
301                                   proc);
302         }
303 }
304
305 static void
306 disable_bp_cb(void *addr, void *sbp, void *proc)
307 {
308         debug(DEBUG_FUNCTION, "disable_bp_cb(pid=%d)", ((Process *)proc)->pid);
309         if (((struct breakpoint *)sbp)->enabled)
310                 disable_breakpoint(proc, sbp);
311 }
312
313 void
314 disable_all_breakpoints(Process *proc) {
315         debug(DEBUG_FUNCTION, "disable_all_breakpoints(pid=%d)", proc->pid);
316         assert(proc->leader == proc);
317         dict_apply_to_all(proc->breakpoints, disable_bp_cb, proc);
318 }
319
320 /* XXX This is not currently properly supported.  On clone, this is
321  * just sliced.  Hopefully at the point that clone is done, this
322  * breakpoint is not necessary anymore.  If this use case ends up
323  * being important, we need to add a clone and destroy callbacks to
324  * breakpoints, and we should also probably drop arch_breakpoint_data
325  * so that we don't end up with two different customization mechanisms
326  * for one structure.  */
327 struct entry_breakpoint {
328         struct breakpoint super;
329         arch_addr_t dyn_addr;
330 };
331
332 static void
333 entry_breakpoint_on_hit(struct breakpoint *a, struct Process *proc)
334 {
335         struct entry_breakpoint *bp = (void *)a;
336         if (proc == NULL || proc->leader == NULL)
337                 return;
338         arch_addr_t dyn_addr = bp->dyn_addr;
339         delete_breakpoint(proc, bp->super.addr);
340         linkmap_init(proc, dyn_addr);
341         arch_dynlink_done(proc);
342 }
343
344 int
345 entry_breakpoint_init(struct Process *proc,
346                       struct entry_breakpoint *bp, arch_addr_t addr,
347                       struct library *lib)
348 {
349         assert(addr != 0);
350         int err = breakpoint_init(&bp->super, proc, addr, NULL);
351         if (err < 0)
352                 return err;
353
354         static struct bp_callbacks entry_callbacks = {
355                 .on_hit = entry_breakpoint_on_hit,
356         };
357         bp->super.cbs = &entry_callbacks;
358         bp->dyn_addr = lib->dyn_addr;
359         return 0;
360 }
361
362 int
363 breakpoints_init(Process *proc)
364 {
365         debug(DEBUG_FUNCTION, "breakpoints_init(pid=%d)", proc->pid);
366
367         /* XXX breakpoint dictionary should be initialized
368          * outside.  Here we just put in breakpoints.  */
369         assert(proc->breakpoints != NULL);
370
371         /* Only the thread group leader should hold the breakpoints.  */
372         assert(proc->leader == proc);
373
374         /* N.B. the following used to be conditional on this, and
375          * maybe it still needs to be.  */
376         assert(proc->filename != NULL);
377
378         struct library *lib = ltelf_read_main_binary(proc, proc->filename);
379         struct entry_breakpoint *entry_bp = NULL;
380         int bp_state = 0;
381         int result = -1;
382         switch (lib != NULL) {
383         fail:
384                 switch (bp_state) {
385                 case 2:
386                         proc_remove_library(proc, lib);
387                         proc_remove_breakpoint(proc, &entry_bp->super);
388                 case 1:
389                         breakpoint_destroy(&entry_bp->super);
390                 }
391                 library_destroy(lib);
392                 free(entry_bp);
393         case 0:
394                 return result;
395         }
396
397         entry_bp = malloc(sizeof(*entry_bp));
398         if (entry_bp == NULL
399             || (entry_breakpoint_init(proc, entry_bp,
400                                       lib->entry, lib)) < 0) {
401                 fprintf(stderr,
402                         "Couldn't initialize entry breakpoint for PID %d.\n"
403                         "Some tracing events may be missed.\n", proc->pid);
404                 free(entry_bp);
405
406         } else {
407                 ++bp_state;
408
409                 if ((result = proc_add_breakpoint(proc, &entry_bp->super)) < 0)
410                         goto fail;
411                 ++bp_state;
412
413                 if ((result = breakpoint_turn_on(&entry_bp->super, proc)) < 0)
414                         goto fail;
415         }
416         proc_add_library(proc, lib);
417
418         proc->callstack_depth = 0;
419         return 0;
420 }