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