breakpoints.c revision 98ff309cdc98857eb30992f108439cb7d7673598
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
88/*****************************************************************************/
89
90struct breakpoint *
91address2bpstruct(struct process *proc, arch_addr_t 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
98	struct breakpoint *found;
99	if (DICT_FIND_VAL(proc->breakpoints, &addr, &found) < 0)
100		return NULL;
101	return found;
102}
103
104#ifndef ARCH_HAVE_BREAKPOINT_DATA
105int
106arch_breakpoint_init(struct process *proc, struct breakpoint *sbp)
107{
108	return 0;
109}
110
111void
112arch_breakpoint_destroy(struct breakpoint *sbp)
113{
114}
115
116int
117arch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp)
118{
119	return 0;
120}
121#endif
122
123static void
124breakpoint_init_base(struct breakpoint *bp, struct process *proc,
125		     arch_addr_t addr, struct library_symbol *libsym)
126{
127	bp->cbs = NULL;
128	bp->addr = addr;
129	memset(bp->orig_value, 0, sizeof(bp->orig_value));
130	bp->enabled = 0;
131	bp->libsym = libsym;
132}
133
134/* On second thought, I don't think we need PROC.  All the translation
135 * (arch_translate_address in particular) should be doable using
136 * static lookups of various sections in the ELF file.  We shouldn't
137 * need process for anything.  */
138int
139breakpoint_init(struct breakpoint *bp, struct process *proc,
140		arch_addr_t addr, struct library_symbol *libsym)
141{
142	breakpoint_init_base(bp, proc, addr, libsym);
143	return arch_breakpoint_init(proc, bp);
144}
145
146void
147breakpoint_set_callbacks(struct breakpoint *bp, struct bp_callbacks *cbs)
148{
149	if (bp->cbs != NULL)
150		assert(bp->cbs == NULL);
151	bp->cbs = cbs;
152}
153
154void
155breakpoint_destroy(struct breakpoint *bp)
156{
157	if (bp == NULL)
158		return;
159	arch_breakpoint_destroy(bp);
160}
161
162int
163breakpoint_clone(struct breakpoint *retp, struct process *new_proc,
164		 struct breakpoint *bp, struct process *old_proc)
165{
166	struct library_symbol *libsym = NULL;
167	if (bp->libsym != NULL) {
168		int rc = proc_find_symbol(new_proc, bp->libsym, NULL, &libsym);
169		assert(rc == 0);
170	}
171
172	breakpoint_init_base(retp, new_proc, bp->addr, libsym);
173	memcpy(retp->orig_value, bp->orig_value, sizeof(bp->orig_value));
174	retp->enabled = bp->enabled;
175	if (arch_breakpoint_clone(retp, bp) < 0)
176		return -1;
177	breakpoint_set_callbacks(retp, bp->cbs);
178	return 0;
179}
180
181int
182breakpoint_turn_on(struct breakpoint *bp, struct process *proc)
183{
184	bp->enabled++;
185	if (bp->enabled == 1) {
186		assert(proc->pid != 0);
187		enable_breakpoint(proc, bp);
188	}
189	return 0;
190}
191
192int
193breakpoint_turn_off(struct breakpoint *bp, struct process *proc)
194{
195	bp->enabled--;
196	if (bp->enabled == 0)
197		disable_breakpoint(proc, bp);
198	assert(bp->enabled >= 0);
199	return 0;
200}
201
202struct breakpoint *
203insert_breakpoint(struct process *proc, arch_addr_t addr,
204		  struct library_symbol *libsym)
205{
206	struct process *leader = proc->leader;
207
208	/* Only the group leader should be getting the breakpoints and
209	 * thus have ->breakpoint initialized.  */
210	assert(leader != NULL);
211	assert(leader->breakpoints != NULL);
212
213	debug(DEBUG_FUNCTION, "insert_breakpoint(pid=%d, addr=%p, symbol=%s)",
214	      proc->pid, addr, libsym ? libsym->name : "NULL");
215
216	assert(addr != 0);
217
218	/* XXX what we need to do instead is have a list of
219	 * breakpoints that are enabled at this address.  The
220	 * following works if every breakpoint is the same and there's
221	 * no extra data, but that doesn't hold anymore.  For now it
222	 * will suffice, about the only realistic case where we need
223	 * to have more than one breakpoint per address is return from
224	 * a recursive library call.  */
225	struct breakpoint *bp;
226	if (DICT_FIND_VAL(leader->breakpoints, &addr, &bp) < 0) {
227		bp = malloc(sizeof(*bp));
228		if (bp == NULL
229		    || breakpoint_init(bp, proc, addr, libsym) < 0) {
230			free(bp);
231			return NULL;
232		}
233		if (proc_add_breakpoint(leader, bp) < 0) {
234		fail:
235			breakpoint_destroy(bp);
236			free(bp);
237			return NULL;
238		}
239	}
240
241	if (breakpoint_turn_on(bp, proc) < 0) {
242		proc_remove_breakpoint(leader, bp);
243		goto fail;
244	}
245
246	return bp;
247}
248
249void
250delete_breakpoint(struct process *proc, arch_addr_t addr)
251{
252	debug(DEBUG_FUNCTION, "delete_breakpoint(pid=%d, addr=%p)", proc->pid, addr);
253
254	struct process *leader = proc->leader;
255	assert(leader != NULL);
256
257	struct breakpoint *sbp = NULL;
258	DICT_FIND_VAL(leader->breakpoints, &addr, &sbp);
259	assert(sbp != NULL);
260
261	if (breakpoint_turn_off(sbp, proc) < 0) {
262		fprintf(stderr, "Couldn't turn off the breakpoint %s@%p\n",
263			breakpoint_name(sbp), sbp->addr);
264		return;
265	}
266	if (sbp->enabled == 0) {
267		proc_remove_breakpoint(leader, sbp);
268		breakpoint_destroy(sbp);
269		free(sbp);
270	}
271}
272
273const char *
274breakpoint_name(const struct breakpoint *bp)
275{
276	assert(bp != NULL);
277	return bp->libsym != NULL ? bp->libsym->name : NULL;
278}
279
280struct library *
281breakpoint_library(const struct breakpoint *bp)
282{
283	assert(bp != NULL);
284	return bp->libsym != NULL ? bp->libsym->lib : NULL;
285}
286
287static enum callback_status
288enable_bp_cb(arch_addr_t *addr, struct breakpoint **bpp, void *data)
289{
290	struct process *proc = data;
291	debug(DEBUG_FUNCTION, "enable_bp_cb(pid=%d)", proc->pid);
292	if ((*bpp)->enabled)
293		enable_breakpoint(proc, *bpp);
294	return CBS_CONT;
295}
296
297void
298enable_all_breakpoints(struct process *proc)
299{
300	debug(DEBUG_FUNCTION, "enable_all_breakpoints(pid=%d)", proc->pid);
301
302	debug(1, "Enabling breakpoints for pid %u...", proc->pid);
303	if (proc->breakpoints != NULL)
304		DICT_EACH(proc->breakpoints, arch_addr_t, struct breakpoint *,
305			  NULL, enable_bp_cb, proc);
306}
307
308static enum callback_status
309disable_bp_cb(arch_addr_t *addr, struct breakpoint **bpp, void *data)
310{
311	struct process *proc = data;
312	debug(DEBUG_FUNCTION, "disable_bp_cb(pid=%d)", proc->pid);
313	if ((*bpp)->enabled)
314		disable_breakpoint(proc, *bpp);
315	return CBS_CONT;
316}
317
318void
319disable_all_breakpoints(struct process *proc)
320{
321	debug(DEBUG_FUNCTION, "disable_all_breakpoints(pid=%d)", proc->pid);
322	assert(proc->leader == proc);
323	DICT_EACH(proc->breakpoints, arch_addr_t, struct breakpoint *,
324		  NULL, disable_bp_cb, proc);
325}
326
327/* XXX This is not currently properly supported.  On clone, this is
328 * just sliced.  Hopefully at the point that clone is done, this
329 * breakpoint is not necessary anymore.  If this use case ends up
330 * being important, we need to add a clone and destroy callbacks to
331 * breakpoints, and we should also probably drop arch_breakpoint_data
332 * so that we don't end up with two different customization mechanisms
333 * for one structure.  */
334struct entry_breakpoint {
335	struct breakpoint super;
336	arch_addr_t dyn_addr;
337};
338
339static void
340entry_breakpoint_on_hit(struct breakpoint *a, struct process *proc)
341{
342	struct entry_breakpoint *bp = (void *)a;
343	if (proc == NULL || proc->leader == NULL)
344		return;
345	arch_addr_t dyn_addr = bp->dyn_addr;
346	delete_breakpoint(proc, bp->super.addr);
347	linkmap_init(proc, dyn_addr);
348	arch_dynlink_done(proc);
349}
350
351int
352entry_breakpoint_init(struct process *proc,
353		      struct entry_breakpoint *bp, arch_addr_t addr,
354		      struct library *lib)
355{
356	assert(addr != 0);
357	int err = breakpoint_init(&bp->super, proc, addr, NULL);
358	if (err < 0)
359		return err;
360
361	static struct bp_callbacks entry_callbacks = {
362		.on_hit = entry_breakpoint_on_hit,
363	};
364	bp->super.cbs = &entry_callbacks;
365	bp->dyn_addr = lib->dyn_addr;
366	return 0;
367}
368
369int
370breakpoints_init(struct process *proc)
371{
372	debug(DEBUG_FUNCTION, "breakpoints_init(pid=%d)", proc->pid);
373
374	/* XXX breakpoint dictionary should be initialized
375	 * outside.  Here we just put in breakpoints.  */
376	assert(proc->breakpoints != NULL);
377
378	/* Only the thread group leader should hold the breakpoints.  */
379	assert(proc->leader == proc);
380
381	/* N.B. the following used to be conditional on this, and
382	 * maybe it still needs to be.  */
383	assert(proc->filename != NULL);
384
385	struct library *lib = ltelf_read_main_binary(proc, proc->filename);
386	struct entry_breakpoint *entry_bp = NULL;
387	int bp_state = 0;
388	int result = -1;
389	switch ((int)(lib != NULL)) {
390	fail:
391		switch (bp_state) {
392		case 2:
393			proc_remove_library(proc, lib);
394			proc_remove_breakpoint(proc, &entry_bp->super);
395		case 1:
396			breakpoint_destroy(&entry_bp->super);
397		}
398		library_destroy(lib);
399		free(entry_bp);
400	case 0:
401		return result;
402	}
403
404	entry_bp = malloc(sizeof(*entry_bp));
405	if (entry_bp == NULL
406	    || (entry_breakpoint_init(proc, entry_bp,
407				      lib->entry, lib)) < 0) {
408		fprintf(stderr,
409			"Couldn't initialize entry breakpoint for PID %d.\n"
410			"Some tracing events may be missed.\n", proc->pid);
411		free(entry_bp);
412
413	} else {
414		++bp_state;
415
416		if ((result = proc_add_breakpoint(proc, &entry_bp->super)) < 0)
417			goto fail;
418		++bp_state;
419
420		if ((result = breakpoint_turn_on(&entry_bp->super, proc)) < 0)
421			goto fail;
422	}
423	proc_add_library(proc, lib);
424
425	proc->callstack_depth = 0;
426	return 0;
427}
428