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