Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(188)

Side by Side Diff: sim/rl78/gdb-if.c

Issue 11969036: Merge GDB 7.5.1 (Closed) Base URL: http://git.chromium.org/native_client/nacl-gdb.git@master
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sim/rl78/configure ('k') | sim/rx/ChangeLog » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* gdb-if.c -- sim interface to GDB.
2
3 Copyright (C) 2011-2012 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
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
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
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 *
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 **
570 sim_complete_command (SIM_DESC sd, char *text, char *word)
571 {
572 return NULL;
573 }
OLDNEW
« no previous file with comments | « sim/rl78/configure ('k') | sim/rx/ChangeLog » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698