| Juan Cespedes | d44c6b8 | 1998-09-25 14:48:42 +0200 | [diff] [blame] | 1 | #include "config.h" | 
| Juan Cespedes | d44c6b8 | 1998-09-25 14:48:42 +0200 | [diff] [blame] | 2 |  | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 3 | #include <stdlib.h> | 
| Juan Cespedes | 7186e2a | 2003-01-31 19:56:34 +0100 | [diff] [blame] | 4 | #include <string.h> | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 5 | #include <assert.h> | 
 | 6 |  | 
| Juan Cespedes | f1bfe20 | 2002-03-27 00:22:23 +0100 | [diff] [blame] | 7 | #ifdef __powerpc__ | 
 | 8 | #include <sys/ptrace.h> | 
 | 9 | #endif | 
 | 10 |  | 
| Juan Cespedes | f728123 | 2009-06-25 16:11:21 +0200 | [diff] [blame] | 11 | #include "common.h" | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 12 |  | 
 | 13 | /*****************************************************************************/ | 
 | 14 |  | 
| Juan Cespedes | 1dec217 | 2009-05-07 10:12:10 +0200 | [diff] [blame] | 15 | Breakpoint * | 
| Juan Cespedes | a8909f7 | 2009-04-28 20:02:41 +0200 | [diff] [blame] | 16 | address2bpstruct(Process *proc, void *addr) { | 
| Petr Machata | 2662768 | 2011-07-08 18:15:32 +0200 | [diff] [blame] | 17 | 	assert(proc != NULL); | 
 | 18 | 	assert(proc->breakpoints != NULL); | 
| Petr Machata | 9a5420c | 2011-07-09 11:21:23 +0200 | [diff] [blame^] | 19 | 	assert(proc->leader == proc); | 
| Juan Cespedes | cd8976d | 2009-05-14 13:47:58 +0200 | [diff] [blame] | 20 | 	debug(DEBUG_FUNCTION, "address2bpstruct(pid=%d, addr=%p)", proc->pid, addr); | 
| Juan Cespedes | cac15c3 | 2003-01-31 18:58:58 +0100 | [diff] [blame] | 21 | 	return dict_find_entry(proc->breakpoints, addr); | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 22 | } | 
 | 23 |  | 
| Ian Wienand | 9a2ad35 | 2006-02-20 22:44:45 +0100 | [diff] [blame] | 24 | void | 
| Juan Cespedes | a8909f7 | 2009-04-28 20:02:41 +0200 | [diff] [blame] | 25 | insert_breakpoint(Process *proc, void *addr, | 
| Petr Machata | c7585b6 | 2011-07-08 22:58:12 +0200 | [diff] [blame] | 26 | 		  struct library_symbol *libsym, int enable) { | 
| Juan Cespedes | 1dec217 | 2009-05-07 10:12:10 +0200 | [diff] [blame] | 27 | 	Breakpoint *sbp; | 
| Juan Cespedes | cd8976d | 2009-05-14 13:47:58 +0200 | [diff] [blame] | 28 |  | 
| Petr Machata | 9a5420c | 2011-07-09 11:21:23 +0200 | [diff] [blame^] | 29 | 	Process * leader = proc->leader; | 
 | 30 |  | 
 | 31 | 	/* Only the group leader should be getting the breakpoints and | 
 | 32 | 	 * thus have ->breakpoint initialized.  */ | 
 | 33 | 	assert(leader != NULL); | 
 | 34 | 	assert(leader->breakpoints != NULL); | 
 | 35 |  | 
| Zachary T Welch | a2ff9d6 | 2010-10-08 11:47:49 -0700 | [diff] [blame] | 36 | #ifdef __arm__ | 
 | 37 | 	int thumb_mode = (int)addr & 1; | 
 | 38 | 	if (thumb_mode) | 
 | 39 | 		addr = (void *)((int)addr & ~1); | 
 | 40 | #endif | 
 | 41 |  | 
| Juan Cespedes | cd8976d | 2009-05-14 13:47:58 +0200 | [diff] [blame] | 42 | 	debug(DEBUG_FUNCTION, "insert_breakpoint(pid=%d, addr=%p, symbol=%s)", proc->pid, addr, libsym ? libsym->name : "NULL"); | 
| Petr Machata | b3f8fef | 2006-11-30 14:45:07 +0100 | [diff] [blame] | 43 | 	debug(1, "symbol=%s, addr=%p", libsym?libsym->name:"(nil)", addr); | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 44 |  | 
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 45 | 	if (!addr) | 
 | 46 | 		return; | 
| Ian Wienand | 9a2ad35 | 2006-02-20 22:44:45 +0100 | [diff] [blame] | 47 |  | 
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 48 | 	if (libsym) | 
| Ian Wienand | 9a2ad35 | 2006-02-20 22:44:45 +0100 | [diff] [blame] | 49 | 		libsym->needs_init = 0; | 
 | 50 |  | 
| Petr Machata | 9a5420c | 2011-07-09 11:21:23 +0200 | [diff] [blame^] | 51 | 	sbp = dict_find_entry(leader->breakpoints, addr); | 
| Juan Cespedes | cac15c3 | 2003-01-31 18:58:58 +0100 | [diff] [blame] | 52 | 	if (!sbp) { | 
| Juan Cespedes | 1dec217 | 2009-05-07 10:12:10 +0200 | [diff] [blame] | 53 | 		sbp = calloc(1, sizeof(Breakpoint)); | 
| Juan Cespedes | cac15c3 | 2003-01-31 18:58:58 +0100 | [diff] [blame] | 54 | 		if (!sbp) { | 
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 55 | 			return;	/* TODO FIXME XXX: error_mem */ | 
| Juan Cespedes | cac15c3 | 2003-01-31 18:58:58 +0100 | [diff] [blame] | 56 | 		} | 
| Petr Machata | 9a5420c | 2011-07-09 11:21:23 +0200 | [diff] [blame^] | 57 | 		dict_enter(leader->breakpoints, addr, sbp); | 
| Juan Cespedes | cac15c3 | 2003-01-31 18:58:58 +0100 | [diff] [blame] | 58 | 		sbp->addr = addr; | 
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 59 | 		sbp->libsym = libsym; | 
| Juan Cespedes | cac15c3 | 2003-01-31 18:58:58 +0100 | [diff] [blame] | 60 | 	} | 
| Juan Cespedes | 63184be | 2008-12-10 13:30:12 +0100 | [diff] [blame] | 61 | #ifdef __arm__ | 
| Zachary T Welch | a2ff9d6 | 2010-10-08 11:47:49 -0700 | [diff] [blame] | 62 | 	sbp->thumb_mode = thumb_mode | proc->thumb_mode; | 
| Juan Cespedes | 63184be | 2008-12-10 13:30:12 +0100 | [diff] [blame] | 63 | 	proc->thumb_mode = 0; | 
 | 64 | #endif | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 65 | 	sbp->enabled++; | 
| Petr Machata | c7585b6 | 2011-07-08 22:58:12 +0200 | [diff] [blame] | 66 | 	if (sbp->enabled == 1 && enable) { | 
 | 67 | 		assert(proc->pid != 0); | 
| Petr Machata | f789c9c | 2011-07-09 10:54:27 +0200 | [diff] [blame] | 68 | 		enable_breakpoint(proc, sbp); | 
| Petr Machata | c7585b6 | 2011-07-08 22:58:12 +0200 | [diff] [blame] | 69 | 	} | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 70 | } | 
 | 71 |  | 
| Juan Cespedes | f135052 | 2008-12-16 18:19:58 +0100 | [diff] [blame] | 72 | void | 
| Juan Cespedes | a8909f7 | 2009-04-28 20:02:41 +0200 | [diff] [blame] | 73 | delete_breakpoint(Process *proc, void *addr) { | 
| Juan Cespedes | cd8976d | 2009-05-14 13:47:58 +0200 | [diff] [blame] | 74 | 	Breakpoint *sbp; | 
 | 75 |  | 
 | 76 | 	debug(DEBUG_FUNCTION, "delete_breakpoint(pid=%d, addr=%p)", proc->pid, addr); | 
 | 77 |  | 
| Petr Machata | 9a5420c | 2011-07-09 11:21:23 +0200 | [diff] [blame^] | 78 | 	Process * leader = proc->leader; | 
 | 79 | 	assert(leader != NULL); | 
 | 80 |  | 
 | 81 | 	sbp = dict_find_entry(leader->breakpoints, addr); | 
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 82 | 	assert(sbp);		/* FIXME: remove after debugging has been done. */ | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 83 | 	/* This should only happen on out-of-memory conditions. */ | 
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 84 | 	if (sbp == NULL) | 
 | 85 | 		return; | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 86 |  | 
 | 87 | 	sbp->enabled--; | 
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 88 | 	if (sbp->enabled == 0) | 
| Petr Machata | f789c9c | 2011-07-09 10:54:27 +0200 | [diff] [blame] | 89 | 		disable_breakpoint(proc, sbp); | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 90 | 	assert(sbp->enabled >= 0); | 
 | 91 | } | 
 | 92 |  | 
| Juan Cespedes | f135052 | 2008-12-16 18:19:58 +0100 | [diff] [blame] | 93 | static void | 
 | 94 | enable_bp_cb(void *addr, void *sbp, void *proc) { | 
| Juan Cespedes | cd8976d | 2009-05-14 13:47:58 +0200 | [diff] [blame] | 95 | 	debug(DEBUG_FUNCTION, "enable_bp_cb(pid=%d)", ((Process *)proc)->pid); | 
| Juan Cespedes | 1dec217 | 2009-05-07 10:12:10 +0200 | [diff] [blame] | 96 | 	if (((Breakpoint *)sbp)->enabled) { | 
| Petr Machata | f789c9c | 2011-07-09 10:54:27 +0200 | [diff] [blame] | 97 | 		enable_breakpoint(proc, sbp); | 
| Juan Cespedes | cac15c3 | 2003-01-31 18:58:58 +0100 | [diff] [blame] | 98 | 	} | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 99 | } | 
 | 100 |  | 
| Juan Cespedes | f135052 | 2008-12-16 18:19:58 +0100 | [diff] [blame] | 101 | void | 
| Juan Cespedes | a8909f7 | 2009-04-28 20:02:41 +0200 | [diff] [blame] | 102 | enable_all_breakpoints(Process *proc) { | 
| Juan Cespedes | cd8976d | 2009-05-14 13:47:58 +0200 | [diff] [blame] | 103 | 	debug(DEBUG_FUNCTION, "enable_all_breakpoints(pid=%d)", proc->pid); | 
| Juan Cespedes | 5e01f65 | 1998-03-08 22:31:44 +0100 | [diff] [blame] | 104 | 	if (proc->breakpoints_enabled <= 0) { | 
| Juan Cespedes | f1bfe20 | 2002-03-27 00:22:23 +0100 | [diff] [blame] | 105 | #ifdef __powerpc__ | 
 | 106 | 		unsigned long a; | 
 | 107 |  | 
 | 108 | 		/* | 
 | 109 | 		 * PPC HACK! (XXX FIXME TODO) | 
 | 110 | 		 * If the dynamic linker hasn't populated the PLT then | 
 | 111 | 		 * dont enable the breakpoints | 
 | 112 | 		 */ | 
| Juan Cespedes | ce377d5 | 2008-12-16 19:38:10 +0100 | [diff] [blame] | 113 | 		if (options.libcalls) { | 
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 114 | 			a = ptrace(PTRACE_PEEKTEXT, proc->pid, | 
| Paul Gilliam | 76c61f1 | 2006-06-14 06:55:21 +0200 | [diff] [blame] | 115 | 				   sym2addr(proc, proc->list_of_symbols), | 
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 116 | 				   0); | 
| Juan Cespedes | de5a7eb | 2002-03-31 20:53:52 +0200 | [diff] [blame] | 117 | 			if (a == 0x0) | 
 | 118 | 				return; | 
 | 119 | 		} | 
| Juan Cespedes | f1bfe20 | 2002-03-27 00:22:23 +0100 | [diff] [blame] | 120 | #endif | 
 | 121 |  | 
| Juan Cespedes | cac15c3 | 2003-01-31 18:58:58 +0100 | [diff] [blame] | 122 | 		debug(1, "Enabling breakpoints for pid %u...", proc->pid); | 
| Juan Cespedes | a0ccf39 | 2003-02-01 19:02:37 +0100 | [diff] [blame] | 123 | 		if (proc->breakpoints) { | 
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 124 | 			dict_apply_to_all(proc->breakpoints, enable_bp_cb, | 
 | 125 | 					  proc); | 
| Juan Cespedes | a0ccf39 | 2003-02-01 19:02:37 +0100 | [diff] [blame] | 126 | 		} | 
| Eric Vaitl | 1228a91 | 2006-12-28 16:16:56 +0100 | [diff] [blame] | 127 | #ifdef __mips__ | 
| Juan Cespedes | a413e5b | 2007-09-04 17:34:53 +0200 | [diff] [blame] | 128 | 		{ | 
| Juan Cespedes | 5c68204 | 2009-05-21 15:59:56 +0200 | [diff] [blame] | 129 | 			/* | 
 | 130 | 			 * I'm sure there is a nicer way to do this. We need to | 
 | 131 | 			 * insert breakpoints _after_ the child has been started. | 
 | 132 | 			 */ | 
| Juan Cespedes | a413e5b | 2007-09-04 17:34:53 +0200 | [diff] [blame] | 133 | 			struct library_symbol *sym; | 
 | 134 | 			struct library_symbol *new_sym; | 
 | 135 | 			sym=proc->list_of_symbols; | 
 | 136 | 			while(sym){ | 
 | 137 | 				void *addr= sym2addr(proc,sym); | 
 | 138 | 				if(!addr){ | 
 | 139 | 					sym=sym->next; | 
 | 140 | 					continue; | 
 | 141 | 				} | 
 | 142 | 				if(dict_find_entry(proc->breakpoints,addr)){ | 
 | 143 | 					sym=sym->next; | 
 | 144 | 					continue; | 
 | 145 | 				} | 
 | 146 | 				debug(2,"inserting bp %p %s",addr,sym->name); | 
| Arnaud Patard | 4795087 | 2010-01-08 08:40:15 -0500 | [diff] [blame] | 147 | 				new_sym=malloc(sizeof(*new_sym) + strlen(sym->name) + 1); | 
 | 148 | 				memcpy(new_sym,sym,sizeof(*new_sym) + strlen(sym->name) + 1); | 
| Juan Cespedes | a413e5b | 2007-09-04 17:34:53 +0200 | [diff] [blame] | 149 | 				new_sym->next=proc->list_of_symbols; | 
 | 150 | 				proc->list_of_symbols=new_sym; | 
| Juan Cespedes | a413e5b | 2007-09-04 17:34:53 +0200 | [diff] [blame] | 151 | 				insert_breakpoint(proc, addr, new_sym); | 
 | 152 | 				sym=sym->next; | 
 | 153 | 			} | 
 | 154 | 		} | 
| Eric Vaitl | 1228a91 | 2006-12-28 16:16:56 +0100 | [diff] [blame] | 155 | #endif | 
| Juan Cespedes | 5e01f65 | 1998-03-08 22:31:44 +0100 | [diff] [blame] | 156 | 	} | 
 | 157 | 	proc->breakpoints_enabled = 1; | 
 | 158 | } | 
 | 159 |  | 
| Juan Cespedes | f135052 | 2008-12-16 18:19:58 +0100 | [diff] [blame] | 160 | static void | 
 | 161 | disable_bp_cb(void *addr, void *sbp, void *proc) { | 
| Juan Cespedes | cd8976d | 2009-05-14 13:47:58 +0200 | [diff] [blame] | 162 | 	debug(DEBUG_FUNCTION, "disable_bp_cb(pid=%d)", ((Process *)proc)->pid); | 
| Juan Cespedes | 1dec217 | 2009-05-07 10:12:10 +0200 | [diff] [blame] | 163 | 	if (((Breakpoint *)sbp)->enabled) { | 
| Petr Machata | f789c9c | 2011-07-09 10:54:27 +0200 | [diff] [blame] | 164 | 		disable_breakpoint(proc, sbp); | 
| Juan Cespedes | cac15c3 | 2003-01-31 18:58:58 +0100 | [diff] [blame] | 165 | 	} | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 166 | } | 
 | 167 |  | 
| Juan Cespedes | f135052 | 2008-12-16 18:19:58 +0100 | [diff] [blame] | 168 | void | 
| Juan Cespedes | a8909f7 | 2009-04-28 20:02:41 +0200 | [diff] [blame] | 169 | disable_all_breakpoints(Process *proc) { | 
| Juan Cespedes | cd8976d | 2009-05-14 13:47:58 +0200 | [diff] [blame] | 170 | 	debug(DEBUG_FUNCTION, "disable_all_breakpoints(pid=%d)", proc->pid); | 
| Petr Machata | 9a5420c | 2011-07-09 11:21:23 +0200 | [diff] [blame^] | 171 | 	assert(proc->leader == proc); | 
| Juan Cespedes | 5e01f65 | 1998-03-08 22:31:44 +0100 | [diff] [blame] | 172 | 	if (proc->breakpoints_enabled) { | 
| Juan Cespedes | cac15c3 | 2003-01-31 18:58:58 +0100 | [diff] [blame] | 173 | 		debug(1, "Disabling breakpoints for pid %u...", proc->pid); | 
 | 174 | 		dict_apply_to_all(proc->breakpoints, disable_bp_cb, proc); | 
| Juan Cespedes | 5e01f65 | 1998-03-08 22:31:44 +0100 | [diff] [blame] | 175 | 	} | 
 | 176 | 	proc->breakpoints_enabled = 0; | 
 | 177 | } | 
| Juan Cespedes | 7186e2a | 2003-01-31 19:56:34 +0100 | [diff] [blame] | 178 |  | 
| Juan Cespedes | f135052 | 2008-12-16 18:19:58 +0100 | [diff] [blame] | 179 | static void | 
 | 180 | free_bp_cb(void *addr, void *sbp, void *data) { | 
| Juan Cespedes | cd8976d | 2009-05-14 13:47:58 +0200 | [diff] [blame] | 181 | 	debug(DEBUG_FUNCTION, "free_bp_cb(sbp=%p)", sbp); | 
| Juan Cespedes | 7186e2a | 2003-01-31 19:56:34 +0100 | [diff] [blame] | 182 | 	assert(sbp); | 
 | 183 | 	free(sbp); | 
 | 184 | } | 
 | 185 |  | 
| Juan Cespedes | f135052 | 2008-12-16 18:19:58 +0100 | [diff] [blame] | 186 | void | 
| Petr Machata | c7585b6 | 2011-07-08 22:58:12 +0200 | [diff] [blame] | 187 | breakpoints_init(Process *proc, int enable) | 
 | 188 | { | 
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 189 | 	struct library_symbol *sym; | 
| Juan Cespedes | 7186e2a | 2003-01-31 19:56:34 +0100 | [diff] [blame] | 190 |  | 
| Juan Cespedes | cd8976d | 2009-05-14 13:47:58 +0200 | [diff] [blame] | 191 | 	debug(DEBUG_FUNCTION, "breakpoints_init(pid=%d)", proc->pid); | 
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 192 | 	if (proc->breakpoints) {	/* let's remove that struct */ | 
| Juan Cespedes | 7186e2a | 2003-01-31 19:56:34 +0100 | [diff] [blame] | 193 | 		dict_apply_to_all(proc->breakpoints, free_bp_cb, NULL); | 
 | 194 | 		dict_clear(proc->breakpoints); | 
 | 195 | 		proc->breakpoints = NULL; | 
 | 196 | 	} | 
| Petr Machata | 2662768 | 2011-07-08 18:15:32 +0200 | [diff] [blame] | 197 |  | 
| Petr Machata | 9a5420c | 2011-07-09 11:21:23 +0200 | [diff] [blame^] | 198 | 	/* Only the thread group leader should hold the breakpoints. | 
 | 199 | 	 * (N.B. PID may be set to 0 temporarily when called by | 
 | 200 | 	 * handle_exec).  */ | 
 | 201 | 	assert(proc->leader == proc); | 
 | 202 |  | 
| Petr Machata | 2662768 | 2011-07-08 18:15:32 +0200 | [diff] [blame] | 203 | 	proc->breakpoints = dict_init(dict_key2hash_int, | 
 | 204 | 				      dict_key_cmp_int); | 
| Juan Cespedes | 7186e2a | 2003-01-31 19:56:34 +0100 | [diff] [blame] | 205 |  | 
| Petr Machata | 3d7e4b8 | 2011-07-08 18:15:19 +0200 | [diff] [blame] | 206 | 	if (proc->list_of_symbols != NULL) { | 
 | 207 | 		struct library_symbol * sym = proc->list_of_symbols; | 
 | 208 | 		while (sym != NULL) { | 
 | 209 | 			struct library_symbol * next = sym->next; | 
 | 210 | 			free(sym); | 
 | 211 | 			sym = next; | 
 | 212 | 		} | 
 | 213 | 	} | 
 | 214 | 	proc->list_of_symbols = NULL; | 
 | 215 |  | 
| Juan Cespedes | ce377d5 | 2008-12-16 19:38:10 +0100 | [diff] [blame] | 216 | 	if (options.libcalls && proc->filename) { | 
| Ian Wienand | 9a2ad35 | 2006-02-20 22:44:45 +0100 | [diff] [blame] | 217 | 		proc->list_of_symbols = read_elf(proc); | 
| Juan Cespedes | 7186e2a | 2003-01-31 19:56:34 +0100 | [diff] [blame] | 218 | 		if (opt_e) { | 
| Petr Machata | 2662768 | 2011-07-08 18:15:32 +0200 | [diff] [blame] | 219 | 			struct library_symbol **tmp1 = &proc->list_of_symbols; | 
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 220 | 			while (*tmp1) { | 
 | 221 | 				struct opt_e_t *tmp2 = opt_e; | 
| Juan Cespedes | 7186e2a | 2003-01-31 19:56:34 +0100 | [diff] [blame] | 222 | 				int keep = !opt_e_enable; | 
 | 223 |  | 
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 224 | 				while (tmp2) { | 
| Petr Machata | 2662768 | 2011-07-08 18:15:32 +0200 | [diff] [blame] | 225 | 					if (!strcmp((*tmp1)->name, | 
 | 226 | 						    tmp2->name)) { | 
| Juan Cespedes | 7186e2a | 2003-01-31 19:56:34 +0100 | [diff] [blame] | 227 | 						keep = opt_e_enable; | 
 | 228 | 					} | 
 | 229 | 					tmp2 = tmp2->next; | 
 | 230 | 				} | 
 | 231 | 				if (!keep) { | 
 | 232 | 					*tmp1 = (*tmp1)->next; | 
 | 233 | 				} else { | 
 | 234 | 					tmp1 = &((*tmp1)->next); | 
 | 235 | 				} | 
 | 236 | 			} | 
 | 237 | 		} | 
| Juan Cespedes | 7186e2a | 2003-01-31 19:56:34 +0100 | [diff] [blame] | 238 | 	} | 
| Petr Machata | c7585b6 | 2011-07-08 22:58:12 +0200 | [diff] [blame] | 239 |  | 
 | 240 | 	for (sym = proc->list_of_symbols; sym; sym = sym->next) | 
 | 241 | 		insert_breakpoint(proc, sym2addr(proc, sym), sym, enable); | 
 | 242 |  | 
| Juan Cespedes | 7186e2a | 2003-01-31 19:56:34 +0100 | [diff] [blame] | 243 | 	proc->callstack_depth = 0; | 
 | 244 | 	proc->breakpoints_enabled = -1; | 
 | 245 | } | 
| Ian Wienand | 9a2ad35 | 2006-02-20 22:44:45 +0100 | [diff] [blame] | 246 |  | 
| Juan Cespedes | f135052 | 2008-12-16 18:19:58 +0100 | [diff] [blame] | 247 | void | 
| Juan Cespedes | a8909f7 | 2009-04-28 20:02:41 +0200 | [diff] [blame] | 248 | reinitialize_breakpoints(Process *proc) { | 
| Juan Cespedes | cd8976d | 2009-05-14 13:47:58 +0200 | [diff] [blame] | 249 | 	struct library_symbol *sym; | 
 | 250 |  | 
 | 251 | 	debug(DEBUG_FUNCTION, "reinitialize_breakpoints(pid=%d)", proc->pid); | 
 | 252 |  | 
 | 253 | 	sym = proc->list_of_symbols; | 
| Ian Wienand | 9a2ad35 | 2006-02-20 22:44:45 +0100 | [diff] [blame] | 254 |  | 
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 255 | 	while (sym) { | 
 | 256 | 		if (sym->needs_init) { | 
| Petr Machata | c7585b6 | 2011-07-08 22:58:12 +0200 | [diff] [blame] | 257 | 			insert_breakpoint(proc, sym2addr(proc, sym), sym, 1); | 
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 258 | 			if (sym->needs_init && !sym->is_weak) { | 
 | 259 | 				fprintf(stderr, | 
 | 260 | 					"could not re-initialize breakpoint for \"%s\" in file \"%s\"\n", | 
 | 261 | 					sym->name, proc->filename); | 
 | 262 | 				exit(1); | 
 | 263 | 			} | 
 | 264 | 		} | 
 | 265 | 		sym = sym->next; | 
 | 266 | 	} | 
 | 267 | } |