breakpoints.c revision 93d95dff48698b8bde511c7f71acda7646da2626
1d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes#include "config.h"
2d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes
35b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes#include <stdlib.h>
47186e2af704f4458e6383e8a92482594db29b597Juan Cespedes#include <string.h>
55b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes#include <assert.h>
62b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata#include <error.h>
72b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata#include <errno.h>
85b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
9f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes#ifdef __powerpc__
10f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes#include <sys/ptrace.h>
11f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes#endif
12f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes
139294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machata#include "breakpoint.h"
14f728123bd75a65a6a1536e198c3c30719e494e71Juan Cespedes#include "common.h"
15366c2f46d844f040458df9b7e35fc3b8527ed2d3Petr Machata#include "proc.h"
162b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata#include "library.h"
175b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
18c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata#ifndef ARCH_HAVE_TRANSLATE_ADDRESS
19c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machataint
20c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machataarch_translate_address(struct Process *proc,
21c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata		       target_address_t addr, target_address_t *ret)
22c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata{
23c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata	*ret = addr;
24c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata	return 0;
25c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata}
26c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata#endif
27c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata
28a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machatavoid
29a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machatabreakpoint_on_hit(struct breakpoint *bp, struct Process *proc)
30a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata{
31a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata	assert(bp != NULL);
32a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata	if (bp->cbs != NULL && bp->cbs->on_hit != NULL)
3355ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata		(bp->cbs->on_hit)(bp, proc);
3455ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata}
3555ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata
3655ac932f2802f85c53792153ac909dcd8a690c5cPetr Machatavoid
3755ac932f2802f85c53792153ac909dcd8a690c5cPetr Machatabreakpoint_on_continue(struct breakpoint *bp, struct Process *proc)
3855ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata{
3955ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata	assert(bp != NULL);
4055ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata	if (bp->cbs != NULL && bp->cbs->on_continue != NULL)
4155ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata		(bp->cbs->on_continue)(bp, proc);
4255ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata	else
4355ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata		continue_after_breakpoint(proc, bp);
44a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata}
45a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata
465b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes/*****************************************************************************/
475b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
489294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machatastruct breakpoint *
49fed1e8d33ab050df892a88110e1a316d285ee650Petr Machataaddress2bpstruct(Process *proc, void *addr)
50fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{
512662768efe599f6bb43c4310177e30f56b601bb7Petr Machata	assert(proc != NULL);
522662768efe599f6bb43c4310177e30f56b601bb7Petr Machata	assert(proc->breakpoints != NULL);
539a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	assert(proc->leader == proc);
54cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes	debug(DEBUG_FUNCTION, "address2bpstruct(pid=%d, addr=%p)", proc->pid, addr);
55cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes	return dict_find_entry(proc->breakpoints, addr);
565b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes}
575b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
588cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata#ifndef ARCH_HAVE_BREAKPOINT_DATA
592b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machataint
602b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machataarch_breakpoint_init(struct Process *proc, struct breakpoint *sbp)
612b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata{
622b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	return 0;
632b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata}
648cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata
658cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machatavoid
668cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machataarch_breakpoint_destroy(struct breakpoint *sbp)
678cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata{
688cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata}
69d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata
70d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machataint
71d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machataarch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp)
72d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata{
73d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	return 0;
74d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata}
752b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata#endif
762b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata
77d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machatastatic void
78d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machatabreakpoint_init_base(struct breakpoint *bp, struct Process *proc,
79d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata		     target_address_t addr, struct library_symbol *libsym)
80d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata{
81d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	bp->cbs = NULL;
82d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	bp->addr = addr;
83d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	memset(bp->orig_value, 0, sizeof(bp->orig_value));
84d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	bp->enabled = 0;
85d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	bp->libsym = libsym;
86d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata}
87d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata
8852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata/* On second thought, I don't think we need PROC.  All the translation
8952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * (arch_translate_address in particular) should be doable using
9052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * static lookups of various sections in the ELF file.  We shouldn't
9152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * need process for anything.  */
922b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machataint
932b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machatabreakpoint_init(struct breakpoint *bp, struct Process *proc,
9455ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata		target_address_t addr, struct library_symbol *libsym)
952b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata{
96d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	breakpoint_init_base(bp, proc, addr, libsym);
972b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	return arch_breakpoint_init(proc, bp);
982b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata}
992b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata
1008cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machatavoid
10155ac932f2802f85c53792153ac909dcd8a690c5cPetr Machatabreakpoint_set_callbacks(struct breakpoint *bp, struct bp_callbacks *cbs)
10255ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata{
10355ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata	if (bp->cbs != NULL)
10455ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata		assert(bp->cbs == NULL);
10555ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata	bp->cbs = cbs;
10655ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata}
10755ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata
10855ac932f2802f85c53792153ac909dcd8a690c5cPetr Machatavoid
1098cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machatabreakpoint_destroy(struct breakpoint *bp)
1108cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata{
1118cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata	if (bp == NULL)
1128cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata		return;
113d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	arch_breakpoint_destroy(bp);
114d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata}
1158cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata
116d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machatastruct find_symbol_data {
117d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	struct library_symbol *old_libsym;
118d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	struct library_symbol *found_libsym;
119d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata};
1208cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata
121d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machatastatic enum callback_status
122d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machatafind_sym_in_lib(struct Process *proc, struct library *lib, void *u)
123d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata{
124d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	struct find_symbol_data *fs = u;
125d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	fs->found_libsym
126d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata		= library_each_symbol(lib, NULL, library_symbol_equal_cb,
127d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata				      fs->old_libsym);
128d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	return fs->found_libsym != NULL ? CBS_STOP : CBS_CONT;
129d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata}
130d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata
131d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machataint
132d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machatabreakpoint_clone(struct breakpoint *retp, struct Process *new_proc,
133d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata		 struct breakpoint *bp, struct Process *old_proc)
134d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata{
135d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	/* Find library and symbol that this breakpoint was linked to.  */
136d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	struct library_symbol *libsym = bp->libsym;
137d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	struct library *lib = NULL;
138d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	if (libsym != NULL) {
139d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata		struct find_symbol_data f_data = {
140d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata			.old_libsym = libsym,
141d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata		};
142d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata		lib = proc_each_library(old_proc, NULL,
143d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata					find_sym_in_lib, &f_data);
144d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata		assert(lib != NULL);
145d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata		libsym = f_data.found_libsym;
146d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	}
147d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata
148d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	/* LIB and LIBSYM now hold the new library and symbol that
149d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	 * correspond to the original breakpoint.  Now we can do the
150d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	 * clone itself.  */
151d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	breakpoint_init_base(retp, new_proc, bp->addr, libsym);
152d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	memcpy(retp->orig_value, bp->orig_value, sizeof(bp->orig_value));
153d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	retp->enabled = bp->enabled;
154d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	if (arch_breakpoint_clone(retp, bp) < 0)
155d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata		return -1;
156d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	breakpoint_set_callbacks(retp, bp->cbs);
157d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	return 0;
1588cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata}
1598cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata
16052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machataint
161fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machatabreakpoint_turn_on(struct breakpoint *bp, struct Process *proc)
16252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata{
16352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	bp->enabled++;
16452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	if (bp->enabled == 1) {
165fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machata		assert(proc->pid != 0);
166fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machata		enable_breakpoint(proc, bp);
16752dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	}
16852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	return 0;
16952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata}
17052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata
17152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machataint
172fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machatabreakpoint_turn_off(struct breakpoint *bp, struct Process *proc)
17352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata{
17452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	bp->enabled--;
17552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	if (bp->enabled == 0)
176fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machata		disable_breakpoint(proc, bp);
17752dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	assert(bp->enabled >= 0);
17852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	return 0;
17952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata}
18052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata
1819294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machatastruct breakpoint *
1829df15016447915a61526af8cb81c588913bcf44cPetr Machatainsert_breakpoint(struct Process *proc, void *addr,
1839df15016447915a61526af8cb81c588913bcf44cPetr Machata		  struct library_symbol *libsym)
184fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{
1859df15016447915a61526af8cb81c588913bcf44cPetr Machata	Process *leader = proc->leader;
1869a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
1879a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	/* Only the group leader should be getting the breakpoints and
1889a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	 * thus have ->breakpoint initialized.  */
1899a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	assert(leader != NULL);
1909a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	assert(leader->breakpoints != NULL);
1919a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
192050b0a6fd01fc01952c0ab8dbb84d6eba65c71c9Petr Machata	debug(DEBUG_FUNCTION, "insert_breakpoint(pid=%d, addr=%p, symbol=%s)",
193050b0a6fd01fc01952c0ab8dbb84d6eba65c71c9Petr Machata	      proc->pid, addr, libsym ? libsym->name : "NULL");
1945b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
195218c5ff26841f5bbd188c42ccbd67422a7a20556Petr Machata	assert(addr != 0);
1969a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand
19752dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	/* XXX what we need to do instead is have a list of
19852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	 * breakpoints that are enabled at this address.  The
19952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	 * following works if every breakpoint is the same and there's
20052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	 * no extra data, but that doesn't hold anymore.  For now it
20152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	 * will suffice, about the only realistic case where we need
20252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	 * to have more than one breakpoint per address is return from
20352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	 * a recursive library call.  */
2042b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	struct breakpoint *sbp = dict_find_entry(leader->breakpoints, addr);
205fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata	if (sbp == NULL) {
2062b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		sbp = malloc(sizeof(*sbp));
2072b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		if (sbp == NULL
20852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata		    || breakpoint_init(sbp, proc, addr, libsym) < 0) {
20952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata			free(sbp);
21052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata			return NULL;
21152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata		}
212fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machata		if (proc_add_breakpoint(leader, sbp) < 0) {
21352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata		fail:
21452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata			breakpoint_destroy(sbp);
2152b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			free(sbp);
2162b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			return NULL;
217cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes		}
2185b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes	}
2192b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata
2204572877d0dd0b5060f4498e705467eaef51c6459Petr Machata	if (breakpoint_turn_on(sbp, proc) < 0) {
2214572877d0dd0b5060f4498e705467eaef51c6459Petr Machata		proc_remove_breakpoint(leader, sbp);
22252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata		goto fail;
2234572877d0dd0b5060f4498e705467eaef51c6459Petr Machata	}
2249294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machata
2259294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machata	return sbp;
2265b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes}
2275b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
228f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid
229fed1e8d33ab050df892a88110e1a316d285ee650Petr Machatadelete_breakpoint(Process *proc, void *addr)
230fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{
2319294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machata	struct breakpoint *sbp;
232cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes
233cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes	debug(DEBUG_FUNCTION, "delete_breakpoint(pid=%d, addr=%p)", proc->pid, addr);
234cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes
2359a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	Process * leader = proc->leader;
2369a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	assert(leader != NULL);
2379a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2389a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	sbp = dict_find_entry(leader->breakpoints, addr);
2392d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	assert(sbp);		/* FIXME: remove after debugging has been done. */
2405b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes	/* This should only happen on out-of-memory conditions. */
2412d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	if (sbp == NULL)
2422d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand		return;
2435b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
244fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machata	if (breakpoint_turn_off(sbp, proc) < 0) {
24552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata		fprintf(stderr, "Couldn't turn off the breakpoint %s@%p\n",
24652dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata			breakpoint_name(sbp), sbp->addr);
24752dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata		return;
24852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	}
2495b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes}
2505b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
251e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machataconst char *
252e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machatabreakpoint_name(const struct breakpoint *bp)
253e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata{
254e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata	assert(bp != NULL);
255e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata	return bp->libsym != NULL ? bp->libsym->name : NULL;
256e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata}
257e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata
25852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machatastruct library *
25952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machatabreakpoint_library(const struct breakpoint *bp)
26052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata{
26152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	assert(bp != NULL);
26252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	return bp->libsym != NULL ? bp->libsym->lib : NULL;
26352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata}
26452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata
265f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesstatic void
266fed1e8d33ab050df892a88110e1a316d285ee650Petr Machataenable_bp_cb(void *addr, void *sbp, void *proc)
267fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{
268cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes	debug(DEBUG_FUNCTION, "enable_bp_cb(pid=%d)", ((Process *)proc)->pid);
269bc37326ace5c70e57928c000162cffbcca9afb77Petr Machata	if (((struct breakpoint *)sbp)->enabled)
270f789c9c0d1f3301afad66e5f0520b9093665f242Petr Machata		enable_breakpoint(proc, sbp);
2715b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes}
2725b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
273f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid
274bc37326ace5c70e57928c000162cffbcca9afb77Petr Machataenable_all_breakpoints(Process *proc)
275bc37326ace5c70e57928c000162cffbcca9afb77Petr Machata{
276cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes	debug(DEBUG_FUNCTION, "enable_all_breakpoints(pid=%d)", proc->pid);
277f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes
27861196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata	debug(1, "Enabling breakpoints for pid %u...", proc->pid);
27961196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata	if (proc->breakpoints) {
28061196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata		dict_apply_to_all(proc->breakpoints, enable_bp_cb,
28161196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata				  proc);
28261196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata	}
2831228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl#ifdef __mips__
28461196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata	{
28561196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata		/*
28661196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata		 * I'm sure there is a nicer way to do this. We need to
28761196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata		 * insert breakpoints _after_ the child has been started.
28861196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata		 */
28961196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata		struct library_symbol *sym;
29061196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata		struct library_symbol *new_sym;
29161196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata		sym=proc->list_of_symbols;
29261196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata		while(sym){
29361196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			void *addr= sym2addr(proc,sym);
29461196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			if(!addr){
29561196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata				sym=sym->next;
29661196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata				continue;
29761196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			}
29861196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			if(dict_find_entry(proc->breakpoints,addr)){
299a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes				sym=sym->next;
30061196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata				continue;
301a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes			}
30261196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			debug(2,"inserting bp %p %s",addr,sym->name);
30361196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			new_sym=malloc(sizeof(*new_sym) + strlen(sym->name) + 1);
30461196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			memcpy(new_sym,sym,sizeof(*new_sym) + strlen(sym->name) + 1);
30561196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			new_sym->next=proc->list_of_symbols;
30661196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			proc->list_of_symbols=new_sym;
30761196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			insert_breakpoint(proc, addr, new_sym);
30861196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			sym=sym->next;
309a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes		}
3105e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	}
31161196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata#endif
3125e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes}
3135e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes
314f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesstatic void
315fed1e8d33ab050df892a88110e1a316d285ee650Petr Machatadisable_bp_cb(void *addr, void *sbp, void *proc)
316fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{
317cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes	debug(DEBUG_FUNCTION, "disable_bp_cb(pid=%d)", ((Process *)proc)->pid);
318bc37326ace5c70e57928c000162cffbcca9afb77Petr Machata	if (((struct breakpoint *)sbp)->enabled)
319f789c9c0d1f3301afad66e5f0520b9093665f242Petr Machata		disable_breakpoint(proc, sbp);
3205b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes}
3215b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
322f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid
323a8909f71e1421949c960f287217be6c42c286c0fJuan Cespedesdisable_all_breakpoints(Process *proc) {
324cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes	debug(DEBUG_FUNCTION, "disable_all_breakpoints(pid=%d)", proc->pid);
3259a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	assert(proc->leader == proc);
32661196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata	dict_apply_to_all(proc->breakpoints, disable_bp_cb, proc);
3275e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes}
3287186e2af704f4458e6383e8a92482594db29b597Juan Cespedes
329d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata/* XXX This is not currently properly supported.  On clone, this is
330d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * just sliced.  Hopefully at the point that clone is done, this
331d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * breakpoint is not necessary anymore.  If this use case ends up
332d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * being important, we need to add a clone and destroy callbacks to
333d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * breakpoints, and we should also probably drop arch_breakpoint_data
334d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * so that we don't end up with two different customization mechanisms
335d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * for one structure.  */
33652dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machatastruct entry_breakpoint {
33752dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	struct breakpoint super;
33852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	target_address_t dyn_addr;
33952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata};
34052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata
34102648a119092bb5b64918063521237f257283c72Petr Machatastatic void
34212affff3c88731a0880690442485494e540f7a58Petr Machataentry_breakpoint_on_hit(struct breakpoint *a, struct Process *proc)
34302648a119092bb5b64918063521237f257283c72Petr Machata{
3440092820afcd45fe045ccc294b061bce8da00a1f2Petr Machata	fprintf(stderr, "entry_breakpoint_on_hit\n");
34552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	struct entry_breakpoint *bp = (void *)a;
34602648a119092bb5b64918063521237f257283c72Petr Machata	if (proc == NULL || proc->leader == NULL)
34702648a119092bb5b64918063521237f257283c72Petr Machata		return;
3483fd099b71ae9e0c4fe9f48a239523e7037e4baf4Petr Machata	delete_breakpoint(proc, bp->super.addr);
34952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	linkmap_init(proc, bp->dyn_addr);
35093d95dff48698b8bde511c7f71acda7646da2626Petr Machata	arch_dynlink_done(proc);
35152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata}
35252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata
35352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machataint
35452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machataentry_breakpoint_init(struct Process *proc,
3559a04d0ef18b9d019b87ba10adee27f41980b286fPetr Machata		      struct entry_breakpoint *bp, target_address_t addr,
3569a04d0ef18b9d019b87ba10adee27f41980b286fPetr Machata		      struct library *lib)
35752dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata{
35852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	int err;
35952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	if ((err = breakpoint_init(&bp->super, proc, addr, NULL)) < 0)
36052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata		return err;
36152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata
36252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	static struct bp_callbacks entry_callbacks = {
36312affff3c88731a0880690442485494e540f7a58Petr Machata		.on_hit = entry_breakpoint_on_hit,
36452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	};
36552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	bp->super.cbs = &entry_callbacks;
3669a04d0ef18b9d019b87ba10adee27f41980b286fPetr Machata	bp->dyn_addr = lib->dyn_addr;
36752dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	return 0;
36802648a119092bb5b64918063521237f257283c72Petr Machata}
36902648a119092bb5b64918063521237f257283c72Petr Machata
3701974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machataint
37175934ad3b30790f6a892069576d0790a351ef101Petr Machatabreakpoints_init(Process *proc)
372c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata{
373cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes	debug(DEBUG_FUNCTION, "breakpoints_init(pid=%d)", proc->pid);
3742662768efe599f6bb43c4310177e30f56b601bb7Petr Machata
3752b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	/* XXX breakpoint dictionary should be initialized
3762b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	 * outside.  Here we just put in breakpoints.  */
3772b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	assert(proc->breakpoints != NULL);
3787186e2af704f4458e6383e8a92482594db29b597Juan Cespedes
3792b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	/* Only the thread group leader should hold the breakpoints.  */
3802b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	assert(proc->leader == proc);
3813d7e4b8d6119c1cda159e2665b40b6dcd4052e85Petr Machata
382807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	/* N.B. the following used to be conditional on this, and
383807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	 * maybe it still needs to be.  */
384807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	assert(proc->filename != NULL);
385807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata
386807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	struct library *lib = ltelf_read_main_binary(proc, proc->filename);
387807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	struct entry_breakpoint *entry_bp = NULL;
388807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	int bp_state = 0;
389807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	int result = -1;
390807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	switch (lib != NULL) {
391807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	fail:
392807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		switch (bp_state) {
393807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		case 2:
394a24163658be2cc9249621701e6d056df0063f52fPetr Machata			proc_remove_library(proc, lib);
395807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata			proc_remove_breakpoint(proc, &entry_bp->super);
396807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		case 1:
397807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata			breakpoint_destroy(&entry_bp->super);
3981974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata		}
399a24163658be2cc9249621701e6d056df0063f52fPetr Machata		library_destroy(lib);
400807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		free(entry_bp);
401807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	case 0:
402807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		return result;
403807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	}
40452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata
405807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	entry_bp = malloc(sizeof(*entry_bp));
406807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	if (entry_bp == NULL
407807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	    || (result = entry_breakpoint_init(proc, entry_bp,
408807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata					       lib->entry, lib)) < 0)
409807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		goto fail;
410807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	++bp_state;
4110092820afcd45fe045ccc294b061bce8da00a1f2Petr Machata
412807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	if ((result = proc_add_breakpoint(proc, &entry_bp->super)) < 0)
413807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		goto fail;
414807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	++bp_state;
4150092820afcd45fe045ccc294b061bce8da00a1f2Petr Machata
416fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machata	if ((result = breakpoint_turn_on(&entry_bp->super, proc)) < 0)
417807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		goto fail;
418a24163658be2cc9249621701e6d056df0063f52fPetr Machata	proc_add_library(proc, lib);
419a24163658be2cc9249621701e6d056df0063f52fPetr Machata
4207186e2af704f4458e6383e8a92482594db29b597Juan Cespedes	proc->callstack_depth = 0;
4211974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata	return 0;
4227186e2af704f4458e6383e8a92482594db29b597Juan Cespedes}
423