OSDN Git Service

Merge branch 'master' of git://github.com/monaka/binutils
[pf3gnuchains/pf3gnuchains3x.git] / sid / component / gdb / gdb.cxx
1 // gdb.cxx - GDB stub implementation.  -*- C++ -*-
2
3 // Copyright (C) 1999-2002, 2004, 2005, 2006 Red Hat.
4 // This file is part of SID and is licensed under the GPL.
5 // See the file COPYING.SID for conditions for redistribution.
6
7 #include "config.h"
8 #include "gdb.h"
9 #include <cassert>
10
11 extern "C" {
12 #include <stdio.h>
13 #include "gdbserv.h"
14 #include "gdbserv-client.h"
15 #include "gdbserv-target.h"
16 #include "gdbserv-utils.h"
17 #include "gdbserv-output.h"
18 }
19
20 // ----------------------------------------------------------------------------
21 // Interface functions to gdbserv code: client side
22
23 extern "C" void
24 gdbsid_client_write_hook (struct gdbserv *gdbserv, const unsigned char* ch, unsigned len)
25 {
26   assert (gdbserv != 0);
27   assert (ch != 0);
28   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
29   g->gdbsid_client_write (ch, len);
30 }
31
32
33
34 // ----------------------------------------------------------------------------
35 // Interface functions to gdbserv code: target side
36
37 extern "C" struct gdbserv_target*
38 gdbsid_target_attach_hook (struct gdbserv *gdbserv, void *globalstate)
39 {
40   gdb* g = static_cast<gdb*> (globalstate);
41   return g->gdbsid_target_attach (gdbserv);
42 }
43
44 extern "C" void
45 process_rcmd_hook (struct gdbserv *gdbserv, const char* cmd, int sizeof_cmd)
46 {
47   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
48   g->process_rcmd (cmd, sizeof_cmd);
49 }
50
51 extern "C" void
52 process_set_gen_hook (struct gdbserv *gdbserv)
53 {
54   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
55   return g->process_set_gen ();
56 }
57
58 extern "C" void
59 process_get_gen_hook (struct gdbserv *gdbserv)
60 {
61   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
62   return g->process_get_gen ();
63 }
64
65 extern "C" void
66 process_set_args_hook (struct gdbserv *gdbserv)
67 {
68   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
69   return g->process_set_args ();
70 }
71
72 extern "C" int
73 process_set_reg_hook (struct gdbserv *gdbserv, int reg)
74 {
75   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
76   return g->process_set_reg (reg);
77 }
78
79 extern "C" int
80 process_set_regs_hook (struct gdbserv *gdbserv)
81 {
82   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
83   return g->process_set_regs ();
84 }
85
86 extern "C" void
87 process_get_reg_hook (struct gdbserv *gdbserv, int reg)
88 {
89   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
90   return g->process_get_reg (reg);
91 }
92
93 extern "C" void
94 process_get_regs_hook (struct gdbserv *gdbserv)
95 {
96   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
97   return g->process_get_regs ();
98 }
99
100 extern "C" void
101 process_get_exp_regs_hook (struct gdbserv *gdbserv)
102 {
103   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
104   return g->process_get_exp_regs ();
105 }
106
107 extern "C" void
108 process_get_mem_hook (struct gdbserv *gdbserv,
109                       struct gdbserv_reg *reg_addr,
110                       struct gdbserv_reg *reg_len)
111 {
112   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
113   return g->process_get_mem (reg_addr, reg_len);
114 }
115
116 extern "C" void
117 process_set_mem_hook (struct gdbserv *gdbserv,
118                       struct gdbserv_reg *reg_addr,
119                       struct gdbserv_reg *reg_len,
120                       int binary)
121 {
122   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
123   return g->process_set_mem (reg_addr, reg_len, binary);
124 }
125
126 extern "C" void
127 process_set_pc_hook (struct gdbserv *gdbserv, struct gdbserv_reg *val) 
128 {
129   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
130   return g->process_set_pc (val);
131 }
132
133 extern "C" int
134 process_signal_hook (struct gdbserv *gdbserv, int sig) 
135 {
136   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
137   return g->process_signal (sig);
138 }
139
140 extern "C" void
141 flush_i_cache_hook (struct gdbserv *gdbserv) 
142 {
143   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
144   return g->flush_i_cache ();
145 }
146
147 extern "C" unsigned long
148 compute_signal_hook (struct gdbserv *gdbserv, unsigned long sig)
149 {
150   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
151   return g->compute_signal (sig);
152 }
153
154 extern "C" unsigned long
155 get_trap_number_hook (struct gdbserv *gdbserv)
156 {
157   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
158   return g->get_trap_number ();
159 }
160
161 extern "C" int
162 exit_program_hook (struct gdbserv *gdbserv)
163 {
164   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
165   return g->exit_program ();
166 }
167
168 extern "C" int
169 break_program_hook (struct gdbserv *gdbserv)
170 {
171   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
172   return g->break_program ();
173 }
174
175 extern "C" void
176 restart_program_hook (struct gdbserv *gdbserv)
177 {
178   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
179   return g->restart_program ();
180 }
181
182 extern "C" int
183 singlestep_program_hook (struct gdbserv *gdbserv)
184 {
185   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
186   return g->singlestep_program ();
187 }
188
189 extern "C" int
190 rangestep_program_hook (struct gdbserv *gdbserv, struct gdbserv_reg *val1,
191                         struct gdbserv_reg *val2)
192 {
193   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
194   return g->rangestep_program (val1, val2);
195 }
196
197
198 extern "C" void
199 sigkill_program_hook (struct gdbserv *gdbserv)
200 {
201   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
202   g->sigkill_program ();
203 }
204
205 extern "C" int
206 continue_program_hook (struct gdbserv *gdbserv) 
207 {
208   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
209   return g->continue_program ();
210 }
211
212 extern "C" int
213 remove_breakpoint_hook (struct gdbserv *gdbserv, unsigned long type,
214                         struct gdbserv_reg *addr, struct gdbserv_reg* len)
215 {
216   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
217   return g->remove_breakpoint (type, addr, len);
218 }
219
220 extern "C" int
221 set_breakpoint_hook (struct gdbserv *gdbserv, unsigned long type,
222                      struct gdbserv_reg *addr, struct gdbserv_reg* len)
223 {
224   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
225   return g->set_breakpoint (type, addr, len);
226 }
227
228 extern "C" void
229 process_detach_hook (struct gdbserv *gdbserv)
230 {
231   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
232   return g->process_detach ();
233 }
234
235 extern "C" int
236 set_exec_direction_hook (struct gdbserv *gdbserv, const char *direction)
237 {
238   gdb* g = static_cast<gdb*> (gdbserv_target_data (gdbserv));
239   return g->set_exec_direction (direction);
240 }
241
242
243
244
245 // ----------------------------------------------------------------------------
246 // Implementations for base class.
247
248
249 struct gdbserv_target*
250 gdb::gdbsid_target_attach (struct gdbserv *gdbserv)
251 {
252   // Do nothing if we're not configured properly.
253   if (this->cpu == 0)
254     {
255       cerr << "Error: Cannot attach to gdb: cpu relationship is not configured." << endl;
256       return 0;
257     }
258
259   if (this->gdbserv == 0)
260     {
261       struct gdbserv_target* gdbtarget = new ::gdbserv_target();
262       assert (gdbtarget != 0);
263       memset (gdbtarget, 0, sizeof (*gdbtarget)); // XXX: needed?
264
265       gdbtarget->process_rcmd = process_rcmd_hook;
266       gdbtarget->process_get_gen = process_get_gen_hook;
267       gdbtarget->process_set_gen = process_set_gen_hook;
268       gdbtarget->process_set_args = process_set_args_hook;
269       gdbtarget->process_set_reg = process_set_reg_hook;
270       gdbtarget->process_get_reg = process_get_reg_hook;
271       gdbtarget->process_set_regs = process_set_regs_hook;
272       gdbtarget->process_get_regs = process_get_regs_hook;
273       gdbtarget->process_get_exp_regs = process_get_exp_regs_hook;
274       gdbtarget->process_get_mem = process_get_mem_hook;
275       gdbtarget->process_set_mem = process_set_mem_hook;
276       gdbtarget->process_set_pc = process_set_pc_hook;
277       gdbtarget->process_signal = process_signal_hook;
278       gdbtarget->flush_i_cache = flush_i_cache_hook;
279       gdbtarget->compute_signal = compute_signal_hook;
280       gdbtarget->get_trap_number = get_trap_number_hook;
281       gdbtarget->exit_program = exit_program_hook;
282       gdbtarget->break_program = break_program_hook;
283       gdbtarget->restart_program = restart_program_hook;
284       gdbtarget->singlestep_program = singlestep_program_hook;
285       gdbtarget->rangestep_program = rangestep_program_hook;
286       gdbtarget->sigkill_program = sigkill_program_hook;
287       gdbtarget->continue_program = continue_program_hook;
288       gdbtarget->set_exec_direction = set_exec_direction_hook;
289       gdbtarget->remove_breakpoint = remove_breakpoint_hook;
290       gdbtarget->set_breakpoint = set_breakpoint_hook;
291       gdbtarget->detach = process_detach_hook;
292
293       // install mutual pointers
294       gdbtarget->data = static_cast<void*>(this);
295       this->gdbserv = gdbserv;
296
297       if (trace_gdbsid)
298         cerr << "gdb open" << endl;
299
300       // shut down target
301       target_power (false);
302       
303       // signal gdb
304       last_signal = GDBSERV_SIGTRAP;
305       gdbserv_fromtarget_break (gdbserv, last_signal);
306
307       return gdbtarget;
308     }
309   else
310     {
311       cerr << "Error: Cannot attach again to gdb." << endl;
312       return 0;
313     }
314 }
315
316
317 void
318 gdb::process_rcmd (const char *cmd, int sizeof_cmd)
319 {
320   string command = string (cmd, sizeof_cmd);
321   vector<string> tokens = sidutil::tokenize (command, " ");
322
323   if (trace_gdbsid)
324     cerr << "process_rcmd " << command << endl;
325
326   if (tokens.size() >= 1 &&
327       tokens[0] == "set" &&
328       this->cfgroot != 0)
329     {
330       // pass command string straight through to cfgroot
331       component::status s = this->cfgroot->set_attribute_value ("config-line!", command);
332       if (s != component::ok)
333         gdbserv_output_string (gdbserv, "E02");
334       else
335         gdbserv_output_string (gdbserv, "OK");
336
337       return;
338     }
339
340   gdbserv_output_string (gdbserv, "E01");
341 }
342
343
344 void
345 gdb::process_get_gen ()
346 {
347 }
348
349
350 void
351 gdb::process_set_gen ()
352 {
353
354   if (trace_gdbsid)
355     cerr << "process_set_gen" << endl;
356
357 #if 0
358   char *lhs;
359   char *rhs;
360   size_t sizeof_buf;
361
362   sizeof_buf = gdbserv_input_size (gdbserv);
363   if (sizeof_buf <= 0)
364     {
365       gdbserv_output_string (gdbserv, "E01");
366       return;
367     }
368   lhs = (char*) alloca (sizeof_buf + 1);
369   gdbserv_input_string (gdbserv, lhs, sizeof_buf + 1);
370   rhs = strchr (lhs, '=');
371   if (rhs == NULL)
372     {
373       gdbserv_output_string (gdbserv, "E02");
374       return;
375     }
376   *rhs++ = '\0';
377   //  if (this->general_set_func)
378   //    gdbsid->general_set_func (gdbsid->general_set_data, lhs, rhs);
379 #endif
380 }
381
382
383 void
384 gdb::process_set_args ()
385 {
386   if (trace_gdbsid)
387     cerr << "process_set_args" << endl;
388
389   if (gloss)
390     {
391       ; // XXX: collect arguments etc.
392     }
393   else
394     {
395       cerr << "Warning: gloss component not configured!" << endl;
396     }
397 }
398
399 using std::hex;
400 using std::setw;
401 using std::dec;
402
403 int
404 gdb::process_set_reg (int reg)
405 {
406   string reg_image;
407
408   if (trace_gdbsid)
409     cerr << "process_set_reg " << reg << " = [" << hex;
410   
411   dbg_register_number_t regno = reg;
412   string reg_name = string("gdb-register-") + make_numeric_attribute(regno);
413
414   int byte = gdbserv_input_byte (gdbserv);
415   while (byte >= 0) 
416     {
417       if (trace_gdbsid)
418         cerr << setw(2) << (unsigned) byte << " ";
419       
420       reg_image += (char) byte;
421       byte = gdbserv_input_byte (gdbserv);
422     }
423
424   if (trace_gdbsid)
425     cerr << "]" << dec << endl;
426
427   component::status s = cpu->set_attribute_value (reg_name, reg_image);
428   if (s != component::ok)
429     return -1;
430     
431   return 0;
432 }
433
434
435 void
436 gdb::process_get_reg (int reg)
437 {
438   if (trace_gdbsid)
439     cerr << "process_get_reg " << reg << endl;
440
441   // Not implemented
442   gdbserv_output_string (gdbserv, "E01");
443 }
444
445
446 int
447 gdb::process_set_regs ()
448 {
449   if (trace_gdbsid)
450     cerr << "process_set_regs" << endl;
451
452   // Not implemented
453   gdbserv_output_string (gdbserv, "E01");
454
455   return 0;
456 }
457
458
459 void
460 gdb::process_get_regs ()
461 {
462   if (trace_gdbsid)
463     cerr << "process_get_regs " << endl;
464
465   dbg_register_number_t num_regs;
466   string num_regs_str = cpu->attribute_value ("gdb-num-registers");
467   component::status s = parse_attribute (num_regs_str, num_regs);
468   if (s != component::ok)
469     num_regs = 0;
470
471   if (trace_gdbsid)
472     cerr << "num_regs=" << num_regs;
473   unsigned num_bytes = 0;
474
475   for (dbg_register_number_t regno=0; regno<num_regs; regno++) 
476     {
477       string reg_name = string("gdb-register-") 
478         + make_numeric_attribute(regno);
479       string value = cpu->attribute_value (reg_name);
480
481       for (unsigned i=0; i < value.length(); i++)
482         {
483           gdbserv_output_byte (gdbserv, value[i]);
484           num_bytes ++;
485         }
486     }
487
488   if (trace_gdbsid)
489     cerr << " bytes=" << num_bytes << endl;
490 }
491
492
493 void
494 gdb::process_get_exp_regs ()
495 {
496   if (trace_gdbsid)
497     cerr << "process_get_exp_regs";
498
499   string exp_regs_str = cpu->attribute_value ("gdb-exp-registers");
500   // None supplied
501   if (exp_regs_str == "")
502     return;
503
504   vector<string> exp_regs_list = tokenize (exp_regs_str, ";");
505   unsigned num_bytes = 0;
506
507   for (unsigned i=0; i<exp_regs_list.size(); i++)
508     {
509       dbg_register_number_t regno;
510       component::status s = parse_attribute (exp_regs_list[i], regno);
511       if (s != component::ok)
512         continue;
513
514       if (trace_gdbsid)
515         cerr << " " << regno;
516
517       string reg_name = string("gdb-register-") + make_numeric_attribute (regno);
518       string value = cpu->attribute_value (reg_name);
519
520       // encode register number
521       string regno_hex = make_numeric_attribute (regno, ios::hex); // no ios::showbase
522       gdbserv_output_string (gdbserv, regno_hex.c_str());
523       gdbserv_output_char (gdbserv, ':');
524
525       // and value
526       for (unsigned i=0; i < value.length(); i++)
527         {
528           gdbserv_output_byte (gdbserv, value[i]);
529           num_bytes ++;
530         }
531       gdbserv_output_char (gdbserv, ';');
532     }
533
534   if (trace_gdbsid)
535     cerr << " bytes=" << num_bytes << endl;
536 }
537
538
539
540 // Helper functions
541
542 template <class Type>
543 void
544 read_bus_word(gdbserv* gdbserv, 
545               sid::bus* bus,
546               host_int_4 address,
547               const Type& _dummy)
548 {
549   Type value;
550   bus::status s = bus->read (address, value);
551   if (s == bus::ok) 
552     {
553       for (unsigned i=0; i < sizeof(typename Type::value_type); i++)
554         gdbserv_output_byte (gdbserv, value.read_byte(i));
555     }
556   else if (s == bus::misaligned)
557     {
558       // Try it one byte at a time
559       for (unsigned i=0; i < sizeof(typename Type::value_type); i++)
560         {
561           big_int_1 b; // endianness of a single byte is irrelevent
562           s = bus->read (address + i, b);
563           if (s == bus::ok) 
564             gdbserv_output_byte (gdbserv, b);
565           else
566             gdbserv_output_string (gdbserv, "E05");
567         }
568     }
569   else
570     gdbserv_output_string (gdbserv, "E05");
571 }
572
573
574 template <class Type>
575 void
576 write_bus_word(gdbserv* gdbserv, 
577                int binary,
578                sid::bus* bus,
579                host_int_4 address,
580                const Type& _dummy)
581 {
582   Type value;
583
584   for (unsigned i=0; i < sizeof(typename Type::value_type); i++)
585     {
586       char b;
587       if (binary)
588         gdbserv_input_escaped_binary (gdbserv, & b, 1);
589       else
590         gdbserv_input_bytes (gdbserv, & b, 1);
591
592       value.write_byte (i, b);
593     }
594
595   bus::status s = bus->write (address, value);
596   if (s == bus::misaligned)
597     {
598       // Try it a byte at a time
599       for (unsigned i=0; i < sizeof(typename Type::value_type); i++)
600         {
601           // endianness of a single byte is irrelevent
602           big_int_1 b = value.read_byte (i);
603           s = bus->write (address + i, b);
604           if (s != bus::ok)
605             gdbserv_output_string (gdbserv, "E05");
606         }
607     }
608   else if (s != bus::ok)
609     gdbserv_output_string (gdbserv, "E05");
610 }
611
612
613
614 void
615 gdb::process_get_mem (struct gdbserv_reg *reg_addr,
616                       struct gdbserv_reg *reg_len)
617 {
618   unsigned long long addr8;
619   gdbserv_reg_to_ulonglong (gdbserv, reg_addr, &addr8);
620   unsigned long len;
621   gdbserv_reg_to_ulong (gdbserv, reg_len, &len);
622
623   if (trace_gdbsid)
624     cerr << "process_get_mem addr=" << addr8 << " len=" << len << endl;
625
626   if (! cpu)
627     {
628       cerr << "No cpu!" << endl;
629       gdbserv_output_string (gdbserv, "E01");
630       return;
631     }
632   sid::bus* memory = cpu->find_bus ("debugger-bus");
633   if (! memory)
634     {
635       cerr << "No debugger-bus!" << endl;
636       gdbserv_output_string (gdbserv, "E02");
637       return;
638     }
639  
640   endian e;
641   component::status s = 
642     parse_attribute (cpu->attribute_value ("endian"), e);
643   if (s != component::ok) assert (e == endian_unknown);
644
645   // XXX: 64-bit addresses unsupported
646   if (0 && addr8 >= (1ULL << 32))
647     {
648       cerr << "Bad address" << endl;
649       gdbserv_output_string (gdbserv, "E03");
650       return;
651     }
652   host_int_4 addr = addr8; // truncate
653
654   if (len==1 && e==endian_big) 
655     read_bus_word (gdbserv, memory, addr, big_int_1());
656   else if (len==1 && e==endian_little)
657     read_bus_word (gdbserv, memory, addr, little_int_1());
658   else if (len==2 && e==endian_big) 
659     read_bus_word (gdbserv, memory, addr, big_int_2());
660   else if (len==2 && e==endian_little)
661     read_bus_word (gdbserv, memory, addr, little_int_2());
662   else if (len==4 && e==endian_big) 
663     read_bus_word (gdbserv, memory, addr, big_int_4());
664   else if (len==4 && e==endian_little)
665     read_bus_word (gdbserv, memory, addr, little_int_4());
666   else if (len==8 && e==endian_big) 
667     read_bus_word (gdbserv, memory, addr, big_int_8());
668   else if (len==8 && e==endian_little)
669     read_bus_word (gdbserv, memory, addr, little_int_8());
670   else if (e==endian_little)
671     {
672       for (unsigned long i=0; i<len; i++)
673         read_bus_word (gdbserv, memory, addr + i, little_int_1());
674     }
675   else if (e==endian_big)
676     {
677       for (unsigned long i=0; i<len; i++)
678         read_bus_word (gdbserv, memory, addr + i, big_int_1());
679     }
680   else
681     {
682       cerr << "Unknown endianness/size combination!" << endl;
683       gdbserv_output_string (gdbserv, "E04");
684     }
685 }
686
687
688 void
689 gdb::process_set_mem (struct gdbserv_reg *reg_addr,
690                       struct gdbserv_reg *reg_len,
691                       int binary)
692 {
693   unsigned long long addr8;
694   gdbserv_reg_to_ulonglong (gdbserv, reg_addr, &addr8);
695
696   unsigned long len;
697   gdbserv_reg_to_ulong (gdbserv, reg_len, &len);
698
699   if (trace_gdbsid)
700     cerr << "process_set_mem"
701         << " addr=" << addr8 
702         << " len=" << len 
703         << " binary=" << binary 
704         << endl;
705
706   if (! cpu)
707     {
708       cerr << "No cpu!" << endl;
709       gdbserv_output_string (gdbserv, "E01");
710       return;
711     }
712   sid::bus* memory = cpu->find_bus ("debugger-bus");
713   if (! memory)
714     {
715       cerr << "No debugger-bus!" << endl;
716       gdbserv_output_string (gdbserv, "E02");
717       return;
718     }
719  
720   endian e;
721   component::status s = 
722     parse_attribute (cpu->attribute_value ("endian"), e);
723   if (s != component::ok) assert (e == endian_unknown);
724
725   // XXX: 64-bit addresses unsupported
726   if (0 && addr8 >= (1ULL << 32))
727     {
728       cerr << "Bad address" << endl;
729       gdbserv_output_string (gdbserv, "E03");
730       return;
731     }
732   host_int_4 addr = addr8; // truncate
733
734   if (len==1 && e==endian_big) 
735     write_bus_word (gdbserv, binary, memory, addr, big_int_1());
736   else if (len==1 && e==endian_little)
737     write_bus_word (gdbserv, binary, memory, addr, little_int_1());
738   else if (len==2 && e==endian_big) 
739     write_bus_word (gdbserv, binary, memory, addr, big_int_2());
740   else if (len==2 && e==endian_little)
741     write_bus_word (gdbserv, binary, memory, addr, little_int_2());
742   else if (len==4 && e==endian_big) 
743     write_bus_word (gdbserv, binary, memory, addr, big_int_4());
744   else if (len==4 && e==endian_little)
745     write_bus_word (gdbserv, binary, memory, addr, little_int_4());
746   else if (len==8 && e==endian_big) 
747     write_bus_word (gdbserv, binary, memory, addr, big_int_8());
748   else if (len==8 && e==endian_little)
749     write_bus_word (gdbserv, binary, memory, addr, little_int_8());
750   else if (e==endian_little)
751     {
752       for (unsigned long i=0; i<len; i++)
753         write_bus_word (gdbserv, binary, memory, addr + i, little_int_1());
754     }
755   else if (e==endian_big)
756     {
757       for (unsigned long i=0; i<len; i++)
758         write_bus_word (gdbserv, binary, memory, addr + i, big_int_1());
759     }
760   else
761     {
762       cerr << "Unknown endianness/size combination!" << endl;
763       gdbserv_output_string (gdbserv, "E04");
764     }
765 }
766
767
768 void
769 gdb::process_set_pc (struct gdbserv_reg* val) 
770 {
771   if (trace_gdbsid)
772     cerr << "process_set_pc ";
773
774   host_int_8 pc;
775   gdbserv_reg_to_ulonglong (gdbserv, val, & pc);
776
777   if (trace_gdbsid)
778     cerr << pc;
779
780   // Handle disharvardization
781   if (this->gdb_pc_mask)
782     {
783       pc &= this->gdb_pc_mask;
784       if (trace_gdbsid)
785         cerr << " =Z=> "
786              << pc;
787     }
788       
789   if (trace_gdbsid)
790     cerr << endl;
791
792   component::status s = cpu->set_attribute_value ("gdb-register-pc",
793                                                   make_numeric_attribute (pc));
794   if (s != component::ok)
795     {
796       cerr << "cannot set gdb-register-pc " << pc << endl;
797     }
798 }
799
800
801 int
802 gdb::process_signal (int sig)
803 {
804   if (trace_gdbsid)
805     cerr << "process_signal " << sig << endl;
806
807   // Mark next occurrence of this signal as to be ignored
808   this->pending_signal_counts [sig] ++;
809
810   return 0;
811 }
812
813
814 void
815 gdb::flush_i_cache () 
816 {
817   if (trace_gdbsid)
818     cerr << "flush_i_cache" << endl;
819
820   this->icache_flush_pin.drive (0);
821 }
822
823
824 unsigned long
825 gdb::compute_signal (unsigned long sig)
826 {
827   if (trace_gdbsid)
828     cerr << "compute_signal " << sig << endl;
829
830   return sig;
831 }
832
833
834 unsigned long
835 gdb::get_trap_number ()
836 {
837   if (trace_gdbsid)
838     cerr << "get_trap_number " << endl;
839
840   return last_signal;
841 }
842
843
844 int
845 gdb::exit_program ()
846 {
847   if (trace_gdbsid)
848     cerr << "exit_program " << endl;
849
850   // Turn off the range-stepping!
851   this->step_range_start = 0;
852   this->step_range_end = 0;
853
854   // shut down target
855   target_power (false);
856
857   // signal gdb
858   last_signal = GDBSERV_SIGINT;
859   gdbserv_fromtarget_break (gdbserv, last_signal);
860
861   // [don't] signal cfgroot to shut down
862   // this->process_signal_pin.drive (1);
863
864   return 0;
865 }
866
867
868 int
869 gdb::break_program ()
870 {
871   if (trace_gdbsid)
872     cerr << "break_program " << endl;
873
874   // Turn off the range-stepping!
875   this->step_range_start = 0;
876   this->step_range_end = 0;
877
878   // shut down target
879   target_power (false);
880
881   // signal gdb
882   last_signal = GDBSERV_SIGINT;
883   gdbserv_fromtarget_break (gdbserv, last_signal);
884   return 0;
885 }
886
887
888 void
889 gdb::restart_program ()
890 {
891   if (trace_gdbsid)
892     cerr << "restart_program " << endl;
893
894   // Drive restart pin so reset can be performed
895   this->restart_pin.drive (1);
896 }
897
898
899 int
900 gdb::singlestep_program ()
901 {
902   if (trace_gdbsid)
903     cerr << "singlestep_program " << endl;
904
905   assert (cpu != 0);
906   component::status s = cpu->set_attribute_value ("enable-step-trap?", "1");
907   if (s != component::ok)
908     {
909       cerr << "Cannot set enable-step-trap? attribute in cpu: status " << (int)s << endl;
910     }
911
912   this->step_range_start = 0;
913   this->step_range_end = 0;
914
915   // turn on target subsystem
916   target_power (true);
917
918   return 0;
919 }
920
921
922 int
923 gdb::rangestep_program (struct gdbserv_reg* range_start, struct gdbserv_reg* range_end)
924 {
925   if (! this->enable_E_packet)
926     return GDBSERV_TARGET_RC_ERROR;
927
928   if (trace_gdbsid)
929     cerr << "rangestep_program ";
930
931   assert (cpu != 0);
932   component::status s = cpu->set_attribute_value ("enable-step-trap?", "1");
933   if (s != component::ok)
934     {
935       cerr << "Cannot set enable-step-trap? attribute in cpu: status " << (int)s << endl;
936     }
937
938   gdbserv_reg_to_ulonglong (gdbserv, range_start, & this->step_range_start);
939   gdbserv_reg_to_ulonglong (gdbserv, range_end, & this->step_range_end);
940
941   if (trace_gdbsid)
942     cerr << "[" << this->step_range_start << "," << this->step_range_end << ")";
943
944   // Handle disharvardization
945   if (this->gdb_pc_mask)
946     {
947       this->step_range_start &= this->gdb_pc_mask;
948       this->step_range_end &= this->gdb_pc_mask;
949       if (trace_gdbsid)
950         cerr << " =Z=> "
951              << "[" << this->step_range_start << "," << this->step_range_end << ")";
952     }
953
954   if (trace_gdbsid)
955     cerr << endl;
956
957   // turn on target subsystem
958   target_power (true);
959
960   return GDBSERV_TARGET_RC_OK;
961 }
962
963
964 void
965 gdb::sigkill_program ()
966 {
967   if (trace_gdbsid)
968     cerr << "sigkill_program " << endl;
969
970   // signal gdb
971   last_signal = GDBSERV_SIGKILL;
972   gdbserv_fromtarget_exit (gdbserv, last_signal);
973 }
974
975
976 int
977 gdb::continue_program () 
978 {
979   if (trace_gdbsid)
980     cerr << "continue_program " << endl;
981
982   // turn off single-stepping
983   assert (cpu != 0);
984   component::status s = cpu->set_attribute_value ("enable-step-trap?", "0");
985   if (s != component::ok)
986     {
987       cerr << "Cannot clear enable-step-trap? attribute in cpu: status " << (int) s << endl;
988     }
989
990   this->step_range_start = 0;
991   this->step_range_end = 0;
992
993   // turn on target subsystem
994   target_power (true);
995   return 0;
996 }
997
998
999 int
1000 gdb::remove_breakpoint (unsigned long type, struct gdbserv_reg *addr, struct gdbserv_reg *len)
1001 {
1002   host_int_8 watch_pc;
1003   gdbserv_reg_to_ulonglong (gdbserv, addr, &watch_pc);
1004
1005   unsigned long bp_length;
1006   gdbserv_reg_to_ulong (gdbserv, len, &bp_length);
1007
1008   if (trace_gdbsid)
1009     cerr << "remove_breakpoint"
1010          << " type " << type
1011          << " addr " << watch_pc
1012          << " length " << bp_length
1013          << endl;
1014
1015   if (! enable_Z_packet) return 1;
1016   if (this->cpu == 0) return -1;
1017
1018   int rc = 1; // Not supported
1019
1020   if ((type == GDBSERV_TARGET_BP_HARDWARE) || 
1021       (type == GDBSERV_TARGET_BP_SOFTWARE && force_Z_sw_to_hw))
1022     rc = this->remove_hw_breakpoint (watch_pc, bp_length) ? 0 : -1;
1023   else if ((type == GDBSERV_TARGET_BP_SOFTWARE) || 
1024            (type == GDBSERV_TARGET_BP_HARDWARE && force_Z_hw_to_sw))
1025     rc = this->remove_sw_breakpoint (watch_pc, bp_length) ? 0 : -1;
1026   else if (type == GDBSERV_TARGET_BP_WRITE)
1027     rc = this->remove_hw_watchpoint (watch_pc, bp_length) ? 0 : -1;
1028   // Fail on uses of other breakpoint types (WRITE, READ, ACCESS, UNKNOWN)
1029
1030   return rc;
1031 }
1032
1033
1034 bool
1035 gdb::remove_all_hw_breakpoints ()
1036 {
1037   while (true)
1038     {
1039       hw_breakpoints_t::iterator it = this->hw_breakpoints.begin();
1040       if (it == this->hw_breakpoints.end()) break;
1041
1042       // clean up carcass with refcount=0
1043       if (it->second == 0)
1044         {
1045           this->hw_breakpoints.erase(it);
1046           continue;
1047         }
1048
1049       // decrement refcount
1050       host_int_8 address = it->first;
1051       bool ok = this->remove_hw_breakpoint (address, 0);
1052       if (!ok) return ok;
1053     }
1054   return true;
1055 }
1056
1057
1058 bool
1059 gdb::remove_hw_breakpoint (host_int_8 address, host_int_4 length)
1060 {  
1061   if (this->hw_breakpoints[address] <= 0)
1062     {
1063       cerr << "sw-debug-gdb: duplicate breakpoint count underflow!" << endl;
1064       return false;
1065     }
1066
1067   string watcher_name;
1068   if (this->gdb_pc_mask)
1069     {
1070       watcher_name =
1071         string ("watch:") + 
1072         map_watchable_name ("gdb-register-pc") + string (":") +
1073         string ("mask/value:") + 
1074         make_numeric_attribute (this->gdb_pc_mask) + string (":") +
1075         make_numeric_attribute (address);
1076     }
1077   else
1078     {
1079       watcher_name =
1080         string ("watch:") + 
1081         map_watchable_name ("gdb-register-pc") + string (":") +
1082         string ("value:") + 
1083         make_numeric_attribute (address);
1084     }
1085   // see also ::add_hw_breakpoint()
1086   
1087   this->hw_breakpoints[address] --;
1088   if (this->hw_breakpoints[address] == 0)
1089     {
1090       component::status s = this->cpu->disconnect_pin (watcher_name, & this->trapstop_pin);
1091       return (s == component::ok);
1092     }
1093   else
1094     return true;
1095 }
1096
1097
1098 bool
1099 gdb::remove_all_sw_breakpoints ()
1100 {
1101   while (true)
1102     {
1103       sw_breakpoints_t::iterator it = this->sw_breakpoints.begin();
1104       if (it == this->sw_breakpoints.end()) break;
1105
1106       host_int_8 address = it->first;
1107       bool ok = this->remove_hw_breakpoint (address, 0 /* unknown length */);
1108       if (!ok) return ok;
1109     }
1110   return true;
1111 }
1112
1113
1114 bool
1115 gdb::remove_sw_breakpoint (host_int_8 address, host_int_4 length)
1116 {
1117   // see also ::add_sw_breakpoint()
1118
1119   // reject absent entry
1120   if (this->sw_breakpoints.find(address) == this->sw_breakpoints.end())
1121     return fallback_Z_sw_to_hw && this->remove_hw_breakpoint (address, length);
1122
1123   // Beyond this point, don't try to fall back to hw breakpoints.
1124   // That's because only a successful add_sw_breakpoint would pass the
1125   // previous test.  If it fails anything beyond this point, then a sw
1126   // breakpoint is already in place, and cannot possibly be removed by
1127   // using hw breakpoints.
1128
1129   sid::bus* memory = cpu->find_bus ("debugger-bus");
1130   if (! memory)
1131     return false;
1132
1133   string imem = this->sw_breakpoints [address];
1134
1135   if (length != 0 && (imem.length() != length))
1136     return false;
1137   // maybe we don't know the removal length any more; update length if so
1138   if (length == 0)
1139     length = imem.length();
1140
1141   // put back insn memory at given address
1142   for (host_int_4 i=0; i<length; i++)
1143     {
1144       little_int_1 byte; // == big_int_1
1145
1146       // store back old image
1147       byte = imem[i]; // range already checked above
1148       bus::status s = memory->write (address + i, byte);
1149       if (s != bus::ok)
1150         return false;
1151     }
1152
1153   // success!
1154   this->sw_breakpoints.erase (address);
1155   return true;
1156 }
1157
1158
1159 bool
1160 gdb::remove_all_hw_watchpoints ()
1161 {
1162   while (true)
1163     {
1164       hw_watchpoints_t::iterator it = this->hw_watchpoints.begin();
1165       if (it == this->hw_watchpoints.end()) break;
1166
1167       // clean up carcass with refcount=0
1168       if (it->second == 0)
1169         {
1170           this->hw_watchpoints.erase(it);
1171           continue;
1172         }
1173
1174       // decrement refcount
1175       string watcher_name = it->first;
1176       bool ok = this->remove_hw_watchpoint (watcher_name);
1177       if (!ok) return ok;
1178     }
1179   return true;
1180 }
1181
1182
1183 bool
1184 gdb::remove_hw_watchpoint (const string &watcher_name)
1185 {  
1186   if (this->hw_watchpoints[watcher_name] <= 0)
1187     {
1188       cerr << "sw-debug-gdb: duplicate watchpoint count underflow!" << endl;
1189       return false;
1190     }
1191
1192   this->hw_watchpoints[watcher_name] --;
1193   if (this->hw_watchpoints[watcher_name] == 0)
1194     {
1195       component::status s = this->cpu->disconnect_pin (watcher_name, & this->trapstop_pin);
1196       return (s == component::ok);
1197     }
1198   else
1199     return true;
1200 }
1201
1202
1203 bool
1204 gdb::remove_hw_watchpoint (host_int_8 address, host_int_4 length)
1205 {  
1206   string watcher_name = string ("watch:")
1207     + map_watchable_name ("gdb-watchpoint-"
1208                           + make_numeric_attribute (address)
1209                           + "-"
1210                           + make_numeric_attribute (length))
1211     + ":change";
1212
1213   return remove_hw_watchpoint (watcher_name);
1214 }
1215
1216
1217 int
1218 gdb::set_breakpoint (unsigned long type, struct gdbserv_reg *addr, struct gdbserv_reg *len)
1219 {
1220   host_int_8 watch_pc;
1221   gdbserv_reg_to_ulonglong (gdbserv, addr, &watch_pc);
1222
1223   unsigned long bp_length;
1224   gdbserv_reg_to_ulong (gdbserv, len, &bp_length);
1225
1226   if (trace_gdbsid)
1227     cerr << "add_breakpoint"
1228          << " type " << type
1229          << " addr " << watch_pc
1230          << " length " << bp_length
1231          << endl;
1232
1233
1234   if (! enable_Z_packet) return 1;
1235   if (this->cpu == 0) return -1;
1236
1237   int rc = 1; // Not supported
1238
1239   if ((type == GDBSERV_TARGET_BP_HARDWARE) || 
1240       (type == GDBSERV_TARGET_BP_SOFTWARE && force_Z_sw_to_hw))
1241     rc = this->add_hw_breakpoint (watch_pc, bp_length) ? 0 : -1;
1242   else if ((type == GDBSERV_TARGET_BP_SOFTWARE) || 
1243            (type == GDBSERV_TARGET_BP_HARDWARE && force_Z_hw_to_sw))
1244     rc = this->add_sw_breakpoint (watch_pc, bp_length) ? 0 : -1;
1245   else if (type == GDBSERV_TARGET_BP_WRITE)
1246     rc = this->add_hw_watchpoint (watch_pc, bp_length) ? 0 : -1;
1247   // Fail on uses of other breakpoint types (READ, ACCESS, UNKNOWN)
1248
1249   return rc;
1250 }
1251
1252
1253 bool
1254 gdb::add_hw_breakpoint (host_int_8 address, host_int_4 length)
1255 {
1256   // XXX: be sensitive to length
1257
1258   string watcher_name;
1259   if (this->gdb_pc_mask)
1260     {
1261       watcher_name =
1262         string ("watch:") + 
1263         map_watchable_name ("gdb-register-pc") + string (":") +
1264         string ("mask/value:") + 
1265         make_numeric_attribute (this->gdb_pc_mask) + string (":") +
1266         make_numeric_attribute (address);
1267     }
1268   else
1269     {
1270       watcher_name =
1271         string ("watch:") + 
1272         map_watchable_name ("gdb-register-pc") + string (":") +
1273         string ("value:") + 
1274         make_numeric_attribute (address);
1275     }
1276   // see also ::remove_hw_breakpoint()
1277
1278   this->hw_breakpoints[address] ++;
1279   if (this->hw_breakpoints[address] == 1)
1280     {
1281       component::status s = this->cpu->connect_pin (watcher_name, & this->trapstop_pin);
1282       return (s == component::ok);
1283     }
1284   else
1285     return true;
1286 }
1287
1288
1289 bool
1290 gdb::add_sw_breakpoint (host_int_8 address, host_int_4 length)
1291 {
1292   // see also ::remove_sw_breakpoint()
1293
1294   // reject duplicate
1295   if (this->sw_breakpoints.find(address) != this->sw_breakpoints.end())
1296     return false;
1297
1298   sid::bus* memory = cpu->find_bus ("debugger-bus");
1299   if (! memory)
1300     return fallback_Z_sw_to_hw && this->add_hw_breakpoint (address, length);
1301
1302   // fetch cpu sw breakpoint image
1303   endian e;
1304   component::status s = 
1305     parse_attribute (cpu->attribute_value ("endian"), e);
1306   if (s != component::ok) assert (e == endian_unknown);
1307   string bp_attr_name = string("gdb-sw-breakpoint") + 
1308     (e == endian_little ? string ("-little") :
1309      e == endian_big ? string ("-big") :
1310      string ("")); // should not happen; will fail when used
1311   string bp = cpu->attribute_value (bp_attr_name);
1312   if (bp.length() != length)
1313     return fallback_Z_sw_to_hw && this->add_hw_breakpoint (address, length);
1314
1315   // fetch insn memory at given address; replace it byte by byte
1316   string imem;
1317   for (host_int_4 i=0; i<length; i++)
1318     {
1319       little_int_1 byte; // == big_int_1
1320
1321       // fetch old image
1322       bus::status s = memory->read (address + i, byte);
1323       if (s != bus::ok)
1324         return fallback_Z_sw_to_hw && this->add_hw_breakpoint (address, length);
1325       imem += byte;
1326
1327       // store new image
1328       byte = bp[i]; // range already checked above
1329       s = memory->write (address + i, byte);
1330       if (s != bus::ok)
1331         return fallback_Z_sw_to_hw && this->add_hw_breakpoint (address, length);
1332     }
1333
1334   // success!
1335   this->sw_breakpoints [address] = imem;
1336   return true;
1337 }
1338
1339
1340 int
1341 gdb::set_exec_direction (const char *direction)
1342 {
1343   if (trace_gdbsid)
1344     cerr << "set_exec_direction " << endl;
1345
1346   assert (cpu != 0);
1347   component::status s = cpu->set_attribute_value ("exec-direction", direction);
1348   if (s != component::ok)
1349     {
1350       cerr << "Cannot set exec-direction attribute in cpu: status " << (int)s << endl;
1351     }
1352
1353   return 0;
1354 }
1355
1356
1357 bool
1358 gdb::add_hw_watchpoint (host_int_8 address, host_int_4 length)
1359 {
1360   // XXX: be sensitive to length
1361
1362   string watcher_name = string ("watch:")
1363     + map_watchable_name ("gdb-watchpoint-"
1364                           + make_numeric_attribute (address)
1365                           + "-"
1366                           + make_numeric_attribute (length))
1367     + ":change";
1368
1369   // see also ::remove_hw_watchpoint()
1370
1371   this->hw_watchpoints[watcher_name] ++;
1372   if (this->hw_watchpoints[watcher_name] == 1)
1373     {
1374       component::status s = this->cpu->connect_pin (watcher_name, & this->trapstop_pin);
1375       return (s == component::ok);
1376     }
1377   else
1378     return true;
1379 }
1380
1381
1382 void
1383 gdb::process_detach ()
1384 {
1385   if (trace_gdbsid)
1386     cerr << "process_detach " << endl;
1387
1388   bool ok =
1389     this->remove_all_hw_breakpoints () &&
1390     this->remove_all_sw_breakpoints () &&
1391     this->remove_all_hw_watchpoints ();
1392   if (!ok)
1393     {
1394       cerr << "sw-debug-gdb: cannot clean up breakpoints" << endl;
1395     }
1396
1397   // Decouple from gdbserv; caller will free it.
1398   this->gdbserv = 0;
1399
1400   // Conditionally stop sim.
1401   if (this->exit_on_detach)
1402     {
1403       // shut down target
1404       target_power (false);
1405       // signal cfgroot to shut down
1406       this->process_signal_pin.drive (1);
1407     }
1408   else
1409     {
1410       // Don't resume target subsystem.  It may be halted on purpose,
1411       // such as after having executed an exit().  A gdb re-attach may
1412       // bring the target back to life.
1413     }
1414 }
1415
1416 // Increment a given attribute value, interpreted as a plain `int'.
1417 static void 
1418 increment_attribute (sid::component* comp, const string& attr, int increment)
1419 {
1420   assert(comp);
1421   string valstr = comp->attribute_value (attr);
1422   int num;
1423   component::status s = parse_attribute(valstr, num);
1424   if (s != component::ok)
1425     {
1426       cerr << "Cannot parse " << attr << " attribute: string " << valstr
1427            << " status " << (int) s << endl;
1428       return;
1429     }
1430   
1431   num += increment;
1432   
1433   valstr = make_numeric_attribute (num);
1434   
1435   s = comp->set_attribute_value (attr, valstr);
1436   if (s != component::ok)
1437     {
1438       cerr << "Cannot set " << attr << " attribute: string " << valstr
1439            << " status " << (int) s << endl;
1440       return;
1441     }
1442 }
1443
1444 void
1445 gdb::target_power (bool on)
1446 {
1447   if (trace_gdbsid)
1448     cerr << "target_power " << on << endl;
1449
1450   // clear signal cause
1451   last_signal = GDBSERV_SIGNONE;
1452
1453   // signal target system to yield
1454   this->yield_pin.drive (0);
1455
1456   // increment/decrement enabled? attribute of target schedulers when 'on'
1457   // is true/false respectively.  Do not increment/decrement the attribute
1458   // if the scheduler is already enabled/disabled from our point of view.
1459   int incr = on ? 1 : -1;
1460   for (unsigned i=0; i<target_schedulers.size(); i++)
1461     {
1462       bool enabled = target_schedulers_enabled[i];
1463       if (trace_gdbsid)
1464         cerr << "  Target scheduler " << i << " enabled==" << enabled << endl;
1465       if (enabled != on)
1466         {
1467           increment_attribute (target_schedulers[i], "enabled?", incr);
1468           target_schedulers_enabled[i] = on;
1469         }
1470     }
1471
1472   // increment/decrement enabled? attribute of host schedulers when 'on'
1473   // is false/true respectively.  Do not increment/decrement the attribute
1474   // if the scheduler is already enabled/disabled from our point of view.
1475   for (unsigned j=0; j<host_schedulers.size(); j++)
1476     {
1477       bool yielded = host_schedulers_host_time_yielded[j];
1478       if (trace_gdbsid)
1479         cerr << "  Host scheduler " << j << " yielded==" << yielded << endl;
1480       if (yielded == on)
1481         {
1482           increment_attribute (host_schedulers[j], "yield-host-time?", -incr);
1483           host_schedulers_host_time_yielded[j] = ! on;
1484         }
1485     }
1486 }
1487
1488
1489 // ----------------------------------------------------------------------------
1490 // Interface functions to gdbserv / client code
1491
1492
1493 void
1494 gdb::gdbsid_client_write (const unsigned char* ch, unsigned len)
1495 {
1496   if (! this->connected_p)
1497     {
1498       cerr << "gdb: warning: writing but not yet connected" << endl;
1499     }
1500
1501   for (unsigned i = 0; i < len; i++)
1502     {
1503       this->remote_tx_pin.drive (ch[i]);
1504     }
1505 }
1506
1507
1508 void
1509 gdb::remote_rx_eof_handler ()
1510 {
1511   if (this->trace_gdbserv)
1512     cout << "gdb: disconnect" << endl;
1513
1514   if (! this->connected_p)
1515     {
1516       cerr << "gdb: unexpected disconnection." << endl;
1517       return;
1518     }
1519
1520   this->connected_p = false;
1521
1522   gdbserv_fromclient_detach (this->gdbserv);
1523
1524   assert (this->gdbserv_client != 0);
1525   delete this->gdbserv_client;
1526   this->gdbserv_client = 0;
1527 }
1528
1529
1530 void
1531 gdb::remote_rx_handler (host_int_4 value)
1532 {
1533   // dispatch to EOF handler
1534   if (value & ~0x00FF)
1535     return this->remote_rx_eof_handler ();
1536
1537   // first byte coming from a connection?
1538   if (! this->connected_p)
1539     {
1540       if (this->trace_gdbserv)
1541         cout << "gdb: connect" << endl;
1542
1543       this->connected_p = true;
1544
1545       assert (this->gdbserv_client == 0);
1546       this->gdbserv_client = new ::gdbserv_client();
1547       this->gdbserv_client->write = & gdbsid_client_write_hook;
1548       this->gdbserv_client->data = static_cast<void*>(this);
1549
1550       // Attach to gdbserv engine.  NB: This calls back into this
1551       // object through the attach_hook.
1552       struct gdbserv* serv = gdbserv_fromclient_attach (this->gdbserv_client,
1553                                                         & gdbsid_target_attach_hook,
1554                                                         static_cast<void*>(this));
1555       if (serv == 0)
1556         {
1557           // This shouldn't happen, since 
1558           cerr << "gdb: refusing connection" << endl;
1559           this->connected_p = false;
1560           delete this->gdbserv_client;
1561           this->gdbserv_client = 0;
1562           this->remote_tx_pin.drive (~0); // send EOF
1563           return;
1564         }
1565     }
1566
1567   // forward the byte to gdbserv-input.
1568   assert (this->gdbserv != 0);
1569
1570   char data = (value & 0x00FF);
1571   gdbserv_fromclient_data (this->gdbserv, & data, 1);
1572 }
1573
1574
1575 // ----------------------------------------------------------------------------
1576 // Interface functions to sid code
1577
1578 gdb::gdb ():
1579   init_pin (this, & gdb::init_handler), 
1580   deinit_pin (this, & gdb::deinit_handler),
1581   connected_p (false),
1582   remote_rx_pin (this, & gdb::remote_rx_handler),
1583   cpu (0),
1584   gloss (0),
1585   cpu_trap_ipin (this, & gdb::cpu_trap_handler),
1586   gloss_process_signal_pin (this, & gdb::gloss_signal_handler),
1587   target_tx_pin (this, & gdb::target_tx_handler),
1588   stop_pin (this, & gdb::stop_handler),
1589   trapstop_pin (this, & gdb::trapstop_handler),
1590   start_pin (this, & gdb::start_handler),
1591   gdbserv (0),
1592   gdbserv_client (0)
1593 {
1594   add_pin ("init", & init_pin);
1595   add_attribute ("init", & init_pin, "pin");
1596   add_pin ("deinit", & deinit_pin);
1597   add_attribute ("deinit", & deinit_pin, "pin");
1598   add_pin ("trap-code", & cpu_trap_code_pin);
1599   add_pin ("process-signal", & process_signal_pin);
1600   add_pin ("restart", & restart_pin);
1601   add_pin ("gloss-process-signal", & gloss_process_signal_pin);
1602   add_pin ("remote-rx", & remote_rx_pin);
1603   add_attribute ("remote-rx", & remote_rx_pin, "pin");
1604   add_pin ("remote-tx", & remote_tx_pin);
1605   add_attribute ("remote-tx", & remote_tx_pin, "pin");
1606   add_pin ("target-tx", & target_tx_pin);
1607   add_attribute ("target-tx", & target_tx_pin, "pin");
1608   add_pin ("trap", & cpu_trap_ipin, & cpu_trap_opin);
1609   add_pin ("yield", & yield_pin);
1610   add_attribute ("yield", & yield_pin, "pin");
1611   add_pin ("flush-icache", & icache_flush_pin);
1612   add_attribute ("flush-icache", & icache_flush_pin, "pin");
1613   add_pin ("stop-target", & stop_pin);
1614   add_attribute ("stop-target", & stop_pin, "pin");
1615   add_pin ("start-target", & start_pin);
1616   add_attribute ("start-target", & start_pin, "pin");
1617
1618   // NB: We don't have to register the stoptrap_pin as an externally
1619   // visible input pin.
1620   // add_pin ("stop-target-trap", & stoptrap_pin);
1621
1622   this->connected_p = false;
1623   add_attribute_ro ("connected?", & this->connected_p, "register");
1624
1625   cpu = 0;
1626   gloss = 0;
1627   cfgroot = 0;
1628   add_uni_relation ("cfgroot", & cfgroot);
1629   add_uni_relation ("cpu", & cpu);
1630   add_uni_relation ("gloss", & gloss);
1631   add_multi_relation ("target-schedulers", & target_schedulers);
1632   add_multi_relation ("host-schedulers", & host_schedulers);
1633
1634   // trace flags
1635   trace_gdbserv = false;
1636   trace_gdbsid = false;
1637   exit_on_detach = false;
1638   enable_Z_packet = true;
1639   force_Z_sw_to_hw = false;
1640   force_Z_hw_to_sw = false;
1641   fallback_Z_sw_to_hw = true;
1642   enable_E_packet = true;
1643   operating_mode_p = true;
1644   gdb_pc_mask = 0;
1645   step_range_start = 0;
1646   step_range_end = 0;
1647
1648   add_attribute_notify ("trace-gdbserv?", & trace_gdbserv, 
1649                         this, & gdb::update_trace_flags, "setting");
1650   add_attribute_notify ("trace-gdbsid?", & trace_gdbsid,
1651                         this, & gdb::update_trace_flags, "setting");
1652   add_attribute ("exit-on-detach?", & exit_on_detach, "setting");
1653   add_attribute ("enable-Z-packet?", & enable_Z_packet, "setting");
1654   add_attribute ("force-Z-hw-to-sw?", & force_Z_sw_to_hw, "setting");
1655   add_attribute ("force-Z-sw-to-hw?", & force_Z_hw_to_sw, "setting");
1656   add_attribute ("fallback-Z-sw-to-hw?", & fallback_Z_sw_to_hw, "setting");
1657   add_attribute ("enable-E-packet?", & enable_E_packet, "setting");
1658   add_attribute ("operating-mode?", & operating_mode_p, "setting");
1659   add_attribute ("gdb-pc-mask", & gdb_pc_mask, "setting");
1660   add_attribute_alias ("Z-packet-pc-mask", "gdb-pc-mask"); // backward compat.
1661 }
1662
1663
1664
1665 void
1666 gdb::init_handler (host_int_4) 
1667 {
1668   if (!cpu) 
1669     {
1670       cerr << "sid-gdb: no debug cpu specified." << endl;
1671       return;
1672     }
1673
1674   // Initialize vectors representing the state of each host/target scheduler.
1675   for (unsigned i=0; i<target_schedulers.size(); i++)
1676     target_schedulers_enabled.push_back (true);
1677   for (unsigned j=0; j<host_schedulers.size(); j++)
1678     host_schedulers_host_time_yielded.push_back (false);
1679
1680   // suspend down target system
1681   target_power (false);
1682 }
1683
1684
1685 void
1686 gdb::deinit_handler (host_int_4) 
1687 {
1688   // disconnect if needed
1689   if (this->connected_p)
1690     {
1691       // shut down target
1692       target_power (false);
1693       // signal gdb
1694       gdbserv_fromtarget_exit (gdbserv, 0);
1695       this->remote_rx_eof_handler ();
1696     }
1697 }
1698
1699
1700
1701 void
1702 gdb::update_trace_flags()
1703 {
1704   gdbserv_state_trace = trace_gdbserv ? stderr : NULL;
1705
1706
1707
1708 // Some sid-side component would like the target CPU to stop and hand
1709 // control to the debugger.
1710 void
1711 gdb::stop_handler (host_int_4)
1712 {
1713   if (trace_gdbsid)
1714     cerr << "stop_handler" << endl;
1715
1716   // Turn off the range-stepping!
1717   this->step_range_start = 0;
1718   this->step_range_end = 0;
1719
1720   // ignore if signal is pending
1721   if (this->pending_signal_counts [GDBSERV_SIGINT] > 0)
1722     {
1723       this->pending_signal_counts [GDBSERV_SIGINT] --;
1724       return;
1725     }
1726
1727   // shut down target
1728   target_power (false);
1729
1730   // attached?
1731   if (this->gdbserv == 0)
1732     {
1733       // XXX: Is this warning useful?
1734       cerr << "gdb: warning: stopping without attached debugger!" << endl;
1735     }
1736   else
1737     {
1738       // signal gdb
1739       last_signal = GDBSERV_SIGINT;
1740       gdbserv_fromtarget_break (gdbserv, last_signal);
1741     }
1742 }
1743
1744
1745 // The "target-stop-trap" pin was tickled, presumably because the CPU has
1746 // hit an hardware breakpoint, emulated by a PC triggerpoint.
1747 void
1748 gdb::trapstop_handler (host_int_4)
1749 {
1750   if (trace_gdbsid)
1751     cerr << "trapstop_handler" << endl;
1752
1753   // ignore if signal is pending
1754   if (this->pending_signal_counts [GDBSERV_SIGTRAP] > 0)
1755     {
1756       this->pending_signal_counts [GDBSERV_SIGTRAP] --;
1757       return;
1758     }
1759
1760   // Turn off the range-stepping!
1761   this->step_range_start = 0;
1762   this->step_range_end = 0;
1763
1764   // shut down target
1765   target_power (false);
1766
1767   // attached?
1768   if (this->gdbserv == 0)
1769     {
1770       // XXX: Is this warning useful?
1771       cerr << "gdb: warning: stopping without attached debugger!" << endl;
1772     }
1773   else
1774     {
1775       // signal gdb
1776       last_signal = GDBSERV_SIGTRAP;
1777       gdbserv_fromtarget_break (gdbserv, last_signal);
1778     }
1779 }
1780
1781
1782 // Some sid-side component would like the target CPU to start again.
1783 // NB: This could upset an attached external debugger.
1784 void
1785 gdb::start_handler (host_int_4)
1786 {
1787   if (trace_gdbsid)
1788     cerr << "start_handler" << endl;
1789
1790   // resume target
1791   target_power (true);
1792
1793   // attached?
1794   if (this->gdbserv != 0)
1795     {
1796       // We may already be halted, or running.  But there is no way to
1797       // inform gdb that we are about to resume running.
1798       cerr << "gdb: warning: starting without informing attached debugger!" << endl;
1799     }
1800 }
1801
1802
1803
1804 // The GLOSS emulator is signalling that a process exit signal 
1805 // is in process.
1806 void
1807 gdb::gloss_signal_handler (host_int_4 value)
1808 {
1809   if (trace_gdbsid)
1810     cerr << "gloss_signal " << value << endl;
1811
1812   // shut down target
1813   target_power (false);
1814
1815   // detached?
1816   if (this->gdbserv == 0)
1817     {
1818       // forward signal
1819       this->process_signal_pin.drive (value);
1820     }
1821   else
1822     {
1823       // signal gdb
1824       last_signal = value & 0xff;
1825       gdbserv_fromtarget_exit (gdbserv, value >> 8);
1826     }
1827 }
1828
1829
1830 // The CPU is signalling that a trap of some sort is in progress.
1831 void
1832 gdb::cpu_trap_handler (host_int_4 trap_type) 
1833 {
1834   if (trace_gdbsid)
1835     cerr << "cpu_trap_handler t=" << trap_type << endl;
1836
1837   // Don't handle CPU traps in operating mode, except for:
1838   // - single-stepping
1839   if (this->operating_mode_p &&
1840       (trap_type != sidutil::cpu_trap_stepped))
1841     return;
1842
1843   // Handle pending step-out-of-range packet
1844   if (trap_type == sidutil::cpu_trap_stepped &&
1845       this->step_range_end)
1846     {
1847       host_int_8 pc;
1848       string pcval = cpu->attribute_value ("gdb-register-pc");
1849       component::status s = parse_attribute (pcval, pc);
1850       if (s != component::ok)
1851         {
1852           cerr << "cannot parse gdb-register-pc " << pcval << endl;
1853         }
1854       else
1855         {
1856           // Handle disharvardization
1857           if (this->gdb_pc_mask)
1858             pc &= this->gdb_pc_mask;
1859
1860           // Note the [start, end) interpretation!
1861           if (pc >= this->step_range_start && pc < this->step_range_end)
1862             {
1863               if (trace_gdbsid)
1864                 cerr << "(pc=" << pc << " - resuming)" << endl;
1865               this->cpu_trap_opin.drive (cpu_trap_handled);
1866               return;
1867             }
1868
1869           // Turn off the range-stepping!
1870           this->step_range_start = 0;
1871           this->step_range_end = 0;
1872         }
1873     }
1874
1875   host_int_4 trapsig =
1876     trap_type == sidutil::cpu_trap_software ? GDBSERV_SIGTRAP :
1877     trap_type == sidutil::cpu_trap_breakpoint ? GDBSERV_SIGTRAP :
1878     trap_type == sidutil::cpu_trap_syscall ? GDBSERV_SIGTRAP :
1879     trap_type == sidutil::cpu_trap_invalid_insn ? GDBSERV_SIGILL :
1880     trap_type == sidutil::cpu_trap_memory_fault ? GDBSERV_SIGSEGV:
1881     trap_type == sidutil::cpu_trap_overflow ? GDBSERV_SIGFPE :
1882     trap_type == sidutil::cpu_trap_stepped ? GDBSERV_SIGTRAP :
1883     GDBSERV_SIGQUIT;
1884
1885   // detached?
1886   if (this->gdbserv == 0)
1887     {
1888       // shut down target
1889       target_power (false);
1890       // forward signal
1891       this->process_signal_pin.drive (trap_type);
1892     }
1893   else 
1894     {
1895       // ignore if signal is pending
1896       if (this->pending_signal_counts [trapsig] > 0)
1897         {
1898           this->pending_signal_counts [trapsig] --;
1899           return;
1900         }
1901
1902       // ack signal
1903       this->cpu_trap_opin.drive (cpu_trap_handled);
1904       // shut down target
1905       target_power (false);
1906       // signal gdb
1907       if (last_signal == GDBSERV_SIGNONE) 
1908         last_signal = trapsig;
1909       gdbserv_fromtarget_break (gdbserv, last_signal);
1910     }
1911 }
1912
1913
1914
1915 // A 'standard output' character came in from the target.  Send it on
1916 // to gdb via a "O" packet.  Each will pile up a pending '+' ACK in
1917 // return ... gah.
1918 void
1919 gdb::target_tx_handler (host_int_4 value)
1920 {
1921   // detached?
1922   if (this->gdbserv == 0)
1923     {
1924       ; // do nothing
1925     }
1926   else
1927     {
1928       gdbserv_output_discard (gdbserv);
1929       gdbserv_output_char (gdbserv, 'O');
1930       gdbserv_output_byte (gdbserv, ((int) value) & 0xFF);  
1931       gdbserv_output_packet (gdbserv);
1932       gdbserv_output_discard (gdbserv);
1933     }
1934 }
1935
1936
1937 void
1938 gdb::configure (const string &config)
1939 {
1940   // Call up to the base class first
1941   configurable_component::configure (config);
1942
1943   // Now handle relevent configuration for us.
1944   if (config.size () <= 8)
1945     return;
1946   if (config.substr (0, 8) == "verbose=")
1947     {
1948       bool verbose_p = (config.substr (8) == "true");
1949       trace_gdbserv = verbose_p;
1950       trace_gdbsid = verbose_p;
1951       return;
1952     }
1953 }
1954
1955
1956 gdb::~gdb() throw()
1957 {
1958   // Do nothing here; disconnection and gdbserv memory cleanup ought
1959   // to have occurred during deinit / detach earlier.
1960 }
1961
1962
1963
1964 // ----------------------------------------------------------------------------
1965
1966 // Standard DLL wrapper-stuff
1967
1968 static vector<string>
1969 gdb_list_types () 
1970 {
1971   vector<string> types;
1972   types.push_back ("sw-debug-gdb");
1973   return types;
1974 }
1975
1976 static component*
1977 gdb_create (const string& name) 
1978 {
1979   if (name == "sw-debug-gdb")
1980     return new gdb ();
1981   else
1982     return 0;
1983 }
1984
1985 static void
1986 gdb_delete (component* c) 
1987 {
1988   delete dynamic_cast<gdb*>(c);
1989 }
1990
1991 // static object
1992 DLLEXPORT extern const component_library gdb_component_library;
1993
1994 const component_library gdb_component_library = {
1995   COMPONENT_LIBRARY_MAGIC,
1996   & gdb_list_types, 
1997   & gdb_create,
1998   & gdb_delete
1999 };