breakpoints.c revision 5ee368270823922ee2a11f0637a355641f6af457
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{
231cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes	debug(DEBUG_FUNCTION, "delete_breakpoint(pid=%d, addr=%p)", proc->pid, addr);
232cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes
2339a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	Process * leader = proc->leader;
2349a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	assert(leader != NULL);
2359a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
236f7fee43f72667f453bba5aaeea6b5490ece6792aPetr Machata	struct breakpoint *sbp = dict_find_entry(leader->breakpoints, addr);
237f7fee43f72667f453bba5aaeea6b5490ece6792aPetr Machata	assert(sbp != NULL);
2385b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes	/* This should only happen on out-of-memory conditions. */
2392d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	if (sbp == NULL)
2402d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand		return;
2415b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
242fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machata	if (breakpoint_turn_off(sbp, proc) < 0) {
24352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata		fprintf(stderr, "Couldn't turn off the breakpoint %s@%p\n",
24452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata			breakpoint_name(sbp), sbp->addr);
24552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata		return;
24652dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	}
247f7fee43f72667f453bba5aaeea6b5490ece6792aPetr Machata	if (sbp->enabled == 0) {
248f7fee43f72667f453bba5aaeea6b5490ece6792aPetr Machata		proc_remove_breakpoint(leader, sbp);
249f7fee43f72667f453bba5aaeea6b5490ece6792aPetr Machata		breakpoint_destroy(sbp);
250f7fee43f72667f453bba5aaeea6b5490ece6792aPetr Machata		free(sbp);
251f7fee43f72667f453bba5aaeea6b5490ece6792aPetr Machata	}
2525b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes}
2535b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
254e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machataconst char *
255e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machatabreakpoint_name(const struct breakpoint *bp)
256e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata{
257e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata	assert(bp != NULL);
258e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata	return bp->libsym != NULL ? bp->libsym->name : NULL;
259e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata}
260e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata
26152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machatastruct library *
26252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machatabreakpoint_library(const struct breakpoint *bp)
26352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata{
26452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	assert(bp != NULL);
26552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	return bp->libsym != NULL ? bp->libsym->lib : NULL;
26652dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata}
26752dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata
268f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesstatic void
269fed1e8d33ab050df892a88110e1a316d285ee650Petr Machataenable_bp_cb(void *addr, void *sbp, void *proc)
270fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{
271cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes	debug(DEBUG_FUNCTION, "enable_bp_cb(pid=%d)", ((Process *)proc)->pid);
272bc37326ace5c70e57928c000162cffbcca9afb77Petr Machata	if (((struct breakpoint *)sbp)->enabled)
273f789c9c0d1f3301afad66e5f0520b9093665f242Petr Machata		enable_breakpoint(proc, sbp);
2745b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes}
2755b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
276f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid
277bc37326ace5c70e57928c000162cffbcca9afb77Petr Machataenable_all_breakpoints(Process *proc)
278bc37326ace5c70e57928c000162cffbcca9afb77Petr Machata{
279cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes	debug(DEBUG_FUNCTION, "enable_all_breakpoints(pid=%d)", proc->pid);
280f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes
28161196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata	debug(1, "Enabling breakpoints for pid %u...", proc->pid);
28261196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata	if (proc->breakpoints) {
28361196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata		dict_apply_to_all(proc->breakpoints, enable_bp_cb,
28461196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata				  proc);
28561196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata	}
2861228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl#ifdef __mips__
28761196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata	{
28861196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata		/*
28961196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata		 * I'm sure there is a nicer way to do this. We need to
29061196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata		 * insert breakpoints _after_ the child has been started.
29161196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata		 */
29261196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata		struct library_symbol *sym;
29361196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata		struct library_symbol *new_sym;
29461196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata		sym=proc->list_of_symbols;
29561196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata		while(sym){
29661196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			void *addr= sym2addr(proc,sym);
29761196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			if(!addr){
29861196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata				sym=sym->next;
29961196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata				continue;
30061196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			}
30161196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			if(dict_find_entry(proc->breakpoints,addr)){
302a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes				sym=sym->next;
30361196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata				continue;
304a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes			}
30561196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			debug(2,"inserting bp %p %s",addr,sym->name);
30661196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			new_sym=malloc(sizeof(*new_sym) + strlen(sym->name) + 1);
30761196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			memcpy(new_sym,sym,sizeof(*new_sym) + strlen(sym->name) + 1);
30861196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			new_sym->next=proc->list_of_symbols;
30961196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			proc->list_of_symbols=new_sym;
31061196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			insert_breakpoint(proc, addr, new_sym);
31161196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata			sym=sym->next;
312a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes		}
3135e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	}
31461196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata#endif
3155e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes}
3165e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes
317f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesstatic void
318fed1e8d33ab050df892a88110e1a316d285ee650Petr Machatadisable_bp_cb(void *addr, void *sbp, void *proc)
319fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{
320cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes	debug(DEBUG_FUNCTION, "disable_bp_cb(pid=%d)", ((Process *)proc)->pid);
321bc37326ace5c70e57928c000162cffbcca9afb77Petr Machata	if (((struct breakpoint *)sbp)->enabled)
322f789c9c0d1f3301afad66e5f0520b9093665f242Petr Machata		disable_breakpoint(proc, sbp);
3235b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes}
3245b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
325f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid
326a8909f71e1421949c960f287217be6c42c286c0fJuan Cespedesdisable_all_breakpoints(Process *proc) {
327cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes	debug(DEBUG_FUNCTION, "disable_all_breakpoints(pid=%d)", proc->pid);
3289a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	assert(proc->leader == proc);
32961196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata	dict_apply_to_all(proc->breakpoints, disable_bp_cb, proc);
3305e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes}
3317186e2af704f4458e6383e8a92482594db29b597Juan Cespedes
332d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata/* XXX This is not currently properly supported.  On clone, this is
333d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * just sliced.  Hopefully at the point that clone is done, this
334d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * breakpoint is not necessary anymore.  If this use case ends up
335d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * being important, we need to add a clone and destroy callbacks to
336d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * breakpoints, and we should also probably drop arch_breakpoint_data
337d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * so that we don't end up with two different customization mechanisms
338d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * for one structure.  */
33952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machatastruct entry_breakpoint {
34052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	struct breakpoint super;
34152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	target_address_t dyn_addr;
34252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata};
34352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata
34402648a119092bb5b64918063521237f257283c72Petr Machatastatic void
34512affff3c88731a0880690442485494e540f7a58Petr Machataentry_breakpoint_on_hit(struct breakpoint *a, struct Process *proc)
34602648a119092bb5b64918063521237f257283c72Petr Machata{
3470092820afcd45fe045ccc294b061bce8da00a1f2Petr Machata	fprintf(stderr, "entry_breakpoint_on_hit\n");
34852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	struct entry_breakpoint *bp = (void *)a;
34902648a119092bb5b64918063521237f257283c72Petr Machata	if (proc == NULL || proc->leader == NULL)
35002648a119092bb5b64918063521237f257283c72Petr Machata		return;
3515ee368270823922ee2a11f0637a355641f6af457Petr Machata	target_address_t dyn_addr = bp->dyn_addr;
3523fd099b71ae9e0c4fe9f48a239523e7037e4baf4Petr Machata	delete_breakpoint(proc, bp->super.addr);
3535ee368270823922ee2a11f0637a355641f6af457Petr Machata	linkmap_init(proc, dyn_addr);
35493d95dff48698b8bde511c7f71acda7646da2626Petr Machata	arch_dynlink_done(proc);
35552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata}
35652dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata
35752dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machataint
35852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machataentry_breakpoint_init(struct Process *proc,
3599a04d0ef18b9d019b87ba10adee27f41980b286fPetr Machata		      struct entry_breakpoint *bp, target_address_t addr,
3609a04d0ef18b9d019b87ba10adee27f41980b286fPetr Machata		      struct library *lib)
36152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata{
36252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	int err;
36352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	if ((err = breakpoint_init(&bp->super, proc, addr, NULL)) < 0)
36452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata		return err;
36552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata
36652dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	static struct bp_callbacks entry_callbacks = {
36712affff3c88731a0880690442485494e540f7a58Petr Machata		.on_hit = entry_breakpoint_on_hit,
36852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	};
36952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	bp->super.cbs = &entry_callbacks;
3709a04d0ef18b9d019b87ba10adee27f41980b286fPetr Machata	bp->dyn_addr = lib->dyn_addr;
37152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	return 0;
37202648a119092bb5b64918063521237f257283c72Petr Machata}
37302648a119092bb5b64918063521237f257283c72Petr Machata
3741974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machataint
37575934ad3b30790f6a892069576d0790a351ef101Petr Machatabreakpoints_init(Process *proc)
376c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata{
377cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes	debug(DEBUG_FUNCTION, "breakpoints_init(pid=%d)", proc->pid);
3782662768efe599f6bb43c4310177e30f56b601bb7Petr Machata
3792b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	/* XXX breakpoint dictionary should be initialized
3802b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	 * outside.  Here we just put in breakpoints.  */
3812b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	assert(proc->breakpoints != NULL);
3827186e2af704f4458e6383e8a92482594db29b597Juan Cespedes
3832b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	/* Only the thread group leader should hold the breakpoints.  */
3842b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	assert(proc->leader == proc);
3853d7e4b8d6119c1cda159e2665b40b6dcd4052e85Petr Machata
386807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	/* N.B. the following used to be conditional on this, and
387807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	 * maybe it still needs to be.  */
388807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	assert(proc->filename != NULL);
389807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata
390807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	struct library *lib = ltelf_read_main_binary(proc, proc->filename);
391807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	struct entry_breakpoint *entry_bp = NULL;
392807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	int bp_state = 0;
393807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	int result = -1;
394807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	switch (lib != NULL) {
395807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	fail:
396807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		switch (bp_state) {
397807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		case 2:
398a24163658be2cc9249621701e6d056df0063f52fPetr Machata			proc_remove_library(proc, lib);
399807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata			proc_remove_breakpoint(proc, &entry_bp->super);
400807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		case 1:
401807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata			breakpoint_destroy(&entry_bp->super);
4021974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata		}
403a24163658be2cc9249621701e6d056df0063f52fPetr Machata		library_destroy(lib);
404807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		free(entry_bp);
405807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	case 0:
406807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		return result;
407807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	}
40852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata
409807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	entry_bp = malloc(sizeof(*entry_bp));
410807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	if (entry_bp == NULL
411807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	    || (result = entry_breakpoint_init(proc, entry_bp,
412807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata					       lib->entry, lib)) < 0)
413807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		goto fail;
414807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	++bp_state;
4150092820afcd45fe045ccc294b061bce8da00a1f2Petr Machata
416807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	if ((result = proc_add_breakpoint(proc, &entry_bp->super)) < 0)
417807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		goto fail;
418807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	++bp_state;
4190092820afcd45fe045ccc294b061bce8da00a1f2Petr Machata
420fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machata	if ((result = breakpoint_turn_on(&entry_bp->super, proc)) < 0)
421807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		goto fail;
422a24163658be2cc9249621701e6d056df0063f52fPetr Machata	proc_add_library(proc, lib);
423a24163658be2cc9249621701e6d056df0063f52fPetr Machata
4247186e2af704f4458e6383e8a92482594db29b597Juan Cespedes	proc->callstack_depth = 0;
4251974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata	return 0;
4267186e2af704f4458e6383e8a92482594db29b597Juan Cespedes}
427