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
arch_translate_address_dyn(struct process * proc,arch_addr_t addr,arch_addr_t * ret)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
arch_translate_address(struct ltelf * lte,arch_addr_t addr,arch_addr_t * ret)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
breakpoint_on_hit(struct breakpoint * bp,struct process * proc)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
breakpoint_on_continue(struct breakpoint * bp,struct process * proc)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
breakpoint_on_retract(struct breakpoint * bp,struct process * proc)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
breakpoint_on_install(struct breakpoint * bp,struct process * proc)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
breakpoint_get_return_bp(struct breakpoint ** ret,struct breakpoint * bp,struct process * proc)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 *
address2bpstruct(struct process * proc,arch_addr_t addr)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
os_breakpoint_init(struct process * proc,struct breakpoint * sbp)128 os_breakpoint_init(struct process *proc, struct breakpoint *sbp)
129 {
130 return 0;
131 }
132
133 void
os_breakpoint_destroy(struct breakpoint * sbp)134 os_breakpoint_destroy(struct breakpoint *sbp)
135 {
136 }
137
138 int
os_breakpoint_clone(struct breakpoint * retp,struct breakpoint * sbp)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
arch_breakpoint_init(struct process * proc,struct breakpoint * sbp)147 arch_breakpoint_init(struct process *proc, struct breakpoint *sbp)
148 {
149 return 0;
150 }
151
152 void
arch_breakpoint_destroy(struct breakpoint * sbp)153 arch_breakpoint_destroy(struct breakpoint *sbp)
154 {
155 }
156
157 int
arch_breakpoint_clone(struct breakpoint * retp,struct breakpoint * sbp)158 arch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp)
159 {
160 return 0;
161 }
162 #endif
163
164 static void
breakpoint_init_base(struct breakpoint * bp,arch_addr_t addr,struct library_symbol * libsym)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
breakpoint_init(struct breakpoint * bp,struct process * proc,arch_addr_t addr,struct library_symbol * libsym)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
breakpoint_set_callbacks(struct breakpoint * bp,struct bp_callbacks * cbs)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
breakpoint_destroy(struct breakpoint * bp)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
breakpoint_clone(struct breakpoint * retp,struct process * new_proc,struct breakpoint * bp)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
breakpoint_turn_on(struct breakpoint * bp,struct process * proc)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
breakpoint_turn_off(struct breakpoint * bp,struct process * proc)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 *
create_default_return_bp(struct process * proc)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 *
insert_breakpoint_at(struct process * proc,arch_addr_t addr,struct library_symbol * libsym)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 *
insert_breakpoint(struct process * proc,struct breakpoint * bp)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
delete_breakpoint_at(struct process * proc,arch_addr_t addr)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
delete_breakpoint(struct process * proc,struct breakpoint * bp)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 *
breakpoint_name(const struct breakpoint * bp)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 *
breakpoint_library(const struct breakpoint * bp)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
disable_bp_cb(arch_addr_t * addr,struct breakpoint ** bpp,void * data)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
disable_all_breakpoints(struct process * proc)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
entry_breakpoint_on_hit(struct breakpoint * bp,struct process * proc)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
entry_breakpoint_init(struct process * proc,struct breakpoint * bp,arch_addr_t addr,struct library * lib)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
breakpoints_init(struct process * proc)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 }
487