blob: 73dd63835bf64f0dbdddc012e3f74c51f6d99374 [file] [log] [blame]
Juan Cespedesd44c6b81998-09-25 14:48:42 +02001#if HAVE_CONFIG_H
2#include "config.h"
3#endif
4
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +02005#include <stdlib.h>
6#include <assert.h>
7
Juan Cespedesf1bfe202002-03-27 00:22:23 +01008#ifdef __powerpc__
9#include <sys/ptrace.h>
10#endif
11
Juan Cespedescac15c32003-01-31 18:58:58 +010012#include "ltrace.h"
13#include "options.h"
14#include "debug.h"
15#include "dict.h"
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020016
17/*****************************************************************************/
18
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010019struct breakpoint *
20address2bpstruct(struct process * proc, void * addr) {
Juan Cespedescac15c32003-01-31 18:58:58 +010021 return dict_find_entry(proc->breakpoints, addr);
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020022}
23
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010024void
25insert_breakpoint(struct process * proc, void * addr) {
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020026 struct breakpoint * sbp;
27
Juan Cespedescac15c32003-01-31 18:58:58 +010028 if (!proc->breakpoints) {
29 proc->breakpoints = dict_init(dict_key2hash_int, dict_key_cmp_int);
30 /* atexit(brk_dict_clear); */ /* why bother to do this on exit? */
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020031 }
Juan Cespedescac15c32003-01-31 18:58:58 +010032 sbp = dict_find_entry(proc->breakpoints, addr);
33 if (!sbp) {
34 sbp = malloc(sizeof(struct breakpoint));
35 if (!sbp) {
36 return; /* TODO FIXME XXX: error_mem */
37 }
38 dict_enter(proc->breakpoints, addr, sbp);
39 sbp->addr = addr;
40 sbp->enabled = 0;
41 }
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020042 sbp->enabled++;
43 if (sbp->enabled==1 && proc->pid) enable_breakpoint(proc->pid, sbp);
44}
45
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010046void
47delete_breakpoint(struct process * proc, void * addr) {
Juan Cespedescac15c32003-01-31 18:58:58 +010048 struct breakpoint * sbp = dict_find_entry(proc->breakpoints, addr);
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020049 assert(sbp); /* FIXME: remove after debugging has been done. */
50 /* This should only happen on out-of-memory conditions. */
51 if (sbp == NULL) return;
52
53 sbp->enabled--;
54 if (sbp->enabled == 0) disable_breakpoint(proc->pid, sbp);
55 assert(sbp->enabled >= 0);
56}
57
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010058static void
Juan Cespedescac15c32003-01-31 18:58:58 +010059enable_bp_cb(void * addr, void * sbp, void * proc) {
60 if (((struct breakpoint *)sbp)->enabled) {
61 enable_breakpoint(((struct process *)proc)->pid, sbp);
62 }
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020063}
64
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010065void
66enable_all_breakpoints(struct process * proc) {
Juan Cespedes5e01f651998-03-08 22:31:44 +010067 if (proc->breakpoints_enabled <= 0) {
Juan Cespedesf1bfe202002-03-27 00:22:23 +010068#ifdef __powerpc__
69 unsigned long a;
70
71 /*
72 * PPC HACK! (XXX FIXME TODO)
73 * If the dynamic linker hasn't populated the PLT then
74 * dont enable the breakpoints
75 */
Juan Cespedesde5a7eb2002-03-31 20:53:52 +020076 if (opt_L) {
77 a = ptrace(PTRACE_PEEKTEXT, proc->pid, proc->list_of_symbols->enter_addr, 0);
78 if (a == 0x0)
79 return;
80 }
Juan Cespedesf1bfe202002-03-27 00:22:23 +010081#endif
82
Juan Cespedescac15c32003-01-31 18:58:58 +010083 debug(1, "Enabling breakpoints for pid %u...", proc->pid);
84 dict_apply_to_all(proc->breakpoints, enable_bp_cb, proc);
Juan Cespedes5e01f651998-03-08 22:31:44 +010085 }
86 proc->breakpoints_enabled = 1;
87}
88
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010089static void
Juan Cespedescac15c32003-01-31 18:58:58 +010090disable_bp_cb(void * addr, void * sbp, void * proc) {
91 if (((struct breakpoint *)sbp)->enabled) {
92 disable_breakpoint(((struct process *)proc)->pid, sbp);
93 }
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020094}
95
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010096void
97disable_all_breakpoints(struct process * proc) {
Juan Cespedes5e01f651998-03-08 22:31:44 +010098 if (proc->breakpoints_enabled) {
Juan Cespedescac15c32003-01-31 18:58:58 +010099 debug(1, "Disabling breakpoints for pid %u...", proc->pid);
100 dict_apply_to_all(proc->breakpoints, disable_bp_cb, proc);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100101 }
102 proc->breakpoints_enabled = 0;
103}