1 /* ICE interface for the NEC V850 for GDB, the GNU debugger.
2 Copyright 1996, Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Pessublic License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
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.
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. */
21 #include "gdb_string.h"
25 #include "breakpoint.h"
36 #include <winuser.h> /* for WM_USER */
38 extern unsigned long int strtoul(const char *nptr
, char **endptr
,
41 /* Local data definitions */
44 int size
; /* length of input or output in bytes */
45 char * buf
; /* buffer having the input/output information */
48 /* Prototypes for functions located in other files */
49 extern void break_command
PARAMS ((char *, int));
51 extern void stepi_command
PARAMS ((char *, int));
53 extern void nexti_command
PARAMS ((char *, int));
55 extern void continue_command
PARAMS ((char *, int));
57 extern HINSTANCE Tk_GetHINSTANCE
PARAMS ((void));
59 extern void (*ui_loop_hook
) PARAMS ((int));
61 /* Prototypes for local functions */
62 static int init_hidden_window
PARAMS ((void));
64 static LRESULT CALLBACK v850ice_wndproc
PARAMS ((HWND
, UINT
, WPARAM
, LPARAM
));
66 static void v850ice_files_info
PARAMS ((struct target_ops
*ignore
));
68 static int v850ice_xfer_memory
PARAMS ((CORE_ADDR memaddr
, char *myaddr
,
69 int len
, int should_write
,
70 struct target_ops
*target
));
72 static void v850ice_prepare_to_store
PARAMS ((void));
74 static void v850ice_fetch_registers
PARAMS ((int regno
));
76 static void v850ice_resume
PARAMS ((int pid
, int step
,
77 enum target_signal siggnal
));
79 static void v850ice_open
PARAMS ((char *name
, int from_tty
));
81 static void v850ice_close
PARAMS ((int quitting
));
83 static void v850ice_stop
PARAMS ((void));
85 static void v850ice_store_registers
PARAMS ((int regno
));
87 static void v850ice_mourn
PARAMS ((void));
89 static int v850ice_wait
PARAMS ((int pid
, struct target_waitstatus
*status
));
91 static void v850ice_kill
PARAMS ((void));
93 static void v850ice_detach
PARAMS ((char *args
, int from_tty
));
95 static int v850ice_insert_breakpoint
PARAMS ((CORE_ADDR
, char *));
97 static int v850ice_remove_breakpoint
PARAMS ((CORE_ADDR
, char *));
99 static void v850ice_command
PARAMS ((char *, int));
101 static int ice_disassemble
PARAMS ((unsigned long, int, char *));
103 static int ice_lookup_addr
PARAMS ((unsigned long *, char *, char *));
105 static int ice_lookup_symbol
PARAMS ((unsigned long, char *));
107 static void ice_SimulateDisassemble
PARAMS ((char *, int));
109 static void ice_SimulateAddrLookup
PARAMS ((char *, int));
111 static void ice_Simulate_SymLookup
PARAMS ((char *, int));
113 static void ice_fputs
PARAMS ((const char *, GDB_FILE
*));
115 static int ice_file
PARAMS ((char *));
117 static int ice_cont
PARAMS ((char *));
119 static int ice_stepi
PARAMS ((char *));
121 static int ice_nexti
PARAMS ((char *));
123 static void togdb_force_update
PARAMS ((void));
125 static void view_source
PARAMS ((CORE_ADDR
));
127 static void do_gdb (char *, char *, int);
131 static HWND hidden_hwnd
; /* HWND for messages */
133 long (__stdcall
*ExeAppReq
) PARAMS ((char *, long, char *, struct MessageIO
*));
135 long (__stdcall
*RegisterClient
) PARAMS ((HWND
));
137 long (__stdcall
*UnregisterClient
) PARAMS ((void));
139 extern Tcl_Interp
*gdbtk_interp
;
141 /* Globals local to this file only */
142 static int ice_open
= 0; /* Is ICE open? */
144 static char * v850_CB_Result
; /* special char array for saving 'callback' results */
146 static int SimulateCallback
; /* simulate a callback event */
148 #define MAX_BLOCK_SIZE 64*1024 /* Cannot transfer memory in blocks bigger
150 /* MDI/ICE Message IDs */
151 #define GSINGLESTEP 0x200 /* single-step target */
152 #define GRESUME 0x201 /* resume target */
153 #define GREADREG 0x202 /* read a register */
154 #define GWRITEREG 0x203 /* write a register */
155 #define GWRITEBLOCK 0x204 /* write a block of memory */
156 #define GREADBLOCK 0x205 /* read a block of memory */
157 #define GSETBREAK 0x206 /* set a breakpoint */
158 #define GREMOVEBREAK 0x207 /* remove a breakpoint */
159 #define GHALT 0x208 /* ??? */
160 #define GCHECKSTATUS 0x209 /* check status of ICE */
161 #define GMDIREPLY 0x210 /* Reply for previous query - NOT USED */
162 #define GDOWNLOAD 0x211 /* something for MDI */
163 #define GCOMMAND 0x212 /* execute command in ice */
164 #define GLOADFILENAME 0x213 /* retrieve load filename */
165 #define GWRITEMEM 0x214 /* write word, half-word, or byte */
167 /* GCHECKSTATUS return codes: */
168 #define ICE_Idle 0x00
169 #define ICE_Breakpoint 0x01 /* hit a breakpoint */
170 #define ICE_Stepped 0x02 /* have stepped */
171 #define ICE_Exception 0x03 /* have exception */
172 #define ICE_Halted 0x04 /* hit a user halt */
173 #define ICE_Exited 0x05 /* called exit */
174 #define ICE_Terminated 0x06 /* user terminated */
175 #define ICE_Running 0x07
176 #define ICE_Unknown 0x99
178 /* Windows messages */
179 #define WM_STATE_CHANGE WM_USER+101
180 #define WM_SYM_TO_ADDR WM_USER+102
181 #define WM_ADDR_TO_SYM WM_USER+103
182 #define WM_DISASSEMBLY WM_USER+104
183 #define WM_SOURCE WM_USER+105
185 /* STATE_CHANGE codes */
186 #define STATE_CHANGE_REGS 1 /* Register(s) changed */
187 #define STATE_CHANGE_LOAD 2 /* HW reset */
188 #define STATE_CHANGE_RESET 3 /* Load new file */
189 #define STATE_CHANGE_CONT 4 /* Run target */
190 #define STATE_CHANGE_STOP 5 /* Stop target */
191 #define STATE_CHANGE_STEPI 6 /* Stepi target */
192 #define STATE_CHANGE_NEXTI 7 /* Nexti target */
194 static struct target_ops v850ice_ops
; /* Forward decl */
196 /* This function creates a hidden window */
198 init_hidden_window ()
202 if (hidden_hwnd
!= NULL
)
206 class.cbClsExtra
= 0;
207 class.cbWndExtra
= 0;
208 class.hInstance
= Tk_GetHINSTANCE();
209 class.hbrBackground
= NULL
;
210 class.lpszMenuName
= NULL
;
211 class.lpszClassName
= "gdbtk_v850ice";
212 class.lpfnWndProc
= v850ice_wndproc
;
214 class.hCursor
= NULL
;
216 if (! RegisterClass (&class))
219 hidden_hwnd
= CreateWindow ("gdbtk_v850ice", "gdbtk_v850ice", WS_TILED
,
220 0, 0, 0, 0, NULL
, NULL
, class.hInstance
,
222 if (hidden_hwnd
== NULL
)
227 err
= GetLastError ();
228 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, err
,
230 printf_unfiltered ("Could not create window: %s", buf
);
238 This function is installed as the message handler for the hidden window
239 which QBox will use to communicate with gdbtk. It recognize and acts
240 on the following messages:
243 WM_ADDR_TO_SYM | Not implemented at NEC's request
245 WM_STATE_CHANGE - tells us that a state change has occured in the ICE
247 static LRESULT CALLBACK
248 v850ice_wndproc (hwnd
, message
, wParam
, lParam
)
254 LRESULT result
= FALSE
;
259 MessageBox (0, "Symbol resolution\nNot implemented", "GDB", MB_OK
);
262 MessageBox (0, "Address resolution\nNot implemented", "GDB", MB_OK
);
265 view_source ((CORE_ADDR
) lParam
);
267 case WM_STATE_CHANGE
:
270 case STATE_CHANGE_LOAD
:
272 struct MessageIO iob
;
278 /* Load in a new file... Need filename */
279 ExeAppReq ("GDB", GLOADFILENAME
, NULL
, &iob
);
280 if (!catch_errors (ice_file
, iob
.buf
, "", RETURN_MASK_ALL
))
281 printf_unfiltered ("load errored\n");
284 case STATE_CHANGE_RESET
:
285 registers_changed ();
286 flush_cached_frames ();
287 togdb_force_update ();
290 case STATE_CHANGE_REGS
:
291 registers_changed ();
292 togdb_force_update ();
295 case STATE_CHANGE_CONT
:
296 if (!catch_errors (ice_cont
, NULL
, "", RETURN_MASK_ALL
))
297 printf_unfiltered ("continue errored\n");
300 case STATE_CHANGE_STEPI
:
301 if (!catch_errors (ice_stepi
, (PTR
)(int) lParam
, "",
303 printf_unfiltered ("stepi errored\n");
306 case STATE_CHANGE_NEXTI
:
307 if (!catch_errors (ice_nexti
, (PTR
)(int) lParam
, "",
309 printf_unfiltered ("nexti errored\n");
316 return DefWindowProc (hwnd
, message
, wParam
, lParam
);
321 /* Code for opening a connection to the ICE. */
324 v850ice_open (name
, from_tty
)
331 error ("Too many arguments.");
333 target_preopen (from_tty
);
335 unpush_target (&v850ice_ops
);
338 puts_filtered ("V850ice debugging\n");
340 push_target (&v850ice_ops
); /* Switch to using v850ice target now */
342 target_terminal_init ();
344 /* Initialize everything necessary to facilitate communication
345 between QBox, gdbtk, and the DLLs which control the ICE */
346 if (ExeAppReq
== NULL
)
348 handle
= LoadLibrary ("necmsg.dll");
350 error ("Cannot load necmsg.dll");
352 ExeAppReq
= (long (*) PARAMS ((char *, long, char *, struct MessageIO
*)))
353 GetProcAddress (handle
, "ExeAppReq");
354 RegisterClient
= (long (*) PARAMS ((HWND
)))
355 GetProcAddress (handle
, "RegisterClient");
356 UnregisterClient
= (long (*) PARAMS ((void)))
357 GetProcAddress (handle
, "UnregisterClient");
359 if (ExeAppReq
== NULL
|| RegisterClient
== NULL
|| UnregisterClient
== NULL
)
360 error ("Could not find requisite functions in necmsg.dll.");
362 if (init_hidden_window () != TCL_OK
)
363 error ("could not initialize message handling");
366 /* Tell the DLL we are here */
367 RegisterClient (hidden_hwnd
);
371 /* Without this, some commands which require an active target (such as kill)
372 won't work. This variable serves (at least) double duty as both the pid
373 of the target process (if it has such), and as a flag indicating that a
374 target is active. These functions should be split out into seperate
375 variables, especially since GDB will someday have a notion of debugging
376 several processes. */
377 inferior_pid
= 42000;
383 /* Clean up connection to a remote debugger. */
387 v850ice_close (quitting
)
398 /* Stop the process on the ice. */
402 /* This is silly, but it works... */
403 v850ice_command ("stop", 0);
407 v850ice_detach (args
, from_tty
)
412 error ("Argument given to \"detach\" when remotely debugging.");
416 puts_filtered ("Ending v850ice debugging.\n");
419 /* Tell the remote machine to resume. */
422 v850ice_resume (pid
, step
, siggnal
)
424 enum target_signal siggnal
;
428 struct MessageIO iob
;
434 retval
= ExeAppReq ("GDB", GSINGLESTEP
, "step", &iob
);
436 retval
= ExeAppReq ("GDB", GRESUME
, "run", &iob
);
439 error ("ExeAppReq (step = %d) returned %d", step
, retval
);
442 /* Wait until the remote machine stops, then return,
443 storing status in STATUS just as `wait' would.
444 Returns "pid" (though it's not clear what, if anything, that
445 means in the case of this target). */
448 v850ice_wait (pid
, status
)
450 struct target_waitstatus
*status
;
454 struct MessageIO iob
;
463 if (count
++ % 100000)
469 v850_status
= ExeAppReq ("GDB", GCHECKSTATUS
, NULL
, &iob
);
477 status
->kind
= TARGET_WAITKIND_STOPPED
;
478 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
482 status
->kind
= TARGET_WAITKIND_SIGNALLED
;
483 status
->value
.sig
= TARGET_SIGNAL_SEGV
;
487 status
->kind
= TARGET_WAITKIND_EXITED
;
488 status
->value
.integer
= 0;
492 status
->kind
= TARGET_WAITKIND_SIGNALLED
;
493 status
->value
.sig
= TARGET_SIGNAL_KILL
;
506 convert_register (regno
, buf
)
511 sprintf (buf
, "r%d", regno
);
512 else if (REGISTER_NAME (regno
)[0] == 's'
513 && REGISTER_NAME (regno
)[1] == 'r')
516 sprintf (buf
, "%s", REGISTER_NAME (regno
));
521 /* Read the remote registers into the block REGS. */
522 /* Note that the ICE returns register contents as ascii hex strings. We have
523 to convert that to an unsigned long, and then call store_unsigned_integer to
524 convert it to target byte-order if necessary. */
527 v850ice_fetch_registers (regno
)
533 struct MessageIO iob
;
534 unsigned long regval
;
539 for (regno
= 0; regno
< NUM_REGS
; regno
++)
540 v850ice_fetch_registers (regno
);
544 strcpy (cmd
, "reg ");
545 if (!convert_register (regno
, &cmd
[4]))
548 iob
.size
= sizeof val
;
550 retval
= ExeAppReq ("GDB", GREADREG
, cmd
, &iob
);
552 error ("1: ExeAppReq returned %d: cmd = %s", retval
, cmd
);
554 regval
= strtoul (val
, NULL
, 16);
555 if (regval
== 0 && p
== val
)
556 error ("v850ice_fetch_registers (%d): bad value from ICE: %s.",
559 store_unsigned_integer (val
, REGISTER_RAW_SIZE (regno
), regval
);
560 supply_register (regno
, val
);
563 /* Store register REGNO, or all registers if REGNO == -1, from the contents
567 v850ice_store_registers (regno
)
572 unsigned long regval
;
574 struct MessageIO iob
;
580 for (regno
= 0; regno
< NUM_REGS
; regno
++)
581 v850ice_store_registers (regno
);
585 regval
= extract_unsigned_integer (®isters
[REGISTER_BYTE (regno
)],
586 REGISTER_RAW_SIZE (regno
));
587 strcpy (cmd
, "reg ");
588 if (!convert_register (regno
, &cmd
[4]))
590 sprintf (cmd
+ strlen (cmd
), "=0x%x", regval
);
592 retval
= ExeAppReq ("GDB", GWRITEREG
, cmd
, &iob
);
594 error ("2: ExeAppReq returned %d: cmd = %s", retval
, cmd
);
597 /* Prepare to store registers. Nothing to do here, since the ICE can write one
598 register at a time. */
601 v850ice_prepare_to_store ()
605 /* Read or write LEN bytes from inferior memory at MEMADDR, transferring
606 to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
607 nonzero. Returns length of data written or read; 0 for error.
609 We can only read/write MAX_BLOCK_SIZE bytes at a time, though, or the DLL
613 v850ice_xfer_memory (memaddr
, myaddr
, len
, should_write
, target
)
618 struct target_ops
*target
; /* ignored */
622 struct MessageIO iob
;
627 if (len
== 4 || len
== 2 || len
== 1)
641 value
|= (long) (myaddr
[3] << 24) & 0xff000000;
642 value
|= (long) (myaddr
[2] << 16) & 0x00ff0000;
643 value
|= (long) (myaddr
[1] << 8) & 0x0000ff00;
644 value
|= (long) myaddr
[0] & 0x000000ff;
647 value
|= (long) myaddr
[1] << 8 & 0xff00;
648 value
|= (long) myaddr
[0] & 0x00ff;
652 value
|= (long) myaddr
[0] & 0xff;
656 sprintf (cmd
, "memory %c c 0x%x=0x%x", c
, (int) memaddr
, value
);
657 retval
= ExeAppReq ("GDB", GWRITEMEM
, cmd
, &iob
);
666 iob
.size
= len
> MAX_BLOCK_SIZE
? MAX_BLOCK_SIZE
: len
;
668 sprintf (cmd
, "memory b c 0x%x=0x00 l=%d", (int)memaddr
, iob
.size
);
669 retval
= ExeAppReq ("GDB", GWRITEBLOCK
, cmd
, &iob
);
686 tmp
= alloca (len
+ 100);
688 memset (tmp
+ len
, 0xff, 100);
693 iob
.size
= len
> MAX_BLOCK_SIZE
? MAX_BLOCK_SIZE
: len
;
695 sprintf (cmd
, "memory b 0x%x l=%d", (int)memaddr
, iob
.size
);
696 retval
= ExeAppReq ("GDB", GREADBLOCK
, cmd
, &iob
);
708 for (i
= 0; i
< 100; i
++)
710 if (t
[sent
+ i
] != 0xff)
712 warning ("GREADBLOCK trashed bytes after transfer area.");
716 memcpy (myaddr
, t
, sent
);
721 error ("3: ExeAppReq returned %d: cmd = %s", retval
, cmd
);
727 v850ice_files_info (ignore
)
728 struct target_ops
*ignore
;
730 puts_filtered ("Debugging a target via the NEC V850 ICE.\n");
734 v850ice_insert_breakpoint (addr
, contents_cache
)
736 char *contents_cache
;
741 struct MessageIO iob
;
745 sprintf (cmd
, "%d, ", addr
);
747 retval
= ExeAppReq ("GDB", GSETBREAK
, cmd
, &iob
);
749 error ("ExeAppReq (GSETBREAK) returned %d: cmd = %s", retval
, cmd
);
755 v850ice_remove_breakpoint (addr
, contents_cache
)
757 char *contents_cache
;
762 struct MessageIO iob
;
767 sprintf (cmd
, "%d, ", addr
);
769 retval
= ExeAppReq ("GDB", GREMOVEBREAK
, cmd
, &iob
);
771 error ("ExeAppReq (GREMOVEBREAK) returned %d: cmd = %s", retval
, cmd
);
779 target_mourn_inferior ();
789 v850ice_load (filename
, from_tty
)
793 struct MessageIO iob
;
798 generic_load(filename
, from_tty
);
799 ExeAppReq ("GDB", GDOWNLOAD
, filename
, &iob
);
808 target_detach (NULL
, 0);
811 printf_unfiltered ("\n");
821 /* Safegaurd against confusing the breakpoint routines... */
822 delete_command(NULL
, 0);
824 /* Must supress from_tty, otherwise we could start asking if the
825 user really wants to load a new symbol table, etc... */
826 printf_unfiltered ("Reading symbols from %s...", arg
);
827 exec_file_command (arg
, 0);
828 symbol_file_command (arg
, 0);
829 printf_unfiltered ("done\n");
831 /* exec_file_command will kill our target, so reinstall the ICE as
833 v850ice_open (NULL
, 0);
835 togdb_force_update ();
843 printf_filtered ("continue (ice)");
844 ReplyMessage ((LRESULT
) 1);
845 Tcl_Eval (gdbtk_interp
, "gdb_immediate continue");
850 do_gdb (cmd
, str
, count
)
856 ReplyMessage ((LRESULT
) 1);
860 printf_unfiltered (str
);
861 Tcl_Eval (gdbtk_interp
, cmd
);
872 do_gdb ("gdb_immediate stepi", "stepi (ice)\n", count
);
882 do_gdb ("gdb_immediate nexti", "nexti (ice)\n", count
);
887 v850ice_command (arg
, from_tty
)
891 struct MessageIO iob
;
896 ExeAppReq ("GDB", GCOMMAND
, arg
, &iob
);
900 togdb_force_update (void)
902 Tcl_Eval (gdbtk_interp
, "gdbtk_update");
911 sprintf (c
, "set src [lindex [manage find src] 0]\n$src location BROWSE [gdb_loc *0x%x]", addr
);
912 Tcl_Eval (gdbtk_interp
, c
);
915 /* Define the target subroutine names */
917 static void init_850ice_ops(void)
919 v850ice_ops
.to_shortname
= "ice";
920 v850ice_ops
.to_longname
= "NEC V850 ICE interface";
921 v850ice_ops
.to_doc
= "Debug a system controlled by a NEC 850 ICE.";
922 v850ice_ops
.to_open
= v850ice_open
;
923 v850ice_ops
.to_close
= v850ice_close
;
924 v850ice_ops
.to_attach
= NULL
;
925 v850ice_ops
.to_detach
= v850ice_detach
;
926 v850ice_ops
.to_resume
= v850ice_resume
;
927 v850ice_ops
.to_wait
= v850ice_wait
;
928 v850ice_ops
.to_fetch_registers
= v850ice_fetch_registers
;
929 v850ice_ops
.to_store_registers
= v850ice_store_registers
;
930 v850ice_ops
.to_prepare_to_store
= v850ice_prepare_to_store
;
931 v850ice_ops
.to_xfer_memory
= v850ice_xfer_memory
;
932 v850ice_ops
.to_files_info
= v850ice_files_info
;
933 v850ice_ops
.to_insert_breakpoint
= v850ice_insert_breakpoint
;
934 v850ice_ops
.to_remove_breakpoint
= v850ice_remove_breakpoint
;
935 v850ice_ops
.to_terminal_init
= NULL
;
936 v850ice_ops
.to_terminal_inferior
= NULL
;
937 v850ice_ops
.to_terminal_ours_for_output
= NULL
;
938 v850ice_ops
.to_terminal_ours
= NULL
;
939 v850ice_ops
.to_terminal_info
= NULL
;
940 v850ice_ops
.to_kill
= v850ice_kill
;
941 v850ice_ops
.to_load
= v850ice_load
;
942 v850ice_ops
.to_lookup_symbol
= NULL
;
943 v850ice_ops
.to_create_inferior
= NULL
;
944 v850ice_ops
.to_mourn_inferior
= v850ice_mourn
;
945 v850ice_ops
.to_can_run
= 0;
946 v850ice_ops
.to_notice_signals
= 0;
947 v850ice_ops
.to_thread_alive
= NULL
;
948 v850ice_ops
.to_stop
= v850ice_stop
;
949 v850ice_ops
.to_stratum
= process_stratum
;
950 v850ice_ops
.DONT_USE
= NULL
;
951 v850ice_ops
.to_has_all_memory
= 1;
952 v850ice_ops
.to_has_memory
= 1;
953 v850ice_ops
.to_has_stack
= 1;
954 v850ice_ops
.to_has_registers
= 1;
955 v850ice_ops
.to_has_execution
= 1;
956 v850ice_ops
.to_sections
= NULL
;
957 v850ice_ops
.to_sections_end
= NULL
;
958 v850ice_ops
.to_magic
= OPS_MAGIC
;
962 _initialize_v850ice ()
965 add_target (&v850ice_ops
);
967 add_com ("ice", class_obscure
, v850ice_command
,
968 "Send command to ICE");