* Sync comment with code's reality.
[dragonfly.git] / contrib / gdb / gdb / remote-rdi.c
1 /* GDB interface to ARM RDI library.
2    Copyright 1997, 1998 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20 #include "defs.h"
21 #include "gdb_string.h"
22 #include <fcntl.h>
23 #include "frame.h"
24 #include "inferior.h"
25 #include "bfd.h"
26 #include "symfile.h"
27 #include "target.h"
28 #include "wait.h"
29 #include "gdbcmd.h"
30 #include "objfiles.h"
31 #include "gdb-stabs.h"
32 #include "gdbthread.h"
33 #include "gdbcore.h"
34
35 #ifdef USG
36 #include <sys/types.h>
37 #endif
38
39 #include <signal.h>
40
41 #include "rdi-share/ardi.h"
42 #include "rdi-share/adp.h"
43 #include "rdi-share/hsys.h"
44
45 extern int isascii PARAMS ((int));
46
47 /* Prototypes for local functions */
48
49 static void arm_rdi_files_info PARAMS ((struct target_ops *ignore));
50
51 static int arm_rdi_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
52                                        int len, int should_write,
53                                        struct target_ops *target));
54
55 static void arm_rdi_prepare_to_store PARAMS ((void));
56
57 static void arm_rdi_fetch_registers PARAMS ((int regno));
58
59 static void arm_rdi_resume PARAMS ((int pid, int step,
60                                    enum target_signal siggnal));
61
62 static int arm_rdi_start_remote PARAMS ((char *dummy));
63
64 static void arm_rdi_open PARAMS ((char *name, int from_tty));
65
66 static void arm_rdi_create_inferior PARAMS ((char *exec_file, char *args,
67                                              char **env));
68
69 static void arm_rdi_close PARAMS ((int quitting));
70
71 static void arm_rdi_store_registers PARAMS ((int regno));
72
73 static void arm_rdi_mourn PARAMS ((void));
74
75 static void arm_rdi_send PARAMS ((char *buf));
76
77 static int arm_rdi_wait PARAMS ((int pid, struct target_waitstatus *status));
78
79 static void arm_rdi_kill PARAMS ((void));
80
81 static void arm_rdi_detach PARAMS ((char *args, int from_tty));
82
83 static void arm_rdi_interrupt PARAMS ((int signo));
84
85 static void arm_rdi_interrupt_twice PARAMS ((int signo));
86
87 static void interrupt_query PARAMS ((void));
88
89 static int arm_rdi_insert_breakpoint PARAMS ((CORE_ADDR, char *));
90
91 static int arm_rdi_remove_breakpoint PARAMS ((CORE_ADDR, char *));
92
93 static char *rdi_error_message PARAMS ((int err));
94
95 static enum target_signal rdi_error_signal PARAMS ((int err));
96
97 /* Global variables.  */
98
99 struct target_ops arm_rdi_ops;
100
101 static struct Dbg_ConfigBlock gdb_config;
102
103 static struct Dbg_HostosInterface gdb_hostif;
104
105 static int max_load_size;
106
107 static int execute_status;
108
109 /* A little list of breakpoints that have been set.  */
110
111 static struct local_bp_list_entry {
112   CORE_ADDR addr;
113   PointHandle point;
114   struct local_bp_list_entry *next;
115 } *local_bp_list;
116
117 \f
118 /* Stub for catch_errors.  */
119
120 static int
121 arm_rdi_start_remote (dummy)
122      char *dummy;
123 {
124   return 1;
125 }
126
127 /* Helper callbacks for the "host interface" structure.  RDI functions call
128    these to forward output from the target system and so forth.  */
129
130 void
131 voiddummy ()
132 {
133   fprintf_unfiltered (gdb_stdout, "void dummy\n");
134 }
135
136 static void
137 myprint (arg, format, ap)
138      PTR arg;
139      const char *format;
140      va_list ap;
141 {
142   vfprintf_unfiltered (gdb_stdout, format, ap);
143 }
144
145 static void
146 mywritec (arg, c)
147      PTR arg;
148      int c;
149 {
150   if (isascii (c))
151     fputc_unfiltered (c, gdb_stdout);
152 }
153
154 static int
155 mywrite (arg, buffer, len)
156      PTR arg;
157      char const *buffer;
158      int len;
159 {
160   int i;
161   char *e;
162
163   e = (char *) buffer;
164   for (i = 0; i < len; i++)
165 {
166       if (isascii ((int) *e))
167         {
168           fputc_unfiltered ((int) *e, gdb_stdout);
169           e++;
170         }
171 }
172
173   return len;
174 }
175
176 static void
177 mypause (arg)
178      PTR arg;
179 {
180 }
181
182 /* These last two are tricky as we have to handle the special case of
183    being interrupted more carefully */
184
185 static int
186 myreadc (arg)
187      PTR arg;
188
189   return fgetc (stdin);
190 }
191
192 static char *
193 mygets (arg, buffer, len)
194      PTR arg;
195      char *buffer;
196      int len;
197 {
198   return fgets(buffer, len, stdin);
199 }
200
201 /* Prevent multiple calls to angel_RDI_close().  */
202 static int closed_already = 1;
203
204 /* Open a connection to a remote debugger.  NAME is the filename used
205    for communication.  */
206
207 static void
208 arm_rdi_open (name, from_tty)
209      char *name;
210      int from_tty;
211 {
212   int rslt, i;
213   unsigned long arg1, arg2;
214
215   if (name == NULL)
216     error ("To open an RDI connection, you need to specify what serial\n\
217 device is attached to the remote system (e.g. /dev/ttya).");
218
219   /* Make the basic low-level connection.  */
220
221   rslt = Adp_OpenDevice (name, NULL, 1);
222
223   if (rslt != adp_ok)
224     error ("Could not open device \"%s\"", name);
225
226   gdb_config.bytesex = 2 | (TARGET_BYTE_ORDER == BIG_ENDIAN ? 1 : 0);
227   gdb_config.fpe = 1;
228   gdb_config.rditype = 2;
229   gdb_config.heartbeat_on = 1;
230   gdb_config.flags = 2;
231
232   gdb_hostif.dbgprint = myprint;
233   gdb_hostif.dbgpause = mypause;
234   gdb_hostif.dbgarg = NULL;
235   gdb_hostif.writec = mywritec;
236   gdb_hostif.readc = myreadc;
237   gdb_hostif.write = mywrite;
238   gdb_hostif.gets = mygets;
239   gdb_hostif.hostosarg = NULL;
240   gdb_hostif.reset = voiddummy;
241
242   rslt = angel_RDI_open (10, &gdb_config, &gdb_hostif, NULL);
243   if (rslt == RDIError_BigEndian || rslt == RDIError_LittleEndian)
244     ;  /* do nothing, this is the expected return */
245   else if (rslt)
246     {
247       printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
248     }
249
250   rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2);
251   if (rslt)
252     {
253       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
254     }
255   rslt = angel_RDI_info (RDIInfo_Points, &arg1, &arg2);
256   if (rslt)
257     {
258       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
259     }
260   rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2);
261   if (rslt)
262     {
263       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
264     }
265   rslt = angel_RDI_info (RDIInfo_CoPro, &arg1, &arg2);
266   if (rslt)
267     {
268       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
269     }
270   rslt = angel_RDI_info (RDIInfo_SemiHosting, &arg1, &arg2);
271   if (rslt)
272     {
273       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
274     }
275
276   rslt = angel_RDI_info (RDIInfo_GetLoadSize, &arg1, &arg2);
277   if (rslt)
278     {
279       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
280     }
281   max_load_size = arg1;
282
283   push_target (&arm_rdi_ops);
284
285   target_fetch_registers (-1);
286
287   rslt = angel_RDI_open (1, &gdb_config, NULL, NULL);
288   if (rslt)
289     {
290       printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
291     }
292
293   arg1 = 0x13b;
294   rslt = angel_RDI_info (RDIVector_Catch, &arg1, &arg2);
295   if (rslt)
296     {
297       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
298     }
299
300   arg1 = (unsigned long) "";
301   rslt = angel_RDI_info (RDISet_Cmdline, &arg1, &arg2);
302   if (rslt)
303     {
304       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
305     }
306
307   /* Clear out any existing records of breakpoints.  */
308   {
309     struct local_bp_list_entry *entry, *preventry = NULL;
310
311     for (entry = local_bp_list; entry != NULL; entry = entry->next)
312       {
313         if (preventry)
314           free (preventry);
315       }
316   }
317
318   printf_filtered ("Connected to ARM RDI target.\n");
319   closed_already = 0;
320   inferior_pid = 42;
321 }
322
323 /* Start an inferior process and set inferior_pid to its pid.
324    EXEC_FILE is the file to run.
325    ARGS is a string containing the arguments to the program.
326    ENV is the environment vector to pass.  Errors reported with error().
327    On VxWorks and various standalone systems, we ignore exec_file.  */
328 /* This is called not only when we first attach, but also when the
329    user types "run" after having attached.  */
330
331 static void
332 arm_rdi_create_inferior (exec_file, args, env)
333      char *exec_file;
334      char *args;
335      char **env;
336 {
337   int len, rslt;
338   unsigned long arg1, arg2;
339   char *arg_buf;
340   CORE_ADDR entry_point;
341
342   if (exec_file == 0 || exec_bfd == 0)
343    error ("No executable file specified.");
344
345   entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd);
346
347   arm_rdi_kill ();       
348   remove_breakpoints ();
349   init_wait_for_inferior ();
350
351   len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop*/ 10;
352   arg_buf = (char *) alloca (len);
353   arg_buf[0] = '\0';
354   strcat (arg_buf, exec_file);
355   strcat (arg_buf, " ");
356   strcat (arg_buf, args);
357
358   inferior_pid = 42;
359   insert_breakpoints ();  /* Needed to get correct instruction in cache */
360
361   if (env != NULL)
362     {
363       while (*env)
364         {
365           if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
366             {
367               unsigned long top_of_memory;
368               char *end_of_num;
369
370               /* Set up memory limit */
371               top_of_memory = strtoul (*env + sizeof ("MEMSIZE=") - 1,
372                                        &end_of_num, 0);
373               printf_filtered ("Setting top-of-memory to 0x%x\n",
374                                top_of_memory);
375           
376               rslt = angel_RDI_info (RDIInfo_SetTopMem, &top_of_memory, &arg2);
377               if (rslt)
378                 {
379                   printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
380                 }
381             }
382           env++;
383         }
384     }
385
386   arg1 = (unsigned long) arg_buf;
387   rslt = angel_RDI_info (RDISet_Cmdline, /* &arg1 */ (unsigned long *)arg_buf, &arg2);
388   if (rslt)
389     {
390       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
391     }
392
393   proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0);
394 }
395
396 /* This takes a program previously attached to and detaches it.  After
397    this is done, GDB can be used to debug some other program.  We
398    better not have left any breakpoints in the target program or it'll
399    die when it hits one.  */
400
401 static void
402 arm_rdi_detach (args, from_tty)
403      char *args;
404      int from_tty;
405 {
406   pop_target ();
407 }
408
409 /* Clean up connection to a remote debugger.  */
410
411 static void
412 arm_rdi_close (quitting)
413      int quitting;
414 {
415   int rslt;
416
417   if (! closed_already)
418     {
419       rslt = angel_RDI_close ();
420       if (rslt)
421         {
422           printf_filtered ("RDI_close: %s\n", rdi_error_message (rslt));
423         }
424       closed_already = 1;
425       inferior_pid = 0;
426     }
427 }
428 \f
429 /* Tell the remote machine to resume.  */
430
431 static void
432 arm_rdi_resume (pid, step, siggnal)
433      int pid, step;
434      enum target_signal siggnal;
435 {
436   int rslt;
437   PointHandle point;
438
439   if (0 /* turn on when hardware supports single-stepping */)
440     {
441       rslt = angel_RDI_step (1, &point);
442       if (rslt)
443         {
444           printf_filtered ("RDI_step: %s\n", rdi_error_message (rslt));
445         }
446     }
447   else
448     {
449       char handle[4];
450       CORE_ADDR pc;
451
452       if (step)
453         {
454           pc = read_register (PC_REGNUM);
455           pc = arm_get_next_pc (pc);
456           arm_rdi_insert_breakpoint (pc, handle);
457         }
458       execute_status = rslt = angel_RDI_execute (&point);
459       if (rslt == RDIError_BreakpointReached)
460         ;
461       else if (rslt)
462         {
463           printf_filtered ("RDI_execute: %s\n", rdi_error_message (rslt));
464         }
465       if (step)
466         {
467           arm_rdi_remove_breakpoint (pc, handle);
468         }
469     }
470 }
471 \f
472 /* Send ^C to target to halt it.  Target will respond, and send us a
473    packet.  */
474
475 static void
476 arm_rdi_interrupt (signo)
477      int signo;
478 {
479 }
480
481 static void (*ofunc)();
482
483 /* The user typed ^C twice.  */
484 static void
485 arm_rdi_interrupt_twice (signo)
486      int signo;
487 {
488 }
489
490 /* Ask the user what to do when an interrupt is received.  */
491
492 static void
493 interrupt_query ()
494 {
495 }
496
497 /* Wait until the remote machine stops, then return, storing status in
498    STATUS just as `wait' would.  Returns "pid" (though it's not clear
499    what, if anything, that means in the case of this target).  */
500
501 static int
502 arm_rdi_wait (pid, status)
503      int pid;
504      struct target_waitstatus *status;
505 {
506   status->kind = (execute_status == RDIError_NoError ?
507     TARGET_WAITKIND_EXITED : TARGET_WAITKIND_STOPPED);
508
509   /* convert stopped code from target into right signal */
510   status->value.sig = rdi_error_signal (execute_status);
511
512   return inferior_pid;
513 }
514
515 /* Read the remote registers into the block REGS.  */
516
517 /* ARGSUSED */
518 static void
519 arm_rdi_fetch_registers (regno)
520      int regno;
521 {
522   int rslt, rdi_regmask;
523   unsigned long rawreg, rawregs[32];
524   char cookedreg[4];
525
526   if (regno == -1) 
527     {
528       rslt = angel_RDI_CPUread (255, 0x27fff, rawregs);
529       if (rslt)
530         {
531           printf_filtered ("RDI_CPUread: %s\n", rdi_error_message (rslt));
532         }
533
534       for (regno = 0; regno < 15; regno++)
535         {
536           store_unsigned_integer (cookedreg, 4, rawregs[regno]);
537           supply_register (regno, (char *) cookedreg);
538         }
539       store_unsigned_integer (cookedreg, 4, rawregs[15]);
540       supply_register (PS_REGNUM, (char *) cookedreg);
541       arm_rdi_fetch_registers (PC_REGNUM);
542     }
543   else
544     {
545       if (regno == PC_REGNUM)
546         rdi_regmask = RDIReg_PC;
547       else if (regno == PS_REGNUM)
548         rdi_regmask = RDIReg_CPSR;
549       else if (regno < 0 || regno > 15)
550         {
551           rawreg = 0;
552           supply_register (regno, (char *) &rawreg);
553           return;
554         }
555       else
556         rdi_regmask = 1 << regno;
557
558       rslt = angel_RDI_CPUread (255, rdi_regmask, &rawreg);
559       if (rslt)
560         {
561           printf_filtered ("RDI_CPUread: %s\n", rdi_error_message (rslt));
562         }
563       store_unsigned_integer (cookedreg, 4, rawreg);
564       supply_register (regno, (char *) cookedreg);
565     }
566 }
567
568 static void 
569 arm_rdi_prepare_to_store ()
570 {
571   /* Nothing to do.  */
572 }
573
574 /* Store register REGNO, or all registers if REGNO == -1, from the contents
575    of REGISTERS.  FIXME: ignores errors.  */
576
577 static void
578 arm_rdi_store_registers (regno)
579      int regno;
580 {
581   int rslt, rdi_regmask;
582
583   /* These need to be able to take 'floating point register' contents */
584   unsigned long rawreg[3], rawerreg[3];
585
586   if (regno  == -1) 
587     {
588       for (regno = 0; regno < NUM_REGS; regno++)
589         arm_rdi_store_registers (regno);
590     }
591   else
592     {
593       read_register_gen (regno, (char *) rawreg);
594       /* RDI manipulates data in host byte order, so convert now. */
595       store_unsigned_integer (rawerreg, 4, rawreg[0]);
596
597       if (regno == PC_REGNUM)
598         rdi_regmask = RDIReg_PC;
599       else if (regno == PS_REGNUM)
600         rdi_regmask = RDIReg_CPSR;
601       else if (regno < 0 || regno > 15)
602         return;
603       else
604         rdi_regmask = 1 << regno;
605
606       rslt = angel_RDI_CPUwrite (255, rdi_regmask, rawerreg);
607       if (rslt)
608         {
609           printf_filtered ("RDI_CPUwrite: %s\n", rdi_error_message (rslt));
610         }
611     }
612 }
613 \f
614 /* Read or write LEN bytes from inferior memory at MEMADDR,
615    transferring to or from debugger address MYADDR.  Write to inferior
616    if SHOULD_WRITE is nonzero.  Returns length of data written or
617    read; 0 for error.  */
618
619 /* ARGSUSED */
620 static int
621 arm_rdi_xfer_memory(memaddr, myaddr, len, should_write, target)
622      CORE_ADDR memaddr;
623      char *myaddr;
624      int len;
625      int should_write;
626      struct target_ops *target;                 /* ignored */
627 {
628   int rslt, i;
629
630   if (should_write)
631     {
632       rslt = angel_RDI_write (myaddr, memaddr, &len);
633       if (rslt)
634         {
635           printf_filtered ("RDI_write: %s\n", rdi_error_message (rslt));
636         }
637     }
638   else 
639     {
640       rslt = angel_RDI_read (memaddr, myaddr, &len);
641       if (rslt)
642         {
643           printf_filtered ("RDI_read: %s\n", rdi_error_message (rslt));
644           len = 0;
645         }
646     }
647   return len;
648 }
649 \f
650 /* Display random info collected from the target.  */
651
652 static void
653 arm_rdi_files_info (ignore)
654      struct target_ops *ignore;
655 {
656   char *file = "nothing";
657   int rslt;
658   unsigned long arg1, arg2;
659
660   rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2);
661   if (rslt)
662     {
663       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
664     }
665   if (arg1 & (1 << 15))
666     printf_filtered ("Target supports Thumb code.\n");
667   if (arg1 & (1 << 14))
668     printf_filtered ("Target can do profiling.\n");
669   if (arg1 & (1 << 4))
670     printf_filtered ("Target is real hardware.\n");
671   
672   rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2);
673   if (rslt)
674     {
675       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
676     }
677   printf_filtered ("Target can%s single-step.\n", (arg1 & 0x4 ? "" : "not"));
678
679   rslt = angel_RDI_info (RDIInfo_Icebreaker, &arg1, &arg2);
680   if (rslt)
681     {
682       printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
683     }
684   else
685     printf_filtered ("Target includes an EmbeddedICE.\n");
686 }
687 \f
688 static void
689 arm_rdi_kill ()
690 {
691   int rslt;
692
693   rslt = angel_RDI_open (1, &gdb_config, NULL, NULL);
694   if (rslt)
695     {
696       printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
697     }
698 }
699
700 static void
701 arm_rdi_mourn_inferior ()
702 {
703   unpush_target (&arm_rdi_ops);
704   generic_mourn_inferior ();
705 }
706 \f
707 /* While the RDI library keeps track of its own breakpoints, we need
708    to remember "handles" so that we can delete them later.  Since
709    breakpoints get used for stepping, be careful not to leak memory
710    here.  */
711
712 static int
713 arm_rdi_insert_breakpoint (addr, contents_cache)
714      CORE_ADDR addr;
715      char *contents_cache;
716 {
717   int rslt;
718   PointHandle point;
719   struct local_bp_list_entry *entry;
720   int type = RDIPoint_EQ;
721
722   if (arm_pc_is_thumb (addr) || arm_pc_is_thumb_dummy (addr))
723     type |= RDIPoint_16Bit;
724   rslt = angel_RDI_setbreak (addr, type, 0, &point);
725   if (rslt)
726     {
727       printf_filtered ("RDI_setbreak: %s\n", rdi_error_message (rslt));
728     }
729   entry =
730     (struct local_bp_list_entry *) xmalloc (sizeof (struct local_bp_list_entry));
731   entry->addr = addr;
732   entry->point = point;
733   entry->next = local_bp_list;
734   local_bp_list = entry;
735   return rslt;
736 }
737
738 static int
739 arm_rdi_remove_breakpoint (addr, contents_cache)
740      CORE_ADDR addr;
741      char *contents_cache;
742 {
743   int rslt;
744   PointHandle point;
745   struct local_bp_list_entry *entry, *preventry;
746
747   for (entry = local_bp_list; entry != NULL; entry = entry->next)
748     {
749       if (entry->addr == addr)
750         {
751           break;
752         }
753       preventry = entry;
754     }
755   if (entry)
756     {
757       rslt = angel_RDI_clearbreak (entry->point);
758       if (rslt)
759         {
760           printf_filtered ("RDI_clearbreak: %s\n", rdi_error_message (rslt));
761         }
762       /* Delete the breakpoint entry locally.  */
763       if (entry == local_bp_list)
764         {
765           local_bp_list = entry->next;
766         }
767       else
768         {
769           preventry->next = entry->next;
770         }
771       free (entry);
772     }
773   return 0;
774 }
775 \f
776 static char *
777 rdi_error_message (err)
778      int err;
779 {
780   switch (err)
781     {
782     case RDIError_NoError: 
783       return "no error";
784     case RDIError_Reset:
785       return "debuggee reset";
786     case RDIError_UndefinedInstruction:
787       return "undefined instruction";
788     case RDIError_SoftwareInterrupt:
789       return "SWI trapped";
790     case RDIError_PrefetchAbort:
791       return "prefetch abort, execution ran into unmapped memory?";
792     case RDIError_DataAbort:
793       return "data abort, no memory at specified address?";
794     case RDIError_AddressException:
795       return "address exception, access >26bit in 26bit mode";
796     case RDIError_IRQ:
797       return "IRQ, interrupt trapped";
798     case RDIError_FIQ:
799       return "FIQ, fast interrupt trapped";
800     case RDIError_Error:
801       return "a miscellaneous type of error";
802     case RDIError_BranchThrough0:
803       return "branch through location 0";
804     case RDIError_NotInitialised:
805       return "internal error, RDI_open not called first";
806     case RDIError_UnableToInitialise:
807       return "internal error, target world is broken";
808     case RDIError_WrongByteSex:
809       return "See Operator: WrongByteSex";
810     case RDIError_UnableToTerminate:
811       return "See Operator: Unable to Terminate";
812     case RDIError_BadInstruction:
813       return "bad instruction, illegal to execute this instruction";
814     case RDIError_IllegalInstruction:
815       return "illegal instruction, the effect of executing it is undefined";
816     case RDIError_BadCPUStateSetting:
817       return "internal error, tried to set SPSR of user mode";
818     case RDIError_UnknownCoPro:
819       return "unknown co-processor";
820     case RDIError_UnknownCoProState:
821       return "cannot execute co-processor request";
822     case RDIError_BadCoProState:
823       return "recognizably broken co-processor request";
824     case RDIError_BadPointType:
825       return "internal error, bad point yype";
826     case RDIError_UnimplementedType:
827       return "internal error, unimplemented type";
828     case RDIError_BadPointSize:
829       return "internal error, bad point size";
830     case RDIError_UnimplementedSize:
831       return "internal error, unimplemented size";
832     case RDIError_NoMorePoints:
833       return "last break/watch point was used";
834     case RDIError_BreakpointReached:
835       return "breakpoint reached";
836     case RDIError_WatchpointAccessed:
837       return "watchpoint accessed";
838     case RDIError_NoSuchPoint:
839       return "attempted to clear non-existent break/watch point";
840     case RDIError_ProgramFinishedInStep:
841       return "end of the program reached while stepping";
842     case RDIError_UserInterrupt:
843       return "you pressed Escape";
844     case RDIError_CantSetPoint:
845       return "no more break/watch points available";
846     case RDIError_IncompatibleRDILevels:
847       return "incompatible RDI levels";
848     case RDIError_LittleEndian:
849       return "debuggee is little endian";
850     case RDIError_BigEndian:
851       return "debuggee is big endian";
852     case RDIError_SoftInitialiseError:
853       return "recoverable error in RDI initialization";
854     case RDIError_InsufficientPrivilege:
855       return "internal error, supervisor state not accessible to monitor";
856     case RDIError_UnimplementedMessage:
857       return "internal error, unimplemented message";
858     case RDIError_UndefinedMessage:
859       return "internal error, undefined message";
860     default:
861       return "undefined error message, should reset target"; 
862     }
863 }
864
865 /* Convert the ARM error messages to signals that GDB knows about.  */
866
867 static enum target_signal
868 rdi_error_signal (err)
869      int err;
870 {
871   switch (err)
872     {
873     case RDIError_NoError:
874       return 0;
875     case RDIError_Reset:
876       return TARGET_SIGNAL_TERM; /* ??? */
877     case RDIError_UndefinedInstruction:
878       return TARGET_SIGNAL_ILL;
879     case RDIError_SoftwareInterrupt:
880     case RDIError_PrefetchAbort:
881     case RDIError_DataAbort:
882       return TARGET_SIGNAL_TRAP;
883     case RDIError_AddressException:
884       return TARGET_SIGNAL_SEGV;
885     case RDIError_IRQ:
886     case RDIError_FIQ:
887       return TARGET_SIGNAL_TRAP;
888     case RDIError_Error:
889       return TARGET_SIGNAL_TERM;
890     case RDIError_BranchThrough0:
891       return TARGET_SIGNAL_TRAP;
892     case RDIError_NotInitialised:
893     case RDIError_UnableToInitialise:
894     case RDIError_WrongByteSex:
895     case RDIError_UnableToTerminate:
896       return TARGET_SIGNAL_UNKNOWN;
897     case RDIError_BadInstruction:
898     case RDIError_IllegalInstruction:
899       return TARGET_SIGNAL_ILL;
900     case RDIError_BadCPUStateSetting:
901     case RDIError_UnknownCoPro:
902     case RDIError_UnknownCoProState:
903     case RDIError_BadCoProState:
904     case RDIError_BadPointType:
905     case RDIError_UnimplementedType:
906     case RDIError_BadPointSize:
907     case RDIError_UnimplementedSize:
908     case RDIError_NoMorePoints:
909       return TARGET_SIGNAL_UNKNOWN;
910     case RDIError_BreakpointReached:
911     case RDIError_WatchpointAccessed:
912       return TARGET_SIGNAL_TRAP;
913     case RDIError_NoSuchPoint:
914     case RDIError_ProgramFinishedInStep:
915       return TARGET_SIGNAL_UNKNOWN;
916     case RDIError_UserInterrupt:
917       return TARGET_SIGNAL_INT;
918     case RDIError_IncompatibleRDILevels:
919     case RDIError_LittleEndian:
920     case RDIError_BigEndian:
921     case RDIError_SoftInitialiseError:
922     case RDIError_InsufficientPrivilege:
923     case RDIError_UnimplementedMessage:
924     case RDIError_UndefinedMessage:
925     default:
926       return TARGET_SIGNAL_UNKNOWN; 
927     }
928 }
929 \f
930 /* Define the target operations structure.  */
931
932 static void
933 init_rdi_ops ()
934 {
935   arm_rdi_ops.to_shortname = "rdi";     
936   arm_rdi_ops.to_longname = "ARM RDI";
937   arm_rdi_ops.to_doc = "Use a remote ARM-based computer; via the RDI library.\n\
938 Specify the serial device it is connected to (e.g. /dev/ttya)." ; 
939   arm_rdi_ops.to_open = arm_rdi_open;           
940   arm_rdi_ops.to_close = arm_rdi_close; 
941   arm_rdi_ops.to_detach = arm_rdi_detach;       
942   arm_rdi_ops.to_resume = arm_rdi_resume;       
943   arm_rdi_ops.to_wait = arm_rdi_wait;   
944   arm_rdi_ops.to_fetch_registers = arm_rdi_fetch_registers;
945   arm_rdi_ops.to_store_registers = arm_rdi_store_registers;
946   arm_rdi_ops.to_prepare_to_store = arm_rdi_prepare_to_store;
947   arm_rdi_ops.to_xfer_memory = arm_rdi_xfer_memory;
948   arm_rdi_ops.to_files_info = arm_rdi_files_info;
949   arm_rdi_ops.to_insert_breakpoint = arm_rdi_insert_breakpoint;
950   arm_rdi_ops.to_remove_breakpoint = arm_rdi_remove_breakpoint; 
951   arm_rdi_ops.to_kill = arm_rdi_kill;           
952   arm_rdi_ops.to_load = generic_load;           
953   arm_rdi_ops.to_create_inferior = arm_rdi_create_inferior;
954   arm_rdi_ops.to_mourn_inferior = arm_rdi_mourn_inferior;
955   arm_rdi_ops.to_stratum = process_stratum;
956   arm_rdi_ops.to_has_all_memory = 1;    
957   arm_rdi_ops.to_has_memory = 1;        
958   arm_rdi_ops.to_has_stack = 1; 
959   arm_rdi_ops.to_has_registers = 1;     
960   arm_rdi_ops.to_has_execution = 1;     
961   arm_rdi_ops.to_magic = OPS_MAGIC;     
962 }
963
964 void
965 _initialize_remote_rdi ()
966 {
967   init_rdi_ops () ;
968   add_target (&arm_rdi_ops);
969 }
970
971 /* A little dummy to make linking with the library succeed. */
972
973 int Fail() { return 0; }