1 /* ICE interface for the NEC V850 for GDB, the GNU debugger.
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
23 #include "gdb_string.h"
27 #include "breakpoint.h"
38 #include <winuser.h> /* for WM_USER */
40 extern unsigned long int strtoul (const char *nptr
, char **endptr
,
43 /* Local data definitions */
46 int size
; /* length of input or output in bytes */
47 char *buf
; /* buffer having the input/output information */
50 /* Prototypes for functions located in other files */
51 extern void break_command (char *, int);
53 /* Prototypes for local functions */
54 static int init_hidden_window (void);
56 static LRESULT CALLBACK
v850ice_wndproc (HWND
, UINT
, WPARAM
, LPARAM
);
58 static void v850ice_files_info (struct target_ops
*ignore
);
60 static int v850ice_xfer_memory (CORE_ADDR memaddr
, char *myaddr
,
61 int len
, int should_write
,
62 struct target_ops
*target
);
64 static void v850ice_prepare_to_store (void);
66 static void v850ice_fetch_registers (int regno
);
68 static void v850ice_resume (ptid_t ptid
, int step
,
69 enum target_signal siggnal
);
71 static void v850ice_open (char *name
, int from_tty
);
73 static void v850ice_close (int quitting
);
75 static void v850ice_stop (void);
77 static void v850ice_store_registers (int regno
);
79 static void v850ice_mourn (void);
81 static ptid_t
v850ice_wait (ptid_t ptid
,
82 struct target_waitstatus
*status
);
84 static void v850ice_kill (void);
86 static void v850ice_detach (char *args
, int from_tty
);
88 static int v850ice_insert_breakpoint (CORE_ADDR
, char *);
90 static int v850ice_remove_breakpoint (CORE_ADDR
, char *);
92 static void v850ice_command (char *, int);
94 static int ice_disassemble (unsigned long, int, char *);
96 static int ice_lookup_addr (unsigned long *, char *, char *);
98 static int ice_lookup_symbol (unsigned long, char *);
100 static void ice_SimulateDisassemble (char *, int);
102 static void ice_SimulateAddrLookup (char *, int);
104 static void ice_Simulate_SymLookup (char *, int);
106 static void ice_fputs (const char *, struct ui_file
*);
108 static int ice_file (char *);
110 static int ice_cont (char *);
112 static int ice_stepi (char *);
114 static int ice_nexti (char *);
116 static void togdb_force_update (void);
118 static void view_source (CORE_ADDR
);
120 static void do_gdb (char *, char *, void (*func
) (char *, int), int);
124 static HWND hidden_hwnd
; /* HWND for messages */
126 long (__stdcall
* ExeAppReq
) (char *, long, char *, struct MessageIO
*);
128 long (__stdcall
* RegisterClient
) (HWND
);
130 long (__stdcall
* UnregisterClient
) (void);
132 extern Tcl_Interp
*gdbtk_interp
;
134 /* Globals local to this file only */
135 static int ice_open
= 0; /* Is ICE open? */
137 static char *v850_CB_Result
; /* special char array for saving 'callback' results */
139 static int SimulateCallback
; /* simulate a callback event */
141 #define MAX_BLOCK_SIZE 64*1024 /* Cannot transfer memory in blocks bigger
143 /* MDI/ICE Message IDs */
144 #define GSINGLESTEP 0x200 /* single-step target */
145 #define GRESUME 0x201 /* resume target */
146 #define GREADREG 0x202 /* read a register */
147 #define GWRITEREG 0x203 /* write a register */
148 #define GWRITEBLOCK 0x204 /* write a block of memory */
149 #define GREADBLOCK 0x205 /* read a block of memory */
150 #define GSETBREAK 0x206 /* set a breakpoint */
151 #define GREMOVEBREAK 0x207 /* remove a breakpoint */
152 #define GHALT 0x208 /* ??? */
153 #define GCHECKSTATUS 0x209 /* check status of ICE */
154 #define GMDIREPLY 0x210 /* Reply for previous query - NOT USED */
155 #define GDOWNLOAD 0x211 /* something for MDI */
156 #define GCOMMAND 0x212 /* execute command in ice */
157 #define GLOADFILENAME 0x213 /* retrieve load filename */
158 #define GWRITEMEM 0x214 /* write word, half-word, or byte */
160 /* GCHECKSTATUS return codes: */
161 #define ICE_Idle 0x00
162 #define ICE_Breakpoint 0x01 /* hit a breakpoint */
163 #define ICE_Stepped 0x02 /* have stepped */
164 #define ICE_Exception 0x03 /* have exception */
165 #define ICE_Halted 0x04 /* hit a user halt */
166 #define ICE_Exited 0x05 /* called exit */
167 #define ICE_Terminated 0x06 /* user terminated */
168 #define ICE_Running 0x07
169 #define ICE_Unknown 0x99
171 /* Windows messages */
172 #define WM_STATE_CHANGE WM_USER+101
173 #define WM_SYM_TO_ADDR WM_USER+102
174 #define WM_ADDR_TO_SYM WM_USER+103
175 #define WM_DISASSEMBLY WM_USER+104
176 #define WM_SOURCE WM_USER+105
178 /* STATE_CHANGE codes */
179 #define STATE_CHANGE_REGS 1 /* Register(s) changed */
180 #define STATE_CHANGE_LOAD 2 /* HW reset */
181 #define STATE_CHANGE_RESET 3 /* Load new file */
182 #define STATE_CHANGE_CONT 4 /* Run target */
183 #define STATE_CHANGE_STOP 5 /* Stop target */
184 #define STATE_CHANGE_STEPI 6 /* Stepi target */
185 #define STATE_CHANGE_NEXTI 7 /* Nexti target */
187 static struct target_ops v850ice_ops
; /* Forward decl */
189 /* This function creates a hidden window */
191 init_hidden_window (void)
195 if (hidden_hwnd
!= NULL
)
199 class.cbClsExtra
= 0;
200 class.cbWndExtra
= 0;
201 class.hInstance
= GetModuleHandle (0);
202 class.hbrBackground
= NULL
;
203 class.lpszMenuName
= NULL
;
204 class.lpszClassName
= "gdb_v850ice";
205 class.lpfnWndProc
= v850ice_wndproc
;
207 class.hCursor
= NULL
;
209 if (!RegisterClass (&class))
212 hidden_hwnd
= CreateWindow ("gdb_v850ice", "gdb_v850ice", WS_TILED
,
213 0, 0, 0, 0, NULL
, NULL
, class.hInstance
,
215 if (hidden_hwnd
== NULL
)
220 err
= GetLastError ();
221 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, err
,
223 printf_unfiltered ("Could not create window: %s", buf
);
231 This function is installed as the message handler for the hidden window
232 which QBox will use to communicate with gdb. It recognize and acts
233 on the following messages:
236 WM_ADDR_TO_SYM | Not implemented at NEC's request
238 WM_STATE_CHANGE - tells us that a state change has occured in the ICE
240 static LRESULT CALLBACK
241 v850ice_wndproc (HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
243 LRESULT result
= FALSE
;
248 MessageBox (0, "Symbol resolution\nNot implemented", "GDB", MB_OK
);
251 MessageBox (0, "Address resolution\nNot implemented", "GDB", MB_OK
);
254 view_source ((CORE_ADDR
) lParam
);
256 case WM_STATE_CHANGE
:
259 case STATE_CHANGE_LOAD
:
261 struct MessageIO iob
;
267 /* Load in a new file... Need filename */
268 ExeAppReq ("GDB", GLOADFILENAME
, NULL
, &iob
);
269 if (!catch_errors ((catch_errors_ftype
*) ice_file
, iob
.buf
, "", RETURN_MASK_ALL
))
270 printf_unfiltered ("load errored\n");
273 case STATE_CHANGE_RESET
:
274 registers_changed ();
275 flush_cached_frames ();
276 togdb_force_update ();
279 case STATE_CHANGE_REGS
:
280 registers_changed ();
281 togdb_force_update ();
284 case STATE_CHANGE_CONT
:
285 if (!catch_errors ((catch_errors_ftype
*) ice_cont
, NULL
, "", RETURN_MASK_ALL
))
286 printf_unfiltered ("continue errored\n");
289 case STATE_CHANGE_STEPI
:
290 if (!catch_errors ((catch_errors_ftype
*) ice_stepi
, (int) lParam
, "",
292 printf_unfiltered ("stepi errored\n");
295 case STATE_CHANGE_NEXTI
:
296 if (!catch_errors ((catch_errors_ftype
*) ice_nexti
, (int) lParam
, "",
298 printf_unfiltered ("nexti errored\n");
305 return DefWindowProc (hwnd
, message
, wParam
, lParam
);
310 /* Code for opening a connection to the ICE. */
313 v850ice_open (char *name
, int from_tty
)
318 error ("Too many arguments.");
320 target_preopen (from_tty
);
322 unpush_target (&v850ice_ops
);
325 puts_filtered ("V850ice debugging\n");
327 push_target (&v850ice_ops
); /* Switch to using v850ice target now */
329 target_terminal_init ();
331 /* Initialize everything necessary to facilitate communication
332 between QBox, gdb, and the DLLs which control the ICE */
333 if (ExeAppReq
== NULL
)
335 handle
= LoadLibrary ("necmsg.dll");
337 error ("Cannot load necmsg.dll");
339 ExeAppReq
= (long (*) (char *, long, char *, struct MessageIO
*))
340 GetProcAddress (handle
, "ExeAppReq");
341 RegisterClient
= (long (*) (HWND
))
342 GetProcAddress (handle
, "RegisterClient");
343 UnregisterClient
= (long (*) (void))
344 GetProcAddress (handle
, "UnregisterClient");
346 if (ExeAppReq
== NULL
|| RegisterClient
== NULL
|| UnregisterClient
== NULL
)
347 error ("Could not find requisite functions in necmsg.dll.");
349 if (!init_hidden_window ())
350 error ("could not initialize message handling");
353 /* Tell the DLL we are here */
354 RegisterClient (hidden_hwnd
);
358 /* Without this, some commands which require an active target (such as kill)
359 won't work. This variable serves (at least) double duty as both the pid
360 of the target process (if it has such), and as a flag indicating that a
361 target is active. These functions should be split out into seperate
362 variables, especially since GDB will someday have a notion of debugging
363 several processes. */
364 inferior_ptid
= pid_to_ptid (42000);
370 /* Clean up connection to a remote debugger. */
373 v850ice_close (int quitting
)
379 inferior_ptid
= null_ptid
;
383 /* Stop the process on the ice. */
387 /* This is silly, but it works... */
388 v850ice_command ("stop", 0);
392 v850ice_detach (char *args
, int from_tty
)
395 error ("Argument given to \"detach\" when remotely debugging.");
399 puts_filtered ("Ending v850ice debugging.\n");
402 /* Tell the remote machine to resume. */
405 v850ice_resume (ptid_t ptid
, int step
, enum target_signal siggnal
)
409 struct MessageIO iob
;
415 retval
= ExeAppReq ("GDB", GSINGLESTEP
, "step", &iob
);
417 retval
= ExeAppReq ("GDB", GRESUME
, "run", &iob
);
420 error ("ExeAppReq (step = %d) returned %d", step
, retval
);
423 /* Wait until the remote machine stops, then return,
424 storing status in STATUS just as `wait' would.
425 Returns "pid" (though it's not clear what, if anything, that
426 means in the case of this target). */
429 v850ice_wait (ptid_t ptid
, struct target_waitstatus
*status
)
433 struct MessageIO iob
;
442 if (count
++ % 100000)
444 deprecated_ui_loop_hook (0);
448 v850_status
= ExeAppReq ("GDB", GCHECKSTATUS
, NULL
, &iob
);
456 status
->kind
= TARGET_WAITKIND_STOPPED
;
457 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
461 status
->kind
= TARGET_WAITKIND_SIGNALLED
;
462 status
->value
.sig
= TARGET_SIGNAL_SEGV
;
466 status
->kind
= TARGET_WAITKIND_EXITED
;
467 status
->value
.integer
= 0;
471 status
->kind
= TARGET_WAITKIND_SIGNALLED
;
472 status
->value
.sig
= TARGET_SIGNAL_KILL
;
481 return inferior_ptid
;
485 convert_register (int regno
, char *buf
)
488 sprintf (buf
, "r%d", regno
);
489 else if (REGISTER_NAME (regno
)[0] == 's'
490 && REGISTER_NAME (regno
)[1] == 'r')
493 sprintf (buf
, "%s", REGISTER_NAME (regno
));
498 /* Read the remote registers into the block REGS. */
499 /* Note that the ICE returns register contents as ascii hex strings. We have
500 to convert that to an unsigned long, and then call store_unsigned_integer to
501 convert it to target byte-order if necessary. */
504 v850ice_fetch_registers (int regno
)
509 struct MessageIO iob
;
510 unsigned long regval
;
515 for (regno
= 0; regno
< NUM_REGS
; regno
++)
516 v850ice_fetch_registers (regno
);
520 strcpy (cmd
, "reg ");
521 if (!convert_register (regno
, &cmd
[4]))
524 iob
.size
= sizeof val
;
526 retval
= ExeAppReq ("GDB", GREADREG
, cmd
, &iob
);
528 error ("1: ExeAppReq returned %d: cmd = %s", retval
, cmd
);
530 regval
= strtoul (val
, NULL
, 16);
531 if (regval
== 0 && p
== val
)
532 error ("v850ice_fetch_registers (%d): bad value from ICE: %s.",
535 store_unsigned_integer (val
, register_size (current_gdbarch
, regno
), regval
);
536 regcache_raw_supply (current_regcache
, regno
, val
);
539 /* Store register REGNO, or all registers if REGNO == -1, from the contents
543 v850ice_store_registers (int regno
)
547 unsigned long regval
;
549 struct MessageIO iob
;
555 for (regno
= 0; regno
< NUM_REGS
; regno
++)
556 v850ice_store_registers (regno
);
560 regval
= extract_unsigned_integer (&deprecated_registers
[DEPRECATED_REGISTER_BYTE (regno
)],
561 register_size (current_gdbarch
, regno
));
562 strcpy (cmd
, "reg ");
563 if (!convert_register (regno
, &cmd
[4]))
565 sprintf (cmd
+ strlen (cmd
), "=0x%x", regval
);
567 retval
= ExeAppReq ("GDB", GWRITEREG
, cmd
, &iob
);
569 error ("2: ExeAppReq returned %d: cmd = %s", retval
, cmd
);
572 /* Prepare to store registers. Nothing to do here, since the ICE can write one
573 register at a time. */
576 v850ice_prepare_to_store (void)
580 /* Read or write LEN bytes from inferior memory at MEMADDR, transferring
581 to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
582 nonzero. TARGET is unused. Returns length of data written or read;
585 We can only read/write MAX_BLOCK_SIZE bytes at a time, though, or the DLL
588 v850ice_xfer_memory (CORE_ADDR memaddr
, char *myaddr
, int len
,
589 int should_write
, struct target_ops
*target
)
593 struct MessageIO iob
;
598 if (len
== 4 || len
== 2 || len
== 1)
612 value
|= (long) ((myaddr
[3] << 24) & 0xff000000);
613 value
|= (long) ((myaddr
[2] << 16) & 0x00ff0000);
614 value
|= (long) ((myaddr
[1] << 8) & 0x0000ff00);
615 value
|= (long) (myaddr
[0] & 0x000000ff);
619 value
|= (long) ((myaddr
[1] << 8) & 0xff00);
620 value
|= (long) (myaddr
[0] & 0x00ff);
624 value
|= (long) (myaddr
[0] & 0xff);
628 sprintf (cmd
, "memory %c c 0x%x=0x%x", c
, (int) memaddr
, value
);
629 retval
= ExeAppReq ("GDB", GWRITEMEM
, cmd
, &iob
);
638 iob
.size
= len
> MAX_BLOCK_SIZE
? MAX_BLOCK_SIZE
: len
;
640 sprintf (cmd
, "memory b c 0x%x=0x00 l=%d", (int) memaddr
, iob
.size
);
641 retval
= ExeAppReq ("GDB", GWRITEBLOCK
, cmd
, &iob
);
658 tmp
= alloca (len
+ 100);
660 memset (tmp
+ len
, 0xff, 100);
665 iob
.size
= len
> MAX_BLOCK_SIZE
? MAX_BLOCK_SIZE
: len
;
667 sprintf (cmd
, "memory b 0x%x l=%d", (int) memaddr
, iob
.size
);
668 retval
= ExeAppReq ("GDB", GREADBLOCK
, cmd
, &iob
);
680 for (i
= 0; i
< 100; i
++)
682 if (t
[sent
+ i
] != 0xff)
684 warning ("GREADBLOCK trashed bytes after transfer area.");
688 memcpy (myaddr
, t
, sent
);
693 error ("3: ExeAppReq returned %d: cmd = %s", retval
, cmd
);
699 v850ice_files_info (struct target_ops
*ignore
)
701 puts_filtered ("Debugging a target via the NEC V850 ICE.\n");
705 v850ice_insert_breakpoint (CORE_ADDR addr
, char *contents_cache
)
710 struct MessageIO iob
;
714 sprintf (cmd
, "%d, ", addr
);
716 retval
= ExeAppReq ("GDB", GSETBREAK
, cmd
, &iob
);
718 error ("ExeAppReq (GSETBREAK) returned %d: cmd = %s", retval
, cmd
);
724 v850ice_remove_breakpoint (CORE_ADDR addr
, char *contents_cache
)
729 struct MessageIO iob
;
734 sprintf (cmd
, "%d, ", addr
);
736 retval
= ExeAppReq ("GDB", GREMOVEBREAK
, cmd
, &iob
);
738 error ("ExeAppReq (GREMOVEBREAK) returned %d: cmd = %s", retval
, cmd
);
746 target_mourn_inferior ();
747 inferior_ptid
= null_ptid
;
756 v850ice_load (char *filename
, int from_tty
)
758 struct MessageIO iob
;
763 generic_load (filename
, from_tty
);
764 ExeAppReq ("GDB", GDOWNLOAD
, filename
, &iob
);
772 target_detach (NULL
, 0);
775 printf_unfiltered ("\n");
785 /* Safegaurd against confusing the breakpoint routines... */
786 delete_command (NULL
, 0);
788 /* Must supress from_tty, otherwise we could start asking if the
789 user really wants to load a new symbol table, etc... */
790 printf_unfiltered ("Reading symbols from %s...", arg
);
792 symbol_file_add_main (arg
, 0);
793 printf_unfiltered ("done\n");
795 /* exec_open will kill our target, so reinstall the ICE as
797 v850ice_open (NULL
, 0);
799 togdb_force_update ();
806 printf_filtered ("continue (ice)\n");
807 ReplyMessage ((LRESULT
) 1);
809 if (gdbtk_interp
== NULL
)
811 continue_command (NULL
, 1);
814 Tcl_Eval (gdbtk_interp
, "gdb_immediate continue");
820 do_gdb (char *cmd
, char *str
, void (*func
) (char *, int), int count
)
822 ReplyMessage ((LRESULT
) 1);
826 printf_unfiltered (str
);
828 if (gdbtk_interp
== NULL
)
833 Tcl_Eval (gdbtk_interp
, cmd
);
843 do_gdb ("gdb_immediate stepi", "stepi (ice)\n", stepi_command
, count
);
852 do_gdb ("gdb_immediate nexti", "nexti (ice)\n", nexti_command
, count
);
857 v850ice_command (char *arg
, int from_tty
)
859 struct MessageIO iob
;
864 ExeAppReq ("GDB", GCOMMAND
, arg
, &iob
);
868 togdb_force_update (void)
870 if (gdbtk_interp
!= NULL
)
871 Tcl_Eval (gdbtk_interp
, "gdbtk_update");
875 view_source (CORE_ADDR addr
)
879 if (gdbtk_interp
!= NULL
)
881 sprintf (c
, "catch {set src [lindex [ManagedWin::find SrcWin] 0]\n$src location BROWSE [gdb_loc *0x%x]}", addr
);
882 Tcl_Eval (gdbtk_interp
, c
);
886 /* Define the target subroutine names */
889 init_850ice_ops (void)
891 v850ice_ops
.to_shortname
= "ice";
892 v850ice_ops
.to_longname
= "NEC V850 ICE interface";
893 v850ice_ops
.to_doc
= "Debug a system controlled by a NEC 850 ICE.";
894 v850ice_ops
.to_open
= v850ice_open
;
895 v850ice_ops
.to_close
= v850ice_close
;
896 v850ice_ops
.to_detach
= v850ice_detach
;
897 v850ice_ops
.to_resume
= v850ice_resume
;
898 v850ice_ops
.to_wait
= v850ice_wait
;
899 v850ice_ops
.to_fetch_registers
= v850ice_fetch_registers
;
900 v850ice_ops
.to_store_registers
= v850ice_store_registers
;
901 v850ice_ops
.to_prepare_to_store
= v850ice_prepare_to_store
;
902 v850ice_ops
.deprecated_xfer_memory
= v850ice_xfer_memory
;
903 v850ice_ops
.to_files_info
= v850ice_files_info
;
904 v850ice_ops
.to_insert_breakpoint
= v850ice_insert_breakpoint
;
905 v850ice_ops
.to_remove_breakpoint
= v850ice_remove_breakpoint
;
906 v850ice_ops
.to_kill
= v850ice_kill
;
907 v850ice_ops
.to_load
= v850ice_load
;
908 v850ice_ops
.to_mourn_inferior
= v850ice_mourn
;
909 v850ice_ops
.to_stop
= v850ice_stop
;
910 v850ice_ops
.to_stratum
= process_stratum
;
911 v850ice_ops
.to_has_all_memory
= 1;
912 v850ice_ops
.to_has_memory
= 1;
913 v850ice_ops
.to_has_stack
= 1;
914 v850ice_ops
.to_has_registers
= 1;
915 v850ice_ops
.to_has_execution
= 1;
916 v850ice_ops
.to_magic
= OPS_MAGIC
;
920 _initialize_v850ice (void)
923 add_target (&v850ice_ops
);
925 add_com ("ice", class_obscure
, v850ice_command
,
926 "Send command to ICE");