do not error on warnings
[platform/upstream/ltrace.git] / breakpoints.c
1 /*
2  * This file is part of ltrace.
3  * Copyright (C) 2006,2007,2011,2012,2013,2014 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 void
89 breakpoint_on_install(struct breakpoint *bp, struct process *proc)
90 {
91         assert(bp != NULL);
92         if (bp->cbs != NULL && bp->cbs->on_install != NULL)
93                 (bp->cbs->on_install)(bp, proc);
94 }
95
96 int
97 breakpoint_get_return_bp(struct breakpoint **ret,
98                          struct breakpoint *bp, struct process *proc)
99 {
100         assert(bp != NULL);
101         if (bp->cbs != NULL && bp->cbs->get_return_bp != NULL)
102                 return (bp->cbs->get_return_bp)(ret, bp, proc);
103
104         if ((*ret = create_default_return_bp(proc)) == NULL)
105                 return -1;
106
107         return 0;
108 }
109
110 /*****************************************************************************/
111
112 struct breakpoint *
113 address2bpstruct(struct process *proc, arch_addr_t addr)
114 {
115         assert(proc != NULL);
116         assert(proc->breakpoints != NULL);
117         assert(proc->leader == proc);
118         debug(DEBUG_FUNCTION, "address2bpstruct(pid=%d, addr=%p)", proc->pid, addr);
119
120         struct breakpoint *found;
121         if (DICT_FIND_VAL(proc->breakpoints, &addr, &found) < 0)
122                 return NULL;
123         return found;
124 }
125
126 #ifndef OS_HAVE_BREAKPOINT_DATA
127 int
128 os_breakpoint_init(struct process *proc, struct breakpoint *sbp)
129 {
130         return 0;
131 }
132
133 void
134 os_breakpoint_destroy(struct breakpoint *sbp)
135 {
136 }
137
138 int
139 os_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp)
140 {
141         return 0;
142 }
143 #endif
144
145 #ifndef ARCH_HAVE_BREAKPOINT_DATA
146 int
147 arch_breakpoint_init(struct process *proc, struct breakpoint *sbp)
148 {
149         return 0;
150 }
151
152 void
153 arch_breakpoint_destroy(struct breakpoint *sbp)
154 {
155 }
156
157 int
158 arch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp)
159 {
160         return 0;
161 }
162 #endif
163
164 static void
165 breakpoint_init_base(struct breakpoint *bp,
166                      arch_addr_t addr, struct library_symbol *libsym)
167 {
168         bp->cbs = NULL;
169         bp->addr = addr;
170         memset(bp->orig_value, 0, sizeof(bp->orig_value));
171         bp->enabled = 0;
172         bp->libsym = libsym;
173 }
174
175 /* On second thought, I don't think we need PROC.  All the translation
176  * (arch_translate_address in particular) should be doable using
177  * static lookups of various sections in the ELF file.  We shouldn't
178  * need process for anything.  */
179 int
180 breakpoint_init(struct breakpoint *bp, struct process *proc,
181                 arch_addr_t addr, struct library_symbol *libsym)
182 {
183         breakpoint_init_base(bp, addr, libsym);
184         if (os_breakpoint_init(proc, bp) < 0)
185                 return -1;
186         if (arch_breakpoint_init(proc, bp) < 0) {
187                 os_breakpoint_destroy(bp);
188                 return -1;
189         }
190         return 0;
191 }
192
193 void
194 breakpoint_set_callbacks(struct breakpoint *bp, struct bp_callbacks *cbs)
195 {
196         if (bp->cbs != NULL)
197                 assert(bp->cbs == NULL);
198         bp->cbs = cbs;
199 }
200
201 void
202 breakpoint_destroy(struct breakpoint *bp)
203 {
204         if (bp == NULL)
205                 return;
206         arch_breakpoint_destroy(bp);
207         os_breakpoint_destroy(bp);
208 }
209
210 int
211 breakpoint_clone(struct breakpoint *retp, struct process *new_proc,
212                  struct breakpoint *bp)
213 {
214         struct library_symbol *libsym = NULL;
215         if (bp->libsym != NULL) {
216                 int rc = proc_find_symbol(new_proc, bp->libsym, NULL, &libsym);
217                 assert(rc == 0);
218         }
219
220         breakpoint_init_base(retp, bp->addr, libsym);
221         memcpy(retp->orig_value, bp->orig_value, sizeof(bp->orig_value));
222         retp->enabled = bp->enabled;
223         if (os_breakpoint_clone(retp, bp) < 0)
224                 return -1;
225         if (arch_breakpoint_clone(retp, bp) < 0) {
226                 os_breakpoint_destroy(retp);
227                 return -1;
228         }
229         breakpoint_set_callbacks(retp, bp->cbs);
230         return 0;
231 }
232
233 int
234 breakpoint_turn_on(struct breakpoint *bp, struct process *proc)
235 {
236         bp->enabled++;
237         if (bp->enabled == 1) {
238                 assert(proc->pid != 0);
239                 enable_breakpoint(proc, bp);
240                 breakpoint_on_install(bp, proc);
241         }
242         return 0;
243 }
244
245 int
246 breakpoint_turn_off(struct breakpoint *bp, struct process *proc)
247 {
248         bp->enabled--;
249         if (bp->enabled == 0)
250                 disable_breakpoint(proc, bp);
251         assert(bp->enabled >= 0);
252         return 0;
253 }
254
255 struct breakpoint *
256 create_default_return_bp(struct process *proc)
257 {
258         struct breakpoint *bp = malloc(sizeof *bp);
259         arch_addr_t return_addr = get_return_addr(proc, proc->stack_pointer);
260         if (return_addr == 0 || bp == NULL
261             || breakpoint_init(bp, proc, return_addr, NULL) < 0) {
262                 free(bp);
263                 return NULL;
264         }
265         return bp;
266 }
267
268 struct breakpoint *
269 insert_breakpoint_at(struct process *proc, arch_addr_t addr,
270                      struct library_symbol *libsym)
271 {
272         debug(DEBUG_FUNCTION,
273               "insert_breakpoint_at(pid=%d, addr=%p, symbol=%s)",
274               proc->pid, addr, libsym ? libsym->name : "NULL");
275
276         assert(addr != 0);
277
278         struct breakpoint *bp = malloc(sizeof *bp);
279         if (bp == NULL || breakpoint_init(bp, proc, addr, libsym) < 0) {
280                 free(bp);
281                 return NULL;
282         }
283
284         /* N.B. (and XXX): BP->addr might differ from ADDR.  On ARM
285          * this is a real possibility.  The problem here is that to
286          * create a return breakpoint ltrace calls get_return_addr and
287          * then insert_breakpoint_at.  So get_return_addr needs to
288          * encode all the information necessary for breakpoint_init
289          * into the address itself, so ADDR is potentially
290          * mangled.  */
291
292         struct breakpoint *tmp = insert_breakpoint(proc, bp);
293         if (tmp != bp) {
294                 breakpoint_destroy(bp);
295                 free(bp);
296         }
297         return tmp;
298 }
299
300 struct breakpoint *
301 insert_breakpoint(struct process *proc, struct breakpoint *bp)
302 {
303         /* Only the group leader should be getting the breakpoints and
304          * thus have ->breakpoint initialized.  */
305         struct process *leader = proc->leader;
306         assert(leader != NULL);
307         assert(leader->breakpoints != NULL);
308
309         /* XXX what we need to do instead is have a list of
310          * breakpoints that are enabled at this address.  The
311          * following works if every breakpoint is the same and there's
312          * no extra data, but that doesn't hold anymore.  For now it
313          * will suffice, about the only realistic case where we need
314          * to have more than one breakpoint per address is return from
315          * a recursive library call.  */
316         struct breakpoint *ext_bp = bp;
317         if (DICT_FIND_VAL(leader->breakpoints, &bp->addr, &ext_bp) != 0) {
318                 if (proc_add_breakpoint(leader, bp) < 0)
319                         return NULL;
320                 ext_bp = bp;
321         }
322
323         if (breakpoint_turn_on(ext_bp, proc) < 0) {
324                 if (ext_bp != bp)
325                         proc_remove_breakpoint(leader, bp);
326                 return NULL;
327         }
328
329         return ext_bp;
330 }
331
332 void
333 delete_breakpoint_at(struct process *proc, arch_addr_t addr)
334 {
335         debug(DEBUG_FUNCTION, "delete_breakpoint_at(pid=%d, addr=%p)",
336               proc->pid, addr);
337
338         struct process *leader = proc->leader;
339         assert(leader != NULL);
340
341         struct breakpoint *bp = NULL;
342         DICT_FIND_VAL(leader->breakpoints, &addr, &bp);
343         assert(bp != NULL);
344
345         if (delete_breakpoint(proc, bp) < 0) {
346                 fprintf(stderr, "Couldn't turn off the breakpoint %s@%p\n",
347                         breakpoint_name(bp), bp->addr);
348         }
349 }
350
351 int
352 delete_breakpoint(struct process *proc, struct breakpoint *bp)
353 {
354         struct process *leader = proc->leader;
355         assert(leader != NULL);
356
357         if (breakpoint_turn_off(bp, proc) < 0)
358                 return -1;
359
360         if (bp->enabled == 0) {
361                 proc_remove_breakpoint(leader, bp);
362                 breakpoint_destroy(bp);
363                 free(bp);
364         }
365
366         return 0;
367 }
368
369 const char *
370 breakpoint_name(const struct breakpoint *bp)
371 {
372         assert(bp != NULL);
373         return bp->libsym != NULL ? bp->libsym->name : NULL;
374 }
375
376 struct library *
377 breakpoint_library(const struct breakpoint *bp)
378 {
379         assert(bp != NULL);
380         return bp->libsym != NULL ? bp->libsym->lib : NULL;
381 }
382
383 static enum callback_status
384 disable_bp_cb(arch_addr_t *addr, struct breakpoint **bpp, void *data)
385 {
386         struct process *proc = data;
387         debug(DEBUG_FUNCTION, "disable_bp_cb(pid=%d)", proc->pid);
388         if ((*bpp)->enabled)
389                 disable_breakpoint(proc, *bpp);
390         return CBS_CONT;
391 }
392
393 void
394 disable_all_breakpoints(struct process *proc)
395 {
396         debug(DEBUG_FUNCTION, "disable_all_breakpoints(pid=%d)", proc->pid);
397         assert(proc->leader == proc);
398         DICT_EACH(proc->breakpoints, arch_addr_t, struct breakpoint *,
399                   NULL, disable_bp_cb, proc);
400 }
401
402 static void
403 entry_breakpoint_on_hit(struct breakpoint *bp, struct process *proc)
404 {
405         if (proc == NULL || proc->leader == NULL)
406                 return;
407         delete_breakpoint_at(proc, bp->addr);
408         process_hit_start(proc);
409 }
410
411 int
412 entry_breakpoint_init(struct process *proc,
413                       struct breakpoint *bp, arch_addr_t addr,
414                       struct library *lib)
415 {
416         assert(addr != 0);
417         int err = breakpoint_init(bp, proc, addr, NULL);
418         if (err < 0)
419                 return err;
420
421         static struct bp_callbacks entry_callbacks = {
422                 .on_hit = entry_breakpoint_on_hit,
423         };
424         bp->cbs = &entry_callbacks;
425         return 0;
426 }
427
428 int
429 breakpoints_init(struct process *proc)
430 {
431         debug(DEBUG_FUNCTION, "breakpoints_init(pid=%d)", proc->pid);
432
433         /* XXX breakpoint dictionary should be initialized
434          * outside.  Here we just put in breakpoints.  */
435         assert(proc->breakpoints != NULL);
436
437         /* Only the thread group leader should hold the breakpoints.  */
438         assert(proc->leader == proc);
439
440         /* N.B. the following used to be conditional on this, and
441          * maybe it still needs to be.  */
442         assert(proc->filename != NULL);
443
444         struct library *lib = ltelf_read_main_binary(proc, proc->filename);
445         struct breakpoint *entry_bp = NULL;
446         int bp_state = 0;
447         int result = -1;
448         switch ((int)(lib != NULL)) {
449         fail:
450                 switch (bp_state) {
451                 case 2:
452                         proc_remove_library(proc, lib);
453                         proc_remove_breakpoint(proc, entry_bp);
454                 case 1:
455                         breakpoint_destroy(entry_bp);
456                 }
457                 library_destroy(lib);
458                 free(entry_bp);
459         case 0:
460                 return result;
461         }
462
463         entry_bp = malloc(sizeof(*entry_bp));
464         if (entry_bp == NULL
465             || (entry_breakpoint_init(proc, entry_bp,
466                                       lib->entry, lib)) < 0) {
467                 fprintf(stderr,
468                         "Couldn't initialize entry breakpoint for PID %d.\n"
469                         "Some tracing events may be missed.\n", proc->pid);
470                 free(entry_bp);
471
472         } else {
473                 ++bp_state;
474
475                 if ((result = proc_add_breakpoint(proc, entry_bp)) < 0)
476                         goto fail;
477                 ++bp_state;
478
479                 if ((result = breakpoint_turn_on(entry_bp, proc)) < 0)
480                         goto fail;
481         }
482         proc_add_library(proc, lib);
483
484         proc->callstack_depth = 0;
485         return 0;
486 }