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