]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/rl78/gdb-if.c
sim: Fix -Werror=shadow=local by changing mem to addr in sim_{read,write}
[thirdparty/binutils-gdb.git] / sim / rl78 / gdb-if.c
CommitLineData
9058f767
KB
1/* gdb-if.c -- sim interface to GDB.
2
1d506c26 3Copyright (C) 2011-2024 Free Software Foundation, Inc.
9058f767
KB
4Contributed by Red Hat, Inc.
5
6This file is part of the GNU simulators.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
6df01ab8
MF
21/* This must come before any other includes. */
22#include "defs.h"
23
9058f767
KB
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"
75070a4e 32#include "libiberty.h"
df68e12b
MF
33#include "sim/callback.h"
34#include "sim/sim.h"
9058f767 35#include "gdb/signals.h"
d026e67e 36#include "sim/sim-rl78.h"
9058f767
KB
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
50struct sim_state
51{
52 const char *message;
53};
54
55static struct sim_state the_minisim = {
56 "This is the sole rl78 minisim instance."
57};
58
9a28444f 59static int is_open;
9058f767 60
9058f767
KB
61static 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
67SIM_DESC
68sim_open (SIM_OPEN_KIND kind,
69 struct host_callback_struct *callback,
2e3d4f4d 70 struct bfd *abfd, char * const *argv)
9058f767 71{
9a28444f 72 if (is_open)
9058f767
KB
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);
9a28444f 91 is_open = 1;
0952813b
DD
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
9058f767
KB
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
131static void
132check_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
140void
141sim_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
9a28444f 148 is_open = 0;
9058f767
KB
149}
150
151/* Open the program to run; print a message if the program cannot
152 be opened. */
153
154static bfd *
155open_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
176SIM_RC
b2b255bd 177sim_load (SIM_DESC sd, const char *prog, struct bfd *abfd, int from_tty)
9058f767
KB
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
193SIM_RC
2e3d4f4d
MF
194sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
195 char * const *argv, char * const *env)
9058f767
KB
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
63fd5b5d 207uint64_t
cbbcd7fd 208sim_read (SIM_DESC sd, uint64_t addr, void *buf, uint64_t length)
9058f767
KB
209{
210 check_desc (sd);
211
cbbcd7fd 212 if (addr >= MEM_SIZE)
9058f767 213 return 0;
cbbcd7fd
MW
214 else if (addr + length > MEM_SIZE)
215 length = MEM_SIZE - addr;
9058f767 216
cbbcd7fd 217 mem_get_blk (addr, buf, length);
9058f767
KB
218 return length;
219}
220
221/* Write memory. */
222
63fd5b5d 223uint64_t
cbbcd7fd 224sim_write (SIM_DESC sd, uint64_t addr, const void *buf, uint64_t length)
9058f767
KB
225{
226 check_desc (sd);
227
cbbcd7fd 228 if (addr >= MEM_SIZE)
9058f767 229 return 0;
cbbcd7fd
MW
230 else if (addr + length > MEM_SIZE)
231 length = MEM_SIZE - addr;
9058f767 232
cbbcd7fd 233 mem_put_blk (addr, buf, length);
9058f767
KB
234 return length;
235}
236
237/* Read the LENGTH bytes at BUF as an little-endian value. */
238
239static SI
ed60d3ed 240get_le (const unsigned char *buf, int length)
9058f767
KB
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
252static void
253put_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
267static int
268check_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
275static size_t
276reg_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
291static unsigned long
292reg_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
329int
ee1cffd3 330sim_fetch_register (SIM_DESC sd, int regno, void *buf, int length)
9058f767
KB
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
358int
ee1cffd3 359sim_store_register (SIM_DESC sd, int regno, const void *buf, int length)
9058f767
KB
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)
317cc67d
KB
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 }
9058f767
KB
386 else
387 memory[reg_addr (regno)] = val;
388 return size;
389}
390
391/* Print out message associated with "info target". */
392
393void
cc67f780 394sim_info (SIM_DESC sd, bool verbose)
9058f767
KB
395{
396 check_desc (sd);
397
398 printf ("The rl78 minisim doesn't collect any statistics.\n");
399}
400
401static volatile int stop;
402static enum sim_stop reason;
403int siggnal;
404
405
406/* Given a signal number used by the rl78 bsp (that is, newlib),
407 return the corresponding signal numbers. */
408
5318ba65 409static int
9058f767
KB
410rl78_signal_to_target (int sig)
411{
412 switch (sig)
413 {
414 case 4:
a493e3e2 415 return GDB_SIGNAL_ILL;
9058f767
KB
416
417 case 5:
a493e3e2 418 return GDB_SIGNAL_TRAP;
9058f767
KB
419
420 case 10:
a493e3e2 421 return GDB_SIGNAL_BUS;
9058f767
KB
422
423 case 11:
a493e3e2 424 return GDB_SIGNAL_SEGV;
9058f767
KB
425
426 case 24:
a493e3e2 427 return GDB_SIGNAL_XCPU;
9058f767
KB
428 break;
429
430 case 2:
a493e3e2 431 return GDB_SIGNAL_INT;
9058f767
KB
432
433 case 8:
a493e3e2 434 return GDB_SIGNAL_FPE;
9058f767
KB
435 break;
436
437 case 6:
a493e3e2 438 return GDB_SIGNAL_ABRT;
9058f767
KB
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
5318ba65 448static void
9058f767
KB
449handle_step (int rc)
450{
451 if (RL78_STEPPED (rc) || RL78_HIT_BREAK (rc))
452 {
453 reason = sim_stopped;
a493e3e2 454 siggnal = GDB_SIGNAL_TRAP;
9058f767
KB
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
472void
473sim_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;
a493e3e2 496 siggnal = GDB_SIGNAL_INT;
9058f767
KB
497 break;
498 }
499
9058f767
KB
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
514int
515sim_stop (SIM_DESC sd)
516{
517 stop = 1;
518
519 return 1;
520}
521
522/* Fetch the stop reason and signal. */
523
524void
525sim_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
536void
60d847df 537sim_do_command (SIM_DESC sd, const char *cmd)
9058f767 538{
75070a4e
MF
539 const char *arg;
540 char **argv = buildargv (cmd);
9058f767
KB
541
542 check_desc (sd);
543
75070a4e
MF
544 cmd = arg = "";
545 if (argv != NULL)
9058f767 546 {
75070a4e
MF
547 if (argv[0] != NULL)
548 cmd = argv[0];
549 if (argv[1] != NULL)
550 arg = argv[1];
9058f767
KB
551 }
552
553 if (strcmp (cmd, "trace") == 0)
554 {
75070a4e 555 if (strcmp (arg, "on") == 0)
9058f767 556 trace = 1;
75070a4e 557 else if (strcmp (arg, "off") == 0)
9058f767
KB
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 {
75070a4e 565 if (strcmp (arg, "on") == 0)
9058f767 566 verbose = 1;
75070a4e 567 else if (strcmp (arg, "noisy") == 0)
9058f767 568 verbose = 2;
75070a4e 569 else if (strcmp (arg, "off") == 0)
9058f767
KB
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");
60d847df 578
75070a4e 579 freeargv (argv);
9058f767
KB
580}
581
582/* Stub for command completion. */
583
584char **
3cb2ab1a 585sim_complete_command (SIM_DESC sd, const char *text, const char *word)
9058f767
KB
586{
587 return NULL;
588}
7a9bd3b4
MF
589
590char *
591sim_memory_map (SIM_DESC sd)
592{
593 return NULL;
594}