breakpoints.c revision e50355295eac26e15db259fbb7ff705487b501d0
1e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata/*
2e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * This file is part of ltrace.
398ff309cdc98857eb30992f108439cb7d7673598Petr Machata * Copyright (C) 2006,2007,2011,2012,2013 Petr Machata, Red Hat Inc.
4e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Copyright (C) 2009 Juan Cespedes
5e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Copyright (C) 1998,2001,2002,2003,2007,2008,2009 Juan Cespedes
6e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Copyright (C) 2006 Ian Wienand
7e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata *
8e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * This program is free software; you can redistribute it and/or
9e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * modify it under the terms of the GNU General Public License as
10e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * published by the Free Software Foundation; either version 2 of the
11e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * License, or (at your option) any later version.
12e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata *
13e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * This program is distributed in the hope that it will be useful, but
14e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of
15e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * General Public License for more details.
17e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata *
18e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * You should have received a copy of the GNU General Public License
19e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * along with this program; if not, write to the Free Software
20e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * 02110-1301 USA
22e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata */
23e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata
24d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes#include "config.h"
25d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes
265b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes#include <assert.h>
272b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata#include <errno.h>
28ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include <stdio.h>
29ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include <stdlib.h>
30ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include <string.h>
315b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
32f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes#ifdef __powerpc__
33f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes#include <sys/ptrace.h>
34f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes#endif
35f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes
36ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include "backend.h"
379294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machata#include "breakpoint.h"
38ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include "debug.h"
392b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata#include "library.h"
40ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include "ltrace-elf.h"
41ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include "proc.h"
425b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
43c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata#ifndef ARCH_HAVE_TRANSLATE_ADDRESS
44c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machataint
45929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_translate_address_dyn(struct process *proc,
46bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		       arch_addr_t addr, arch_addr_t *ret)
47b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata{
48b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata	*ret = addr;
49b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata	return 0;
50b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata}
51b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata
52b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machatastruct ltelf;
53b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machataint
54b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machataarch_translate_address(struct ltelf *lte,
55bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		       arch_addr_t addr, arch_addr_t *ret)
56c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata{
57c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata	*ret = addr;
58c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata	return 0;
59c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata}
60c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata#endif
61c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata
62a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machatavoid
63929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoint_on_hit(struct breakpoint *bp, struct process *proc)
64a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata{
65a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata	assert(bp != NULL);
66a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata	if (bp->cbs != NULL && bp->cbs->on_hit != NULL)
6755ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata		(bp->cbs->on_hit)(bp, proc);
6855ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata}
6955ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata
7055ac932f2802f85c53792153ac909dcd8a690c5cPetr Machatavoid
71929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoint_on_continue(struct breakpoint *bp, struct process *proc)
7255ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata{
7355ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata	assert(bp != NULL);
7455ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata	if (bp->cbs != NULL && bp->cbs->on_continue != NULL)
7555ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata		(bp->cbs->on_continue)(bp, proc);
7655ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata	else
7755ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata		continue_after_breakpoint(proc, bp);
78a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata}
79a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata
8086d3828129e70222abdb77bdda6f31a7f1eafd5aPetr Machatavoid
81929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoint_on_retract(struct breakpoint *bp, struct process *proc)
8286d3828129e70222abdb77bdda6f31a7f1eafd5aPetr Machata{
8386d3828129e70222abdb77bdda6f31a7f1eafd5aPetr Machata	assert(bp != NULL);
8486d3828129e70222abdb77bdda6f31a7f1eafd5aPetr Machata	if (bp->cbs != NULL && bp->cbs->on_retract != NULL)
8586d3828129e70222abdb77bdda6f31a7f1eafd5aPetr Machata		(bp->cbs->on_retract)(bp, proc);
8686d3828129e70222abdb77bdda6f31a7f1eafd5aPetr Machata}
8786d3828129e70222abdb77bdda6f31a7f1eafd5aPetr Machata
885b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes/*****************************************************************************/
895b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
909294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machatastruct breakpoint *
91d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machataaddress2bpstruct(struct process *proc, arch_addr_t addr)
92fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{
932662768efe599f6bb43c4310177e30f56b601bb7Petr Machata	assert(proc != NULL);
942662768efe599f6bb43c4310177e30f56b601bb7Petr Machata	assert(proc->breakpoints != NULL);
959a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	assert(proc->leader == proc);
96cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes	debug(DEBUG_FUNCTION, "address2bpstruct(pid=%d, addr=%p)", proc->pid, addr);
97d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata
9898ff309cdc98857eb30992f108439cb7d7673598Petr Machata	struct breakpoint *found;
9998ff309cdc98857eb30992f108439cb7d7673598Petr Machata	if (DICT_FIND_VAL(proc->breakpoints, &addr, &found) < 0)
100d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata		return NULL;
10198ff309cdc98857eb30992f108439cb7d7673598Petr Machata	return found;
1025b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes}
1035b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
1048cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata#ifndef ARCH_HAVE_BREAKPOINT_DATA
1052b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machataint
106929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_breakpoint_init(struct process *proc, struct breakpoint *sbp)
1072b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata{
1082b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	return 0;
1092b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata}
1108cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata
1118cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machatavoid
1128cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machataarch_breakpoint_destroy(struct breakpoint *sbp)
1138cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata{
1148cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata}
115d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata
116d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machataint
117d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machataarch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp)
118d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata{
119d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	return 0;
120d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata}
1212b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata#endif
1222b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata
123d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machatastatic void
124e50355295eac26e15db259fbb7ff705487b501d0Petr Machatabreakpoint_init_base(struct breakpoint *bp,
125bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		     arch_addr_t addr, struct library_symbol *libsym)
126d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata{
127d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	bp->cbs = NULL;
128d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	bp->addr = addr;
129d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	memset(bp->orig_value, 0, sizeof(bp->orig_value));
130d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	bp->enabled = 0;
131d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	bp->libsym = libsym;
132d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata}
133d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata
13452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata/* On second thought, I don't think we need PROC.  All the translation
13552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * (arch_translate_address in particular) should be doable using
13652dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * static lookups of various sections in the ELF file.  We shouldn't
13752dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * need process for anything.  */
1382b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machataint
139929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoint_init(struct breakpoint *bp, struct process *proc,
140bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		arch_addr_t addr, struct library_symbol *libsym)
1412b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata{
142e50355295eac26e15db259fbb7ff705487b501d0Petr Machata	breakpoint_init_base(bp, addr, libsym);
1432b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	return arch_breakpoint_init(proc, bp);
1442b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata}
1452b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata
1468cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machatavoid
14755ac932f2802f85c53792153ac909dcd8a690c5cPetr Machatabreakpoint_set_callbacks(struct breakpoint *bp, struct bp_callbacks *cbs)
14855ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata{
14955ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata	if (bp->cbs != NULL)
15055ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata		assert(bp->cbs == NULL);
15155ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata	bp->cbs = cbs;
15255ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata}
15355ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata
15455ac932f2802f85c53792153ac909dcd8a690c5cPetr Machatavoid
1558cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machatabreakpoint_destroy(struct breakpoint *bp)
1568cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata{
1578cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata	if (bp == NULL)
1588cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata		return;
159d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	arch_breakpoint_destroy(bp);
160d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata}
1618cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata
162d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machataint
163929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoint_clone(struct breakpoint *retp, struct process *new_proc,
164e50355295eac26e15db259fbb7ff705487b501d0Petr Machata		 struct breakpoint *bp)
165d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata{
166165b566a50b2bd560af3bd9649e456915397066bPetr Machata	struct library_symbol *libsym = NULL;
167165b566a50b2bd560af3bd9649e456915397066bPetr Machata	if (bp->libsym != NULL) {
168165b566a50b2bd560af3bd9649e456915397066bPetr Machata		int rc = proc_find_symbol(new_proc, bp->libsym, NULL, &libsym);
169165b566a50b2bd560af3bd9649e456915397066bPetr Machata		assert(rc == 0);
170d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	}
171d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata
172e50355295eac26e15db259fbb7ff705487b501d0Petr Machata	breakpoint_init_base(retp, bp->addr, libsym);
173d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	memcpy(retp->orig_value, bp->orig_value, sizeof(bp->orig_value));
174d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	retp->enabled = bp->enabled;
175d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	if (arch_breakpoint_clone(retp, bp) < 0)
176d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata		return -1;
177d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	breakpoint_set_callbacks(retp, bp->cbs);
178d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata	return 0;
1798cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata}
1808cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata
18152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machataint
182929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoint_turn_on(struct breakpoint *bp, struct process *proc)
18352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata{
18452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	bp->enabled++;
18552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	if (bp->enabled == 1) {
186fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machata		assert(proc->pid != 0);
187fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machata		enable_breakpoint(proc, bp);
18852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	}
18952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	return 0;
19052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata}
19152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata
19252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machataint
193929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoint_turn_off(struct breakpoint *bp, struct process *proc)
19452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata{
19552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	bp->enabled--;
19652dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	if (bp->enabled == 0)
197fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machata		disable_breakpoint(proc, bp);
19852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	assert(bp->enabled >= 0);
19952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	return 0;
20052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata}
20152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata
2029294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machatastruct breakpoint *
203d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machatainsert_breakpoint(struct process *proc, arch_addr_t addr,
2049df15016447915a61526af8cb81c588913bcf44cPetr Machata		  struct library_symbol *libsym)
205fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{
206929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata	struct process *leader = proc->leader;
2079a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2089a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	/* Only the group leader should be getting the breakpoints and
2099a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	 * thus have ->breakpoint initialized.  */
2109a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	assert(leader != NULL);
2119a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	assert(leader->breakpoints != NULL);
2129a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
213050b0a6fd01fc01952c0ab8dbb84d6eba65c71c9Petr Machata	debug(DEBUG_FUNCTION, "insert_breakpoint(pid=%d, addr=%p, symbol=%s)",
214050b0a6fd01fc01952c0ab8dbb84d6eba65c71c9Petr Machata	      proc->pid, addr, libsym ? libsym->name : "NULL");
2155b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
216218c5ff26841f5bbd188c42ccbd67422a7a20556Petr Machata	assert(addr != 0);
2179a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand
21852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	/* XXX what we need to do instead is have a list of
21952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	 * breakpoints that are enabled at this address.  The
22052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	 * following works if every breakpoint is the same and there's
22152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	 * no extra data, but that doesn't hold anymore.  For now it
22252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	 * will suffice, about the only realistic case where we need
22352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	 * to have more than one breakpoint per address is return from
22452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	 * a recursive library call.  */
225d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata	struct breakpoint *bp;
22698ff309cdc98857eb30992f108439cb7d7673598Petr Machata	if (DICT_FIND_VAL(leader->breakpoints, &addr, &bp) < 0) {
227d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata		bp = malloc(sizeof(*bp));
228d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata		if (bp == NULL
229d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata		    || breakpoint_init(bp, proc, addr, libsym) < 0) {
230d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata			free(bp);
23152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata			return NULL;
23252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata		}
233d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata		if (proc_add_breakpoint(leader, bp) < 0) {
23452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata		fail:
235d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata			breakpoint_destroy(bp);
236d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata			free(bp);
2372b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			return NULL;
238cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes		}
2395b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes	}
2402b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata
241d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata	if (breakpoint_turn_on(bp, proc) < 0) {
242d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata		proc_remove_breakpoint(leader, bp);
24352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata		goto fail;
2444572877d0dd0b5060f4498e705467eaef51c6459Petr Machata	}
2459294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machata
246d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata	return bp;
2475b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes}
2485b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
249f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid
250d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machatadelete_breakpoint(struct process *proc, arch_addr_t addr)
251fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{
252cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes	debug(DEBUG_FUNCTION, "delete_breakpoint(pid=%d, addr=%p)", proc->pid, addr);
253cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes
254929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata	struct process *leader = proc->leader;
2559a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	assert(leader != NULL);
2569a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
25798ff309cdc98857eb30992f108439cb7d7673598Petr Machata	struct breakpoint *sbp = NULL;
25898ff309cdc98857eb30992f108439cb7d7673598Petr Machata	DICT_FIND_VAL(leader->breakpoints, &addr, &sbp);
259f7fee43f72667f453bba5aaeea6b5490ece6792aPetr Machata	assert(sbp != NULL);
2605b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
261fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machata	if (breakpoint_turn_off(sbp, proc) < 0) {
26252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata		fprintf(stderr, "Couldn't turn off the breakpoint %s@%p\n",
26352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata			breakpoint_name(sbp), sbp->addr);
26452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata		return;
26552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	}
266f7fee43f72667f453bba5aaeea6b5490ece6792aPetr Machata	if (sbp->enabled == 0) {
267f7fee43f72667f453bba5aaeea6b5490ece6792aPetr Machata		proc_remove_breakpoint(leader, sbp);
268f7fee43f72667f453bba5aaeea6b5490ece6792aPetr Machata		breakpoint_destroy(sbp);
269f7fee43f72667f453bba5aaeea6b5490ece6792aPetr Machata		free(sbp);
270f7fee43f72667f453bba5aaeea6b5490ece6792aPetr Machata	}
2715b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes}
2725b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
273e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machataconst char *
274e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machatabreakpoint_name(const struct breakpoint *bp)
275e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata{
276e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata	assert(bp != NULL);
277e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata	return bp->libsym != NULL ? bp->libsym->name : NULL;
278e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata}
279e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata
28052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machatastruct library *
28152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machatabreakpoint_library(const struct breakpoint *bp)
28252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata{
28352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	assert(bp != NULL);
28452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	return bp->libsym != NULL ? bp->libsym->lib : NULL;
28552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata}
28652dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata
287d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machatastatic enum callback_status
288d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machataenable_bp_cb(arch_addr_t *addr, struct breakpoint **bpp, void *data)
289fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{
290d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata	struct process *proc = data;
291d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata	debug(DEBUG_FUNCTION, "enable_bp_cb(pid=%d)", proc->pid);
292d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata	if ((*bpp)->enabled)
293d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata		enable_breakpoint(proc, *bpp);
294d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata	return CBS_CONT;
2955b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes}
2965b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
297f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid
298929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataenable_all_breakpoints(struct process *proc)
299bc37326ace5c70e57928c000162cffbcca9afb77Petr Machata{
300cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes	debug(DEBUG_FUNCTION, "enable_all_breakpoints(pid=%d)", proc->pid);
301f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes
30261196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata	debug(1, "Enabling breakpoints for pid %u...", proc->pid);
303d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata	if (proc->breakpoints != NULL)
304d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata		DICT_EACH(proc->breakpoints, arch_addr_t, struct breakpoint *,
305d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata			  NULL, enable_bp_cb, proc);
3065e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes}
3075e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes
308d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machatastatic enum callback_status
309d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machatadisable_bp_cb(arch_addr_t *addr, struct breakpoint **bpp, void *data)
310fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{
311d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata	struct process *proc = data;
312d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata	debug(DEBUG_FUNCTION, "disable_bp_cb(pid=%d)", proc->pid);
313d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata	if ((*bpp)->enabled)
314d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata		disable_breakpoint(proc, *bpp);
315d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata	return CBS_CONT;
3165b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes}
3175b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes
318f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid
319929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatadisable_all_breakpoints(struct process *proc)
320929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata{
321cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes	debug(DEBUG_FUNCTION, "disable_all_breakpoints(pid=%d)", proc->pid);
3229a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	assert(proc->leader == proc);
323d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata	DICT_EACH(proc->breakpoints, arch_addr_t, struct breakpoint *,
324d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata		  NULL, disable_bp_cb, proc);
3255e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes}
3267186e2af704f4458e6383e8a92482594db29b597Juan Cespedes
327d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata/* XXX This is not currently properly supported.  On clone, this is
328d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * just sliced.  Hopefully at the point that clone is done, this
329d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * breakpoint is not necessary anymore.  If this use case ends up
330d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * being important, we need to add a clone and destroy callbacks to
331d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * breakpoints, and we should also probably drop arch_breakpoint_data
332d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * so that we don't end up with two different customization mechanisms
333d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * for one structure.  */
33452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machatastruct entry_breakpoint {
33552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	struct breakpoint super;
336bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata	arch_addr_t dyn_addr;
33752dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata};
33852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata
33902648a119092bb5b64918063521237f257283c72Petr Machatastatic void
340929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataentry_breakpoint_on_hit(struct breakpoint *a, struct process *proc)
34102648a119092bb5b64918063521237f257283c72Petr Machata{
34252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	struct entry_breakpoint *bp = (void *)a;
34302648a119092bb5b64918063521237f257283c72Petr Machata	if (proc == NULL || proc->leader == NULL)
34402648a119092bb5b64918063521237f257283c72Petr Machata		return;
345bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata	arch_addr_t dyn_addr = bp->dyn_addr;
3463fd099b71ae9e0c4fe9f48a239523e7037e4baf4Petr Machata	delete_breakpoint(proc, bp->super.addr);
3475ee368270823922ee2a11f0637a355641f6af457Petr Machata	linkmap_init(proc, dyn_addr);
34893d95dff48698b8bde511c7f71acda7646da2626Petr Machata	arch_dynlink_done(proc);
34952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata}
35052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata
35152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machataint
352929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataentry_breakpoint_init(struct process *proc,
353bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		      struct entry_breakpoint *bp, arch_addr_t addr,
3549a04d0ef18b9d019b87ba10adee27f41980b286fPetr Machata		      struct library *lib)
35552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata{
3561c79025768a4403e016cc59d7f41b266e868c9e6Petr Machata	assert(addr != 0);
3571c79025768a4403e016cc59d7f41b266e868c9e6Petr Machata	int err = breakpoint_init(&bp->super, proc, addr, NULL);
3581c79025768a4403e016cc59d7f41b266e868c9e6Petr Machata	if (err < 0)
35952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata		return err;
36052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata
36152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	static struct bp_callbacks entry_callbacks = {
36212affff3c88731a0880690442485494e540f7a58Petr Machata		.on_hit = entry_breakpoint_on_hit,
36352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	};
36452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	bp->super.cbs = &entry_callbacks;
3659a04d0ef18b9d019b87ba10adee27f41980b286fPetr Machata	bp->dyn_addr = lib->dyn_addr;
36652dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata	return 0;
36702648a119092bb5b64918063521237f257283c72Petr Machata}
36802648a119092bb5b64918063521237f257283c72Petr Machata
3691974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machataint
370929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoints_init(struct process *proc)
371c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata{
372cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes	debug(DEBUG_FUNCTION, "breakpoints_init(pid=%d)", proc->pid);
3732662768efe599f6bb43c4310177e30f56b601bb7Petr Machata
3742b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	/* XXX breakpoint dictionary should be initialized
3752b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	 * outside.  Here we just put in breakpoints.  */
3762b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	assert(proc->breakpoints != NULL);
3777186e2af704f4458e6383e8a92482594db29b597Juan Cespedes
3782b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	/* Only the thread group leader should hold the breakpoints.  */
3792b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	assert(proc->leader == proc);
3803d7e4b8d6119c1cda159e2665b40b6dcd4052e85Petr Machata
381807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	/* N.B. the following used to be conditional on this, and
382807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	 * maybe it still needs to be.  */
383807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	assert(proc->filename != NULL);
384807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata
385807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	struct library *lib = ltelf_read_main_binary(proc, proc->filename);
386807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	struct entry_breakpoint *entry_bp = NULL;
387807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	int bp_state = 0;
388807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	int result = -1;
3896bb420106f77ef8f134a1d4c001668e832f96cc9Andrey Zonov	switch ((int)(lib != NULL)) {
390807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	fail:
391807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		switch (bp_state) {
392807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		case 2:
393a24163658be2cc9249621701e6d056df0063f52fPetr Machata			proc_remove_library(proc, lib);
394807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata			proc_remove_breakpoint(proc, &entry_bp->super);
395807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		case 1:
396807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata			breakpoint_destroy(&entry_bp->super);
3971974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata		}
398a24163658be2cc9249621701e6d056df0063f52fPetr Machata		library_destroy(lib);
399807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		free(entry_bp);
400807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	case 0:
401807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata		return result;
402807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	}
40352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata
404807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	entry_bp = malloc(sizeof(*entry_bp));
405807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata	if (entry_bp == NULL
40691c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata	    || (entry_breakpoint_init(proc, entry_bp,
40791c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata				      lib->entry, lib)) < 0) {
40891c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata		fprintf(stderr,
40991c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata			"Couldn't initialize entry breakpoint for PID %d.\n"
41091c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata			"Some tracing events may be missed.\n", proc->pid);
41191c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata		free(entry_bp);
4120092820afcd45fe045ccc294b061bce8da00a1f2Petr Machata
41391c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata	} else {
41491c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata		++bp_state;
4150092820afcd45fe045ccc294b061bce8da00a1f2Petr Machata
41691c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata		if ((result = proc_add_breakpoint(proc, &entry_bp->super)) < 0)
41791c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata			goto fail;
41891c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata		++bp_state;
41991c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata
42091c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata		if ((result = breakpoint_turn_on(&entry_bp->super, proc)) < 0)
42191c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata			goto fail;
42291c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata	}
423a24163658be2cc9249621701e6d056df0063f52fPetr Machata	proc_add_library(proc, lib);
424a24163658be2cc9249621701e6d056df0063f52fPetr Machata
4257186e2af704f4458e6383e8a92482594db29b597Juan Cespedes	proc->callstack_depth = 0;
4261974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata	return 0;
4277186e2af704f4458e6383e8a92482594db29b597Juan Cespedes}
428