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