1e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata/* 2e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * This file is part of ltrace. 356134ff5442bee4e128b189bb86cfc97dcb6f60aPetr Machata * Copyright (C) 2006,2007,2011,2012,2013,2014 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 8856134ff5442bee4e128b189bb86cfc97dcb6f60aPetr Machatavoid 8956134ff5442bee4e128b189bb86cfc97dcb6f60aPetr Machatabreakpoint_on_install(struct breakpoint *bp, struct process *proc) 9056134ff5442bee4e128b189bb86cfc97dcb6f60aPetr Machata{ 9156134ff5442bee4e128b189bb86cfc97dcb6f60aPetr Machata assert(bp != NULL); 9256134ff5442bee4e128b189bb86cfc97dcb6f60aPetr Machata if (bp->cbs != NULL && bp->cbs->on_install != NULL) 9356134ff5442bee4e128b189bb86cfc97dcb6f60aPetr Machata (bp->cbs->on_install)(bp, proc); 9456134ff5442bee4e128b189bb86cfc97dcb6f60aPetr Machata} 9556134ff5442bee4e128b189bb86cfc97dcb6f60aPetr Machata 96cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machataint 97cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machatabreakpoint_get_return_bp(struct breakpoint **ret, 98cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata struct breakpoint *bp, struct process *proc) 99cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata{ 100cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata assert(bp != NULL); 101cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata if (bp->cbs != NULL && bp->cbs->get_return_bp != NULL) 102cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata return (bp->cbs->get_return_bp)(ret, bp, proc); 103cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata 104cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata if ((*ret = create_default_return_bp(proc)) == NULL) 105cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata return -1; 106cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata 107cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata return 0; 108cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata} 109cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata 1105b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes/*****************************************************************************/ 1115b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 1129294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machatastruct breakpoint * 113d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machataaddress2bpstruct(struct process *proc, arch_addr_t addr) 114fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{ 1152662768efe599f6bb43c4310177e30f56b601bb7Petr Machata assert(proc != NULL); 1162662768efe599f6bb43c4310177e30f56b601bb7Petr Machata assert(proc->breakpoints != NULL); 1179a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata assert(proc->leader == proc); 118cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "address2bpstruct(pid=%d, addr=%p)", proc->pid, addr); 119d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata 12098ff309cdc98857eb30992f108439cb7d7673598Petr Machata struct breakpoint *found; 12198ff309cdc98857eb30992f108439cb7d7673598Petr Machata if (DICT_FIND_VAL(proc->breakpoints, &addr, &found) < 0) 122d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata return NULL; 12398ff309cdc98857eb30992f108439cb7d7673598Petr Machata return found; 1245b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes} 1255b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 1269f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata#ifndef OS_HAVE_BREAKPOINT_DATA 1279f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machataint 1289f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machataos_breakpoint_init(struct process *proc, struct breakpoint *sbp) 1299f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata{ 1309f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata return 0; 1319f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata} 1329f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata 1339f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machatavoid 1349f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machataos_breakpoint_destroy(struct breakpoint *sbp) 1359f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata{ 1369f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata} 1379f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata 1389f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machataint 1399f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machataos_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp) 1409f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata{ 1419f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata return 0; 1429f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata} 1439f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata#endif 1449f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata 1458cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata#ifndef ARCH_HAVE_BREAKPOINT_DATA 1462b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machataint 147929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_breakpoint_init(struct process *proc, struct breakpoint *sbp) 1482b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata{ 1492b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata return 0; 1502b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata} 1518cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata 1528cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machatavoid 1538cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machataarch_breakpoint_destroy(struct breakpoint *sbp) 1548cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata{ 1558cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata} 156d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata 157d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machataint 158d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machataarch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp) 159d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata{ 160d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata return 0; 161d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata} 1622b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata#endif 1632b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata 164d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machatastatic void 165e50355295eac26e15db259fbb7ff705487b501d0Petr Machatabreakpoint_init_base(struct breakpoint *bp, 166bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata arch_addr_t addr, struct library_symbol *libsym) 167d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata{ 168d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata bp->cbs = NULL; 169d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata bp->addr = addr; 170d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata memset(bp->orig_value, 0, sizeof(bp->orig_value)); 171d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata bp->enabled = 0; 172d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata bp->libsym = libsym; 173d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata} 174d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata 17552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata/* On second thought, I don't think we need PROC. All the translation 17652dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * (arch_translate_address in particular) should be doable using 17752dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * static lookups of various sections in the ELF file. We shouldn't 17852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * need process for anything. */ 1792b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machataint 180929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoint_init(struct breakpoint *bp, struct process *proc, 181bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata arch_addr_t addr, struct library_symbol *libsym) 1822b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata{ 183e50355295eac26e15db259fbb7ff705487b501d0Petr Machata breakpoint_init_base(bp, addr, libsym); 1849f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata if (os_breakpoint_init(proc, bp) < 0) 1859f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata return -1; 1869f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata if (arch_breakpoint_init(proc, bp) < 0) { 1879f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata os_breakpoint_destroy(bp); 1889f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata return -1; 1899f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata } 1909f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata return 0; 1912b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata} 1922b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata 1938cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machatavoid 19455ac932f2802f85c53792153ac909dcd8a690c5cPetr Machatabreakpoint_set_callbacks(struct breakpoint *bp, struct bp_callbacks *cbs) 19555ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata{ 19655ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata if (bp->cbs != NULL) 19755ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata assert(bp->cbs == NULL); 19855ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata bp->cbs = cbs; 19955ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata} 20055ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata 20155ac932f2802f85c53792153ac909dcd8a690c5cPetr Machatavoid 2028cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machatabreakpoint_destroy(struct breakpoint *bp) 2038cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata{ 2048cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata if (bp == NULL) 2058cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata return; 206d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata arch_breakpoint_destroy(bp); 2079f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata os_breakpoint_destroy(bp); 208d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata} 2098cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata 210d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machataint 211929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoint_clone(struct breakpoint *retp, struct process *new_proc, 212e50355295eac26e15db259fbb7ff705487b501d0Petr Machata struct breakpoint *bp) 213d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata{ 214165b566a50b2bd560af3bd9649e456915397066bPetr Machata struct library_symbol *libsym = NULL; 215165b566a50b2bd560af3bd9649e456915397066bPetr Machata if (bp->libsym != NULL) { 216165b566a50b2bd560af3bd9649e456915397066bPetr Machata int rc = proc_find_symbol(new_proc, bp->libsym, NULL, &libsym); 217165b566a50b2bd560af3bd9649e456915397066bPetr Machata assert(rc == 0); 218d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata } 219d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata 220e50355295eac26e15db259fbb7ff705487b501d0Petr Machata breakpoint_init_base(retp, bp->addr, libsym); 221d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata memcpy(retp->orig_value, bp->orig_value, sizeof(bp->orig_value)); 222d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata retp->enabled = bp->enabled; 2239f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata if (os_breakpoint_clone(retp, bp) < 0) 224d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata return -1; 2259f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata if (arch_breakpoint_clone(retp, bp) < 0) { 2269f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata os_breakpoint_destroy(retp); 2279f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata return -1; 2289f819d5747dc2b8e0f7ac54b38dc321115de6ddaPetr Machata } 229d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata breakpoint_set_callbacks(retp, bp->cbs); 230d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata return 0; 2318cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata} 2328cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata 23352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machataint 234929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoint_turn_on(struct breakpoint *bp, struct process *proc) 23552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata{ 23652dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata bp->enabled++; 23752dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata if (bp->enabled == 1) { 238fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machata assert(proc->pid != 0); 239fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machata enable_breakpoint(proc, bp); 24056134ff5442bee4e128b189bb86cfc97dcb6f60aPetr Machata breakpoint_on_install(bp, proc); 24152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata } 24252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata return 0; 24352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata} 24452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata 24552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machataint 246929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoint_turn_off(struct breakpoint *bp, struct process *proc) 24752dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata{ 24852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata bp->enabled--; 24952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata if (bp->enabled == 0) 250fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machata disable_breakpoint(proc, bp); 25152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata assert(bp->enabled >= 0); 25252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata return 0; 25352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata} 25452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata 2559294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machatastruct breakpoint * 256cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machatacreate_default_return_bp(struct process *proc) 257cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata{ 258cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata struct breakpoint *bp = malloc(sizeof *bp); 259cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata arch_addr_t return_addr = get_return_addr(proc, proc->stack_pointer); 260cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata if (return_addr == 0 || bp == NULL 261cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata || breakpoint_init(bp, proc, return_addr, NULL) < 0) { 262cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata free(bp); 263cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata return NULL; 264cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata } 265cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata return bp; 266cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata} 267cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machata 268cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9Petr Machatastruct breakpoint * 26902a796e5e49c147982020c78b0066930e979f3e4Petr Machatainsert_breakpoint_at(struct process *proc, arch_addr_t addr, 27002a796e5e49c147982020c78b0066930e979f3e4Petr Machata struct library_symbol *libsym) 271fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{ 27202a796e5e49c147982020c78b0066930e979f3e4Petr Machata debug(DEBUG_FUNCTION, 27302a796e5e49c147982020c78b0066930e979f3e4Petr Machata "insert_breakpoint_at(pid=%d, addr=%p, symbol=%s)", 274050b0a6fd01fc01952c0ab8dbb84d6eba65c71c9Petr Machata proc->pid, addr, libsym ? libsym->name : "NULL"); 2755b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 276218c5ff26841f5bbd188c42ccbd67422a7a20556Petr Machata assert(addr != 0); 2779a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand 278dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata struct breakpoint *bp = malloc(sizeof *bp); 279dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata if (bp == NULL || breakpoint_init(bp, proc, addr, libsym) < 0) { 280dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata free(bp); 281f9d93c50bd246ea7fd42e0c8ad24aa01467e76acPetr Machata return NULL; 282dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata } 283dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata 284dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata /* N.B. (and XXX): BP->addr might differ from ADDR. On ARM 285dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata * this is a real possibility. The problem here is that to 286dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata * create a return breakpoint ltrace calls get_return_addr and 287dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata * then insert_breakpoint_at. So get_return_addr needs to 288dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata * encode all the information necessary for breakpoint_init 289dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata * into the address itself, so ADDR is potentially 290dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata * mangled. */ 291dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata 292dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata struct breakpoint *tmp = insert_breakpoint(proc, bp); 293dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata if (tmp != bp) { 294dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata breakpoint_destroy(bp); 295dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata free(bp); 296dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata } 297dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata return tmp; 298dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata} 299dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata 300dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machatastruct breakpoint * 301dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machatainsert_breakpoint(struct process *proc, struct breakpoint *bp) 302dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata{ 303dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata /* Only the group leader should be getting the breakpoints and 304dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata * thus have ->breakpoint initialized. */ 305dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata struct process *leader = proc->leader; 306dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata assert(leader != NULL); 307dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata assert(leader->breakpoints != NULL); 308f9d93c50bd246ea7fd42e0c8ad24aa01467e76acPetr Machata 30952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata /* XXX what we need to do instead is have a list of 31052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * breakpoints that are enabled at this address. The 31152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * following works if every breakpoint is the same and there's 31252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * no extra data, but that doesn't hold anymore. For now it 31352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * will suffice, about the only realistic case where we need 31452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * to have more than one breakpoint per address is return from 31552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * a recursive library call. */ 316dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata struct breakpoint *ext_bp = bp; 317dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata if (DICT_FIND_VAL(leader->breakpoints, &bp->addr, &ext_bp) != 0) { 318dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata if (proc_add_breakpoint(leader, bp) < 0) 3192b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata return NULL; 320dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata ext_bp = bp; 3215b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes } 3222b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata 323dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata if (breakpoint_turn_on(ext_bp, proc) < 0) { 324dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata if (ext_bp != bp) 325dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata proc_remove_breakpoint(leader, bp); 326dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata return NULL; 3274572877d0dd0b5060f4498e705467eaef51c6459Petr Machata } 3289294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machata 329dad1b779e2ed29c9fce17853ca71cb719240b9cfPetr Machata return ext_bp; 3305b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes} 3315b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 332f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid 333b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machatadelete_breakpoint_at(struct process *proc, arch_addr_t addr) 334fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{ 335b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata debug(DEBUG_FUNCTION, "delete_breakpoint_at(pid=%d, addr=%p)", 336b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata proc->pid, addr); 337cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes 338929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata struct process *leader = proc->leader; 3399a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata assert(leader != NULL); 3409a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata 341b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata struct breakpoint *bp = NULL; 342b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata DICT_FIND_VAL(leader->breakpoints, &addr, &bp); 343b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata assert(bp != NULL); 3445b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 345b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata if (delete_breakpoint(proc, bp) < 0) { 34652dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata fprintf(stderr, "Couldn't turn off the breakpoint %s@%p\n", 347b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata breakpoint_name(bp), bp->addr); 34852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata } 349b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata} 350b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata 351b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machataint 352b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machatadelete_breakpoint(struct process *proc, struct breakpoint *bp) 353b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata{ 354b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata struct process *leader = proc->leader; 355b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata assert(leader != NULL); 356b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata 357b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata if (breakpoint_turn_off(bp, proc) < 0) 358b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata return -1; 359b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata 360b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata if (bp->enabled == 0) { 361b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata proc_remove_breakpoint(leader, bp); 362b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata breakpoint_destroy(bp); 363b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata free(bp); 364f7fee43f72667f453bba5aaeea6b5490ece6792aPetr Machata } 365b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata 366b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata return 0; 3675b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes} 3685b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 369e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machataconst char * 370e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machatabreakpoint_name(const struct breakpoint *bp) 371e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata{ 372e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata assert(bp != NULL); 373e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata return bp->libsym != NULL ? bp->libsym->name : NULL; 374e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata} 375e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata 37652dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machatastruct library * 37752dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machatabreakpoint_library(const struct breakpoint *bp) 37852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata{ 37952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata assert(bp != NULL); 38052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata return bp->libsym != NULL ? bp->libsym->lib : NULL; 38152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata} 38252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata 383d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machatastatic enum callback_status 384d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machatadisable_bp_cb(arch_addr_t *addr, struct breakpoint **bpp, void *data) 385fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{ 386d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata struct process *proc = data; 387d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata debug(DEBUG_FUNCTION, "disable_bp_cb(pid=%d)", proc->pid); 388d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata if ((*bpp)->enabled) 389d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata disable_breakpoint(proc, *bpp); 390d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata return CBS_CONT; 3915b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes} 3925b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 393f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid 394929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatadisable_all_breakpoints(struct process *proc) 395929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata{ 396cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "disable_all_breakpoints(pid=%d)", proc->pid); 3979a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata assert(proc->leader == proc); 398d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata DICT_EACH(proc->breakpoints, arch_addr_t, struct breakpoint *, 399d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata NULL, disable_bp_cb, proc); 4005e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes} 4017186e2af704f4458e6383e8a92482594db29b597Juan Cespedes 40202648a119092bb5b64918063521237f257283c72Petr Machatastatic void 403df2c88cec5bf17a92f0d5d740e3b756f00b798c6Petr Machataentry_breakpoint_on_hit(struct breakpoint *bp, struct process *proc) 40402648a119092bb5b64918063521237f257283c72Petr Machata{ 40502648a119092bb5b64918063521237f257283c72Petr Machata if (proc == NULL || proc->leader == NULL) 40602648a119092bb5b64918063521237f257283c72Petr Machata return; 407b94407705ecddffd7820ee61bcad3f0d72ee87c1Petr Machata delete_breakpoint_at(proc, bp->addr); 408df2c88cec5bf17a92f0d5d740e3b756f00b798c6Petr Machata process_hit_start(proc); 40952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata} 41052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata 41152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machataint 412929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataentry_breakpoint_init(struct process *proc, 413df2c88cec5bf17a92f0d5d740e3b756f00b798c6Petr Machata struct breakpoint *bp, arch_addr_t addr, 4149a04d0ef18b9d019b87ba10adee27f41980b286fPetr Machata struct library *lib) 41552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata{ 4161c79025768a4403e016cc59d7f41b266e868c9e6Petr Machata assert(addr != 0); 417df2c88cec5bf17a92f0d5d740e3b756f00b798c6Petr Machata int err = breakpoint_init(bp, proc, addr, NULL); 4181c79025768a4403e016cc59d7f41b266e868c9e6Petr Machata if (err < 0) 41952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata return err; 42052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata 42152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata static struct bp_callbacks entry_callbacks = { 42212affff3c88731a0880690442485494e540f7a58Petr Machata .on_hit = entry_breakpoint_on_hit, 42352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata }; 424df2c88cec5bf17a92f0d5d740e3b756f00b798c6Petr Machata bp->cbs = &entry_callbacks; 42552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata return 0; 42602648a119092bb5b64918063521237f257283c72Petr Machata} 42702648a119092bb5b64918063521237f257283c72Petr Machata 4281974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machataint 429929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoints_init(struct process *proc) 430c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata{ 431cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "breakpoints_init(pid=%d)", proc->pid); 4322662768efe599f6bb43c4310177e30f56b601bb7Petr Machata 4332b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata /* XXX breakpoint dictionary should be initialized 4342b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata * outside. Here we just put in breakpoints. */ 4352b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata assert(proc->breakpoints != NULL); 4367186e2af704f4458e6383e8a92482594db29b597Juan Cespedes 4372b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata /* Only the thread group leader should hold the breakpoints. */ 4382b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata assert(proc->leader == proc); 4393d7e4b8d6119c1cda159e2665b40b6dcd4052e85Petr Machata 440807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata /* N.B. the following used to be conditional on this, and 441807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata * maybe it still needs to be. */ 442807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata assert(proc->filename != NULL); 443807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata 444807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata struct library *lib = ltelf_read_main_binary(proc, proc->filename); 445df2c88cec5bf17a92f0d5d740e3b756f00b798c6Petr Machata struct breakpoint *entry_bp = NULL; 446807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata int bp_state = 0; 447807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata int result = -1; 4486bb420106f77ef8f134a1d4c001668e832f96cc9Andrey Zonov switch ((int)(lib != NULL)) { 449807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata fail: 450807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata switch (bp_state) { 451807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata case 2: 452a24163658be2cc9249621701e6d056df0063f52fPetr Machata proc_remove_library(proc, lib); 453df2c88cec5bf17a92f0d5d740e3b756f00b798c6Petr Machata proc_remove_breakpoint(proc, entry_bp); 454807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata case 1: 455df2c88cec5bf17a92f0d5d740e3b756f00b798c6Petr Machata breakpoint_destroy(entry_bp); 4561974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata } 457a24163658be2cc9249621701e6d056df0063f52fPetr Machata library_destroy(lib); 458807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata free(entry_bp); 459807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata case 0: 460807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata return result; 461807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata } 46252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata 463807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata entry_bp = malloc(sizeof(*entry_bp)); 464807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata if (entry_bp == NULL 46591c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata || (entry_breakpoint_init(proc, entry_bp, 46691c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata lib->entry, lib)) < 0) { 46791c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata fprintf(stderr, 46891c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata "Couldn't initialize entry breakpoint for PID %d.\n" 46991c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata "Some tracing events may be missed.\n", proc->pid); 47091c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata free(entry_bp); 4710092820afcd45fe045ccc294b061bce8da00a1f2Petr Machata 47291c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata } else { 47391c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata ++bp_state; 4740092820afcd45fe045ccc294b061bce8da00a1f2Petr Machata 475df2c88cec5bf17a92f0d5d740e3b756f00b798c6Petr Machata if ((result = proc_add_breakpoint(proc, entry_bp)) < 0) 47691c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata goto fail; 47791c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata ++bp_state; 47891c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata 479df2c88cec5bf17a92f0d5d740e3b756f00b798c6Petr Machata if ((result = breakpoint_turn_on(entry_bp, proc)) < 0) 48091c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata goto fail; 48191c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata } 482a24163658be2cc9249621701e6d056df0063f52fPetr Machata proc_add_library(proc, lib); 483a24163658be2cc9249621701e6d056df0063f52fPetr Machata 4847186e2af704f4458e6383e8a92482594db29b597Juan Cespedes proc->callstack_depth = 0; 4851974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata return 0; 4867186e2af704f4458e6383e8a92482594db29b597Juan Cespedes} 487