1 //	bfe2 - execution breakpoints
2 //	Copyright (c) 1999-2003 Brand Huntsman and Lee Salzman
3 //
4 
5 
6 #include "common.h"
7 #include "functions.h"
8 
9 
10 //////////////////////////////////////////////////////////////////////////
11 
12 // global
13 s_breakpoint breakpoints[MAX_BREAKPOINTS];
14 
15 // local
16 GtkWidget *bp_add_button, *bp_remove_button, *bp_removeall_button, *bp_address_text;
17 GtkCList *bp_list;
18 int selected_bp;
19 uint nr_breakpoints;
20 s_bgroup *bp_type;
21 
22 #define BP_COLUMN_TITLES 3
23 gchar *bp_column_titles[] = { "Last Stop", "Type", "Breakpoint" };
24 
25 char *bp_titles[] = { " Physical ", " Linear ", " Virtual " };
26 
27 //////////////////////////////////////////////////////////////////////////
28 
29 
read_breakpoints()30 void read_breakpoints( ){
31 	char scan, c;
32 	uint n;
33 
34 	for(n = 0; n < MAX_BREAKPOINTS; n++) breakpoints[n].enabled = 0;
35 	nr_breakpoints = 0;
36 
37 	fprintf(writepipe, "info break\n");
38 
39 	// remove the "Num Type Disp Enb Address"
40 	c = fgetc(readpipe);
41 	for(; !isdigit(c) && (c != '<') && (c != EOF); c = fgetc(readpipe));
42 	if(c == EOF) return;
43 	if(ungetc(c, readpipe) == EOF) return;
44 
45 	for(n = 0; n < MAX_BREAKPOINTS; n++){
46 		c = fgetc(readpipe);
47 		for(; isspace(c) && (c != EOF); c = fgetc(readpipe));
48 		if(c == EOF) return;
49 		if((ungetc(c, readpipe) == EOF) || !isdigit(c)) break;
50 
51 		if(fscanf(readpipe, "%u %c%*s ", &breakpoints[n].number, &scan) != 2) break;
52 		switch(scan){
53 		case 'p':
54 			breakpoints[n].type = BP_PHYSICAL;
55 			break;
56 		case 'l':
57 			breakpoints[n].type = BP_LINEAR;
58 			break;
59 		case 'v':
60 			breakpoints[n].type = BP_VIRTUAL;
61 			break;
62 		default:
63 			prompt_read();
64 			return;
65 		}
66 		if(fscanf(readpipe, "%*s %c ", &scan) != 1) break;
67 		breakpoints[n].enabled = (scan == 'y');
68 		if(fscanf(readpipe, "%x", & breakpoints[n].segment) != 1) break;
69 		if(fscanf(readpipe, ":%x", &breakpoints[n].offset) < 1){
70 			breakpoints[n].offset  = breakpoints[n].segment;
71 			breakpoints[n].segment = 0;
72 		}
73 
74 		nr_breakpoints++;
75 	}
76 
77 	prompt_read();
78 	return;
79 }
80 
81 
82 
add_breakpoint(GtkWidget * widget,gpointer data)83 void add_breakpoint( GtkWidget *widget, gpointer data ){
84 	const char *address;
85 
86 	address = gtk_entry_get_text(GTK_ENTRY(bp_address_text));
87 
88 	switch(bp_type->current){
89 	case BP_PHYSICAL:
90 		fprintf(writepipe, "pb %s\n", address);
91 		break;
92 	case BP_LINEAR:
93 		fprintf(writepipe, "lb %s\n", address);
94 		break;
95 	case BP_VIRTUAL:
96 		fprintf(writepipe, "vb %s\n", address);
97 		break;
98 	}
99 	prompt_read();
100 	if((int)data) breakpointsUpdate(BP_UPDATE);
101 	gtk_entry_set_text(GTK_ENTRY(bp_address_text), "");
102 }
103 
104 
remove_breakpoint(GtkWidget * widget,gpointer data)105 void remove_breakpoint( GtkWidget *widget, gpointer data ){
106 	fprintf(writepipe, "d %u\n", breakpoints[selected_bp].number);
107 	prompt_read();
108 	breakpointsUpdate(BP_UPDATE);
109 }
110 
111 
removeall_breakpoints(GtkWidget * widget,gpointer data)112 void removeall_breakpoints( GtkWidget *widget, gpointer data ){
113 	uint x;
114 
115 	for(x = 0; x < MAX_BREAKPOINTS; x++){
116 		if(breakpoints[0].enabled){
117 			fprintf(writepipe, "d %u\n", breakpoints[0].number);
118 			prompt_read();
119 			breakpointsUpdate(BP_UPDATE);
120 		} else break;
121 	}
122 }
123 
124 
bp_selected(GtkWidget * widget,gint row,gint column,GdkEventButton * event,gpointer data)125 void bp_selected( GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data ){
126 	selected_bp = row;
127 	gtk_widget_set_sensitive(bp_remove_button, TRUE);
128 }
129 
130 
bp_unselected(GtkWidget * widget,gint row,gint column,GdkEventButton * event,gpointer data)131 void bp_unselected( GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data ){
132 	selected_bp = -1;
133 	gtk_widget_set_sensitive(bp_remove_button, FALSE);
134 }
135 
136 
137 //////////////////////////////////////////////////////////////////////////
138 
139 
breakpointsInit(GtkWidget * vbox)140 void breakpointsInit( GtkWidget *vbox ){
141 	GtkWidget *hbox, *vbox2;
142 
143 	hbox = new_hbox(vbox, TRUE);
144 
145 	bp_list = new_list(hbox, BP_COLUMN_TITLES, bp_column_titles);
146 	gtk_clist_column_titles_show(bp_list);
147 	gtk_clist_set_column_justification(bp_list, 0, GTK_JUSTIFY_CENTER);
148 	gtk_clist_set_column_justification(bp_list, 1, GTK_JUSTIFY_CENTER);
149 	gtk_clist_set_column_justification(bp_list, 2, GTK_JUSTIFY_LEFT);
150 
151 	// setup selection handler
152 	gtk_signal_connect(GTK_OBJECT(bp_list), "select_row", GTK_SIGNAL_FUNC(bp_selected), NULL);
153 	gtk_signal_connect(GTK_OBJECT(bp_list), "unselect_row", GTK_SIGNAL_FUNC(bp_unselected), NULL);
154 
155 	vbox2 = new_vbox(hbox, FALSE);
156 	hbox = new_hbox(vbox2, FALSE);
157 
158 	// remove button
159 	bp_remove_button = new_button(hbox, TRUE, " Remove ");
160 	gtk_signal_connect(GTK_OBJECT(bp_remove_button), "clicked", GTK_SIGNAL_FUNC(remove_breakpoint), NULL);
161 
162 	// remove all button
163 	bp_removeall_button = new_button(hbox, TRUE, " Remove All ");
164 	gtk_signal_connect(GTK_OBJECT(bp_removeall_button), "clicked", GTK_SIGNAL_FUNC(removeall_breakpoints), NULL);
165 
166 	new_separator(vbox2, FALSE, HORIZONTAL);
167 
168 	hbox = new_hbox(vbox2, FALSE);
169 
170 	bp_type = new_button_group(hbox, TRUE, HORIZONTAL, 3, bp_titles);
171 
172 	// address text field
173 	bp_address_text = new_text_entry(vbox2, FALSE, 145);
174 	gtk_signal_connect(GTK_OBJECT(bp_address_text), "activate", GTK_SIGNAL_FUNC(add_breakpoint), (gpointer)1);
175 
176 	// add button
177 	bp_add_button = new_button(vbox2, FALSE, " Add ");
178 	gtk_signal_connect(GTK_OBJECT(bp_add_button), "clicked", GTK_SIGNAL_FUNC(add_breakpoint), (gpointer)1);
179 
180 	selected_bp = -1;
181 	nr_breakpoints = 0;
182 }
183 
184 
breakpointsUpdate(e_bp_mode mode)185 void breakpointsUpdate( e_bp_mode mode ){
186 	const char *p_type = "Physical", *l_type = "Linear", *v_type = "Virtual";
187 	char address[LEN_ADDRESS], *row[BP_COLUMN_TITLES];
188 	uint x;
189 
190 	if(bochs_offline) return;
191 
192 	if(mode == BP_UPDATE) read_breakpoints();
193 
194 	gtk_clist_freeze(bp_list);
195 	gtk_clist_clear(bp_list);
196 	selected_bp = -1;
197 	gtk_widget_set_sensitive(bp_remove_button, FALSE);
198 	if(nr_breakpoints) gtk_widget_set_sensitive(bp_removeall_button, TRUE);
199 	else gtk_widget_set_sensitive(bp_removeall_button, FALSE);
200 
201 	row[0] = NULL;
202 	// row[1] is set below
203 	row[2] = address;
204 
205 	for(x = 0; (x < MAX_BREAKPOINTS) && breakpoints[x].enabled; x++){
206 		switch(breakpoints[x].type){
207 		case BP_PHYSICAL:
208 			row[1] = (char *)p_type;
209 			snprintf(address, LEN_ADDRESS, "%.8X", breakpoints[x].offset);
210 			break;
211 		case BP_LINEAR:
212 			row[1] = (char *)l_type;
213 			snprintf(address, LEN_ADDRESS, "%.8X", breakpoints[x].offset);
214 			break;
215 		case BP_VIRTUAL:
216 			row[1] = (char *)v_type;
217 			snprintf(address, LEN_ADDRESS, "%.4X:%.8X",
218 				breakpoints[x].segment, breakpoints[x].offset);
219 			break;
220 		}
221 		gtk_clist_append(bp_list, row);
222 	}
223 	gtk_clist_thaw(bp_list);
224 }
225 
226 
breakpointsReload()227 void breakpointsReload( ){
228 	char address[LEN_ADDRESS];
229 	uint x, old_bp_type;
230 
231 	if(reload_breakpoints){
232 		old_bp_type = bp_type->current;
233 
234 		for(x = 0; (x < MAX_BREAKPOINTS) && breakpoints[x].enabled; x++){
235 			switch(breakpoints[x].type){
236 			case BP_PHYSICAL:
237 			case BP_LINEAR:
238 				snprintf(address, LEN_ADDRESS, "0x%.8X", breakpoints[x].offset);
239 				break;
240 			case BP_VIRTUAL:
241 				snprintf(address, LEN_ADDRESS, "0x%.4X:0x%.8X",
242 					breakpoints[x].segment, breakpoints[x].offset);
243 				break;
244 			}
245 			bp_type->current = breakpoints[x].type;
246 			gtk_entry_set_text(GTK_ENTRY(bp_address_text), address);
247 			add_breakpoint(bp_address_text, (gpointer)0);
248 		}
249 
250 		bp_type->current = old_bp_type;
251 	}
252 
253 	breakpointsUpdate(BP_UPDATE);
254 }
255 
256 
breakpointsEnablePage(gboolean v)257 void breakpointsEnablePage( gboolean v ){
258 	gtk_widget_set_sensitive(GTK_WIDGET(bp_list), v);
259 	gtk_widget_set_sensitive(bp_add_button, v);
260 	if(selected_bp != -1) gtk_widget_set_sensitive(bp_remove_button, v);
261 	else gtk_widget_set_sensitive(bp_remove_button, FALSE);
262 	if(nr_breakpoints) gtk_widget_set_sensitive(bp_removeall_button, v);
263 	else gtk_widget_set_sensitive(bp_removeall_button, FALSE);
264 	gtk_widget_set_sensitive(bp_address_text, v);
265 }
266 
267 
breakpointsSelect(uint bp)268 void breakpointsSelect( uint bp ){
269 	gtk_clist_set_text(bp_list, bp, 0, "X");
270 	gtk_clist_select_row(bp_list, bp, 0);
271 }
272