1 /* gdb-if.c -- sim interface to GDB.
2 
3 Copyright (C) 2011-2013 Free Software Foundation, Inc.
4 Contributed by Red Hat, Inc.
5 
6 This file is part of the GNU simulators.
7 
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20 
21 #include "config.h"
22 #include <stdio.h>
23 #include <assert.h>
24 #include <signal.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <stdlib.h>
28 
29 #include "ansidecl.h"
30 #include "gdb/callback.h"
31 #include "gdb/remote-sim.h"
32 #include "gdb/signals.h"
33 #include "gdb/sim-rl78.h"
34 
35 #include "cpu.h"
36 #include "mem.h"
37 #include "load.h"
38 #include "trace.h"
39 
40 /* Ideally, we'd wrap up all the minisim's data structures in an
41    object and pass that around.  However, neither GDB nor run needs
42    that ability.
43 
44    So we just have one instance, that lives in global variables, and
45    each time we open it, we re-initialize it.  */
46 
47 struct sim_state
48 {
49   const char *message;
50 };
51 
52 static struct sim_state the_minisim = {
53   "This is the sole rl78 minisim instance."
54 };
55 
56 static int open;
57 
58 static unsigned char hw_breakpoints[MEM_SIZE/8];
59 
60 static struct host_callback_struct *host_callbacks;
61 
62 /* Open an instance of the sim.  For this sim, only one instance
63    is permitted.  If sim_open() is called multiple times, the sim
64    will be reset.  */
65 
66 SIM_DESC
sim_open(SIM_OPEN_KIND kind,struct host_callback_struct * callback,struct bfd * abfd,char ** argv)67 sim_open (SIM_OPEN_KIND kind,
68 	  struct host_callback_struct *callback,
69 	  struct bfd *abfd, char **argv)
70 {
71   if (open)
72     fprintf (stderr, "rl78 minisim: re-opened sim\n");
73 
74   /* The 'run' interface doesn't use this function, so we don't care
75      about KIND; it's always SIM_OPEN_DEBUG.  */
76   if (kind != SIM_OPEN_DEBUG)
77     fprintf (stderr, "rl78 minisim: sim_open KIND != SIM_OPEN_DEBUG: %d\n",
78 	     kind);
79 
80   /* We use this for the load command.  Perhaps someday, it'll be used
81      for syscalls too.  */
82   host_callbacks = callback;
83 
84   /* We don't expect any command-line arguments.  */
85 
86   init_cpu ();
87   trace = 0;
88 
89   sim_disasm_init (abfd);
90   open = 1;
91   return &the_minisim;
92 }
93 
94 /* Verify the sim descriptor.  Just print a message if the descriptor
95    doesn't match.  Nothing bad will happen if the descriptor doesn't
96    match because all of the state is global.  But if it doesn't
97    match, that means there's a problem with the caller.  */
98 
99 static void
check_desc(SIM_DESC sd)100 check_desc (SIM_DESC sd)
101 {
102   if (sd != &the_minisim)
103     fprintf (stderr, "rl78 minisim: desc != &the_minisim\n");
104 }
105 
106 /* Close the sim.  */
107 
108 void
sim_close(SIM_DESC sd,int quitting)109 sim_close (SIM_DESC sd, int quitting)
110 {
111   check_desc (sd);
112 
113   /* Not much to do.  At least free up our memory.  */
114   init_mem ();
115 
116   open = 0;
117 }
118 
119 /* Open the program to run; print a message if the program cannot
120    be opened.  */
121 
122 static bfd *
open_objfile(const char * filename)123 open_objfile (const char *filename)
124 {
125   bfd *prog = bfd_openr (filename, 0);
126 
127   if (!prog)
128     {
129       fprintf (stderr, "Can't read %s\n", filename);
130       return 0;
131     }
132 
133   if (!bfd_check_format (prog, bfd_object))
134     {
135       fprintf (stderr, "%s not a rl78 program\n", filename);
136       return 0;
137     }
138 
139   return prog;
140 }
141 
142 /* Load a program.  */
143 
144 SIM_RC
sim_load(SIM_DESC sd,char * prog,struct bfd * abfd,int from_tty)145 sim_load (SIM_DESC sd, char *prog, struct bfd *abfd, int from_tty)
146 {
147   check_desc (sd);
148 
149   if (!abfd)
150     abfd = open_objfile (prog);
151   if (!abfd)
152     return SIM_RC_FAIL;
153 
154   rl78_load (abfd, host_callbacks, "sim");
155 
156   return SIM_RC_OK;
157 }
158 
159 /* Create inferior.  */
160 
161 SIM_RC
sim_create_inferior(SIM_DESC sd,struct bfd * abfd,char ** argv,char ** env)162 sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
163 {
164   check_desc (sd);
165 
166   if (abfd)
167     rl78_load (abfd, 0, "sim");
168 
169   return SIM_RC_OK;
170 }
171 
172 /* Read memory.  */
173 
174 int
sim_read(SIM_DESC sd,SIM_ADDR mem,unsigned char * buf,int length)175 sim_read (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length)
176 {
177   check_desc (sd);
178 
179   if (mem >= MEM_SIZE)
180     return 0;
181   else if (mem + length > MEM_SIZE)
182     length = MEM_SIZE - mem;
183 
184   mem_get_blk (mem, buf, length);
185   return length;
186 }
187 
188 /* Write memory.  */
189 
190 int
sim_write(SIM_DESC sd,SIM_ADDR mem,const unsigned char * buf,int length)191 sim_write (SIM_DESC sd, SIM_ADDR mem, const unsigned char *buf, int length)
192 {
193   check_desc (sd);
194 
195   if (mem >= MEM_SIZE)
196     return 0;
197   else if (mem + length > MEM_SIZE)
198     length = MEM_SIZE - mem;
199 
200   mem_put_blk (mem, buf, length);
201   return length;
202 }
203 
204 /* Read the LENGTH bytes at BUF as an little-endian value.  */
205 
206 static SI
get_le(unsigned char * buf,int length)207 get_le (unsigned char *buf, int length)
208 {
209   SI acc = 0;
210 
211   while (--length >= 0)
212     acc = (acc << 8) + buf[length];
213 
214   return acc;
215 }
216 
217 /* Store VAL as a little-endian value in the LENGTH bytes at BUF.  */
218 
219 static void
put_le(unsigned char * buf,int length,SI val)220 put_le (unsigned char *buf, int length, SI val)
221 {
222   int i;
223 
224   for (i = 0; i < length; i++)
225     {
226       buf[i] = val & 0xff;
227       val >>= 8;
228     }
229 }
230 
231 /* Verify that REGNO is in the proper range.  Return 0 if not and
232    something non-zero if so.  */
233 
234 static int
check_regno(enum sim_rl78_regnum regno)235 check_regno (enum sim_rl78_regnum regno)
236 {
237   return 0 <= regno && regno < sim_rl78_num_regs;
238 }
239 
240 /* Return the size of the register REGNO.  */
241 
242 static size_t
reg_size(enum sim_rl78_regnum regno)243 reg_size (enum sim_rl78_regnum regno)
244 {
245   size_t size;
246 
247   if (regno == sim_rl78_pc_regnum)
248     size = 4;
249   else
250     size = 1;
251 
252   return size;
253 }
254 
255 /* Return the register address associated with the register specified by
256    REGNO.  */
257 
258 static unsigned long
reg_addr(enum sim_rl78_regnum regno)259 reg_addr (enum sim_rl78_regnum regno)
260 {
261   if (sim_rl78_bank0_r0_regnum <= regno
262       && regno <= sim_rl78_bank0_r7_regnum)
263     return 0xffef8 + (regno - sim_rl78_bank0_r0_regnum);
264   else if (sim_rl78_bank1_r0_regnum <= regno
265            && regno <= sim_rl78_bank1_r7_regnum)
266     return 0xffef0 + (regno - sim_rl78_bank1_r0_regnum);
267   else if (sim_rl78_bank2_r0_regnum <= regno
268            && regno <= sim_rl78_bank2_r7_regnum)
269     return 0xffee8 + (regno - sim_rl78_bank2_r0_regnum);
270   else if (sim_rl78_bank3_r0_regnum <= regno
271            && regno <= sim_rl78_bank3_r7_regnum)
272     return 0xffee0 + (regno - sim_rl78_bank3_r0_regnum);
273   else if (regno == sim_rl78_psw_regnum)
274     return 0xffffa;
275   else if (regno == sim_rl78_es_regnum)
276     return 0xffffd;
277   else if (regno == sim_rl78_cs_regnum)
278     return 0xffffc;
279   /* Note: We can't handle PC here because it's not memory mapped.  */
280   else if (regno == sim_rl78_spl_regnum)
281     return 0xffff8;
282   else if (regno == sim_rl78_sph_regnum)
283     return 0xffff9;
284   else if (regno == sim_rl78_pmc_regnum)
285     return 0xffffe;
286   else if (regno == sim_rl78_mem_regnum)
287     return 0xfffff;
288 
289   return 0;
290 }
291 
292 /* Fetch the contents of the register specified by REGNO, placing the
293    contents in BUF.  The length LENGTH must match the sim's internal
294    notion of the register's size.  */
295 
296 int
sim_fetch_register(SIM_DESC sd,int regno,unsigned char * buf,int length)297 sim_fetch_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
298 {
299   size_t size;
300   SI val;
301 
302   check_desc (sd);
303 
304   if (!check_regno (regno))
305     return 0;
306 
307   size = reg_size (regno);
308 
309   if (length != size)
310     return 0;
311 
312   if (regno == sim_rl78_pc_regnum)
313     val = pc;
314   else
315     val = memory[reg_addr (regno)];
316 
317   put_le (buf, length, val);
318 
319   return size;
320 }
321 
322 /* Store the value stored in BUF to the register REGNO.  The length
323    LENGTH must match the sim's internal notion of the register size.  */
324 
325 int
sim_store_register(SIM_DESC sd,int regno,unsigned char * buf,int length)326 sim_store_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
327 {
328   size_t size;
329   SI val;
330 
331   check_desc (sd);
332 
333   if (!check_regno (regno))
334     return -1;
335 
336   size = reg_size (regno);
337 
338   if (length != size)
339     return -1;
340 
341   val = get_le (buf, length);
342 
343   if (regno == sim_rl78_pc_regnum)
344     pc = val;
345   else
346     memory[reg_addr (regno)] = val;
347   return size;
348 }
349 
350 /* Print out message associated with "info target".  */
351 
352 void
sim_info(SIM_DESC sd,int verbose)353 sim_info (SIM_DESC sd, int verbose)
354 {
355   check_desc (sd);
356 
357   printf ("The rl78 minisim doesn't collect any statistics.\n");
358 }
359 
360 static volatile int stop;
361 static enum sim_stop reason;
362 int siggnal;
363 
364 
365 /* Given a signal number used by the rl78 bsp (that is, newlib),
366    return the corresponding signal numbers.  */
367 
368 int
rl78_signal_to_target(int sig)369 rl78_signal_to_target (int sig)
370 {
371   switch (sig)
372     {
373     case 4:
374       return GDB_SIGNAL_ILL;
375 
376     case 5:
377       return GDB_SIGNAL_TRAP;
378 
379     case 10:
380       return GDB_SIGNAL_BUS;
381 
382     case 11:
383       return GDB_SIGNAL_SEGV;
384 
385     case 24:
386       return GDB_SIGNAL_XCPU;
387       break;
388 
389     case 2:
390       return GDB_SIGNAL_INT;
391 
392     case 8:
393       return GDB_SIGNAL_FPE;
394       break;
395 
396     case 6:
397       return GDB_SIGNAL_ABRT;
398     }
399 
400   return 0;
401 }
402 
403 
404 /* Take a step return code RC and set up the variables consulted by
405    sim_stop_reason appropriately.  */
406 
407 void
handle_step(int rc)408 handle_step (int rc)
409 {
410   if (RL78_STEPPED (rc) || RL78_HIT_BREAK (rc))
411     {
412       reason = sim_stopped;
413       siggnal = GDB_SIGNAL_TRAP;
414     }
415   else if (RL78_STOPPED (rc))
416     {
417       reason = sim_stopped;
418       siggnal = rl78_signal_to_target (RL78_STOP_SIG (rc));
419     }
420   else
421     {
422       assert (RL78_EXITED (rc));
423       reason = sim_exited;
424       siggnal = RL78_EXIT_STATUS (rc);
425     }
426 }
427 
428 
429 /* Resume execution after a stop.  */
430 
431 void
sim_resume(SIM_DESC sd,int step,int sig_to_deliver)432 sim_resume (SIM_DESC sd, int step, int sig_to_deliver)
433 {
434   int rc;
435 
436   check_desc (sd);
437 
438   if (sig_to_deliver != 0)
439     {
440       fprintf (stderr,
441 	       "Warning: the rl78 minisim does not implement "
442 	       "signal delivery yet.\n" "Resuming with no signal.\n");
443     }
444 
445       /* We don't clear 'stop' here, because then we would miss
446          interrupts that arrived on the way here.  Instead, we clear
447          the flag in sim_stop_reason, after GDB has disabled the
448          interrupt signal handler.  */
449   for (;;)
450     {
451       if (stop)
452 	{
453 	  stop = 0;
454 	  reason = sim_stopped;
455 	  siggnal = GDB_SIGNAL_INT;
456 	  break;
457 	}
458 
459       if (hw_breakpoints[pc >> 3]
460           && (hw_breakpoints[pc >> 3] & (1 << (pc & 0x7))))
461 	{
462 	  reason = sim_stopped;
463 	  siggnal = GDB_SIGNAL_TRAP;
464 	  break;
465 	}
466       rc = setjmp (decode_jmp_buf);
467       if (rc == 0)
468 	rc = decode_opcode ();
469 
470       if (!RL78_STEPPED (rc) || step)
471 	{
472 	  handle_step (rc);
473 	  break;
474 	}
475     }
476 }
477 
478 /* Stop the sim.  */
479 
480 int
sim_stop(SIM_DESC sd)481 sim_stop (SIM_DESC sd)
482 {
483   stop = 1;
484 
485   return 1;
486 }
487 
488 /* Fetch the stop reason and signal.  */
489 
490 void
sim_stop_reason(SIM_DESC sd,enum sim_stop * reason_p,int * sigrc_p)491 sim_stop_reason (SIM_DESC sd, enum sim_stop *reason_p, int *sigrc_p)
492 {
493   check_desc (sd);
494 
495   *reason_p = reason;
496   *sigrc_p = siggnal;
497 }
498 
499 /* Execute the sim-specific command associated with GDB's "sim ..."
500    command.  */
501 
502 void
sim_do_command(SIM_DESC sd,char * cmd)503 sim_do_command (SIM_DESC sd, char *cmd)
504 {
505   char *args;
506 
507   check_desc (sd);
508 
509   if (cmd == NULL)
510     {
511       cmd = "";
512       args = "";
513     }
514   else
515     {
516       char *p = cmd;
517 
518       /* Skip leading whitespace.  */
519       while (isspace (*p))
520 	p++;
521 
522       /* Find the extent of the command word.  */
523       for (p = cmd; *p; p++)
524 	if (isspace (*p))
525 	  break;
526 
527       /* Null-terminate the command word, and record the start of any
528 	 further arguments.  */
529       if (*p)
530 	{
531 	  *p = '\0';
532 	  args = p + 1;
533 	  while (isspace (*args))
534 	    args++;
535 	}
536       else
537 	args = p;
538     }
539 
540   if (strcmp (cmd, "trace") == 0)
541     {
542       if (strcmp (args, "on") == 0)
543 	trace = 1;
544       else if (strcmp (args, "off") == 0)
545 	trace = 0;
546       else
547 	printf ("The 'sim trace' command expects 'on' or 'off' "
548 		"as an argument.\n");
549     }
550   else if (strcmp (cmd, "verbose") == 0)
551     {
552       if (strcmp (args, "on") == 0)
553 	verbose = 1;
554       else if (strcmp (args, "noisy") == 0)
555 	verbose = 2;
556       else if (strcmp (args, "off") == 0)
557 	verbose = 0;
558       else
559 	printf ("The 'sim verbose' command expects 'on', 'noisy', or 'off'"
560 		" as an argument.\n");
561     }
562   else
563     printf ("The 'sim' command expects either 'trace' or 'verbose'"
564 	    " as a subcommand.\n");
565 }
566 
567 /* Stub for command completion.  */
568 
569 char **
sim_complete_command(SIM_DESC sd,char * text,char * word)570 sim_complete_command (SIM_DESC sd, char *text, char *word)
571 {
572     return NULL;
573 }
574