* cris/cris-sim.h (enum cris_unknown_syscall_action_type)
[external/binutils.git] / sim / cris / sim-if.c
1 /* Main simulator entry points specific to the CRIS.
2    Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
3    Contributed by Axis Communications.
4
5 This file is part of the GNU simulators.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 /* Based on the fr30 file, mixing in bits from the i960 and pruning of
22    dead code.  */
23
24 #include "libiberty.h"
25 #include "bfd.h"
26
27 #include "sim-main.h"
28 #ifdef HAVE_STDLIB_H
29 #include <stdlib.h>
30 #endif
31 #include "sim-options.h"
32 #include "dis-asm.h"
33
34 /* Apparently the autoconf bits are missing (though HAVE_ENVIRON is used
35    in other dirs; also lacking there).  Patch around it for major systems.  */
36 #if defined (HAVE_ENVIRON) || defined (__GLIBC__)
37 extern char **environ;
38 #define GET_ENVIRON() environ
39 #else
40 char *missing_environ[] = { "SHELL=/bin/sh", "PATH=/bin:/usr/bin", NULL };
41 #define GET_ENVIRON() missing_environ
42 #endif
43
44 /* AUX vector entries.  */
45 #define TARGET_AT_NULL 0
46 #define TARGET_AT_PHDR 3
47 #define TARGET_AT_PHENT 4
48 #define TARGET_AT_PHNUM 5
49 #define TARGET_AT_PAGESZ 6
50 #define TARGET_AT_BASE 7
51 #define TARGET_AT_FLAGS 8
52 #define TARGET_AT_ENTRY 9
53 #define TARGET_AT_UID 11
54 #define TARGET_AT_EUID 12
55 #define TARGET_AT_GID 13
56 #define TARGET_AT_EGID 14
57 #define TARGET_AT_HWCAP 16
58 #define TARGET_AT_CLKTCK 17
59
60 /* Used with get_progbounds to find out how much memory is needed for the
61    program.  We don't want to allocate more, since that could mask
62    invalid memory accesses program bugs.  */
63 struct progbounds {
64   USI startmem;
65   USI endmem;
66 };
67
68 static void free_state (SIM_DESC);
69 static void get_progbounds (bfd *, asection *, void *);
70 static SIM_RC cris_option_handler (SIM_DESC, sim_cpu *, int, char *, int);
71
72 /* Since we don't build the cgen-opcode table, we use the old
73    disassembler.  */
74 static CGEN_DISASSEMBLER cris_disassemble_insn;
75
76 /* By default, we set up stack and environment variables like the Linux
77    kernel.  */
78 static char cris_bare_iron = 0;
79
80 /* Whether 0x9000000xx have simulator-specific meanings.  */
81 char cris_have_900000xxif = 0;
82
83 /* What to do when we face a more or less unknown syscall.  */
84 enum cris_unknown_syscall_action_type cris_unknown_syscall_action
85   = CRIS_USYSC_MSG_STOP;
86
87 /* Records simulator descriptor so utilities like cris_dump_regs can be
88    called from gdb.  */
89 SIM_DESC current_state;
90
91 /* CRIS-specific options.  */
92 typedef enum {
93   OPTION_CRIS_STATS = OPTION_START,
94   OPTION_CRIS_TRACE,
95   OPTION_CRIS_NAKED,
96   OPTION_CRIS_900000XXIF,
97   OPTION_CRIS_UNKNOWN_SYSCALL
98 } CRIS_OPTIONS;
99
100 static const OPTION cris_options[] =
101 {
102   { {"cris-cycles", required_argument, NULL, OPTION_CRIS_STATS},
103       '\0', "basic|unaligned|schedulable|all",
104     "Dump execution statistics",
105       cris_option_handler, NULL },
106   { {"cris-trace", required_argument, NULL, OPTION_CRIS_TRACE},
107       '\0', "basic",
108     "Emit trace information while running",
109       cris_option_handler, NULL },
110   { {"cris-naked", no_argument, NULL, OPTION_CRIS_NAKED},
111      '\0', NULL, "Don't set up stack and environment",
112      cris_option_handler, NULL },
113   { {"cris-900000xx", no_argument, NULL, OPTION_CRIS_900000XXIF},
114      '\0', NULL, "Define addresses at 0x900000xx with simulator semantics",
115      cris_option_handler, NULL },
116   { {"cris-unknown-syscall", required_argument, NULL,
117      OPTION_CRIS_UNKNOWN_SYSCALL},
118      '\0', "stop|enosys|enosys-quiet", "Action at an unknown system call",
119      cris_option_handler, NULL },
120   { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
121 };
122 \f
123 /* Add the CRIS-specific option list to the simulator.  */
124
125 SIM_RC
126 cris_option_install (SIM_DESC sd)
127 {
128   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
129   if (sim_add_option_table (sd, NULL, cris_options) != SIM_RC_OK)
130     return SIM_RC_FAIL;
131   return SIM_RC_OK;
132 }
133
134 /* Handle CRIS-specific options.  */
135
136 static SIM_RC
137 cris_option_handler (SIM_DESC sd, sim_cpu *cpu ATTRIBUTE_UNUSED, int opt,
138                      char *arg, int is_command ATTRIBUTE_UNUSED)
139 {
140   /* The options are CRIS-specific, but cpu-specific option-handling is
141      broken; required to being with "--cpu0-".  We store the flags in an
142      unused field in the global state structure and move the flags over
143      to the module-specific CPU data when we store things in the
144      cpu-specific structure.  */
145   char *tracefp = STATE_TRACE_FLAGS (sd);
146
147   switch ((CRIS_OPTIONS) opt)
148     {
149       case OPTION_CRIS_STATS:
150         if (strcmp (arg, "basic") == 0)
151           *tracefp = FLAG_CRIS_MISC_PROFILE_SIMPLE;
152         else if (strcmp (arg, "unaligned") == 0)
153           *tracefp
154             = (FLAG_CRIS_MISC_PROFILE_UNALIGNED
155                | FLAG_CRIS_MISC_PROFILE_SIMPLE);
156         else if (strcmp (arg, "schedulable") == 0)
157           *tracefp
158             = (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE
159                | FLAG_CRIS_MISC_PROFILE_SIMPLE);
160         else if (strcmp (arg, "all") == 0)
161           *tracefp = FLAG_CRIS_MISC_PROFILE_ALL;
162         else
163           {
164             /* Beware; the framework does not handle the error case;
165                we have to do it ourselves.  */
166             sim_io_eprintf (sd, "Unknown option `--cris-cycles=%s'\n", arg);
167             return SIM_RC_FAIL;
168           }
169         break;
170
171       case OPTION_CRIS_TRACE:
172         if (strcmp (arg, "basic") == 0)
173           *tracefp |= FLAG_CRIS_MISC_PROFILE_XSIM_TRACE;
174         else
175           {
176             sim_io_eprintf (sd, "Unknown option `--cris-trace=%s'\n", arg);
177             return SIM_RC_FAIL;
178           }
179         break;
180
181       case OPTION_CRIS_NAKED:
182         cris_bare_iron = 1;
183         break;
184
185       case OPTION_CRIS_900000XXIF:
186         cris_have_900000xxif = 1;
187         break;
188
189       case OPTION_CRIS_UNKNOWN_SYSCALL:
190         if (strcmp (arg, "enosys") == 0)
191           cris_unknown_syscall_action = CRIS_USYSC_MSG_ENOSYS;
192         else if (strcmp (arg, "enosys-quiet") == 0)
193           cris_unknown_syscall_action = CRIS_USYSC_QUIET_ENOSYS;
194         else if (strcmp (arg, "stop") == 0)
195           cris_unknown_syscall_action = CRIS_USYSC_MSG_STOP;
196         else
197           {
198             sim_io_eprintf (sd, "Unknown option `--cris-unknown-syscall=%s'\n",
199                             arg);
200             return SIM_RC_FAIL;
201           }
202         break;
203
204       default:
205         /* We'll actually never get here; the caller handles the error
206            case.  */
207         sim_io_eprintf (sd, "Unknown option `%s'\n", arg);
208         return SIM_RC_FAIL;
209     }
210
211   /* Imply --profile-model=on.  */
212   return sim_profile_set_option (sd, "-model", PROFILE_MODEL_IDX, "on");
213 }
214
215 /* Cover function of sim_state_free to free the cpu buffers as well.  */
216
217 static void
218 free_state (SIM_DESC sd)
219 {
220   if (STATE_MODULES (sd) != NULL)
221     sim_module_uninstall (sd);
222   sim_cpu_free_all (sd);
223   sim_state_free (sd);
224 }
225
226 /* BFD section iterator to find the highest allocated section address
227    (plus one).  If we could, we should use the program header table
228    instead, but we can't get to that using bfd.  */
229
230 void
231 get_progbounds (bfd *abfd ATTRIBUTE_UNUSED, asection *s, void *vp)
232 {
233   struct progbounds *pbp = (struct progbounds *) vp;
234
235   if ((bfd_get_section_flags (abfd, s) & SEC_ALLOC))
236     {
237       bfd_size_type sec_size = bfd_get_section_size (s);
238       bfd_size_type sec_start = bfd_get_section_vma (abfd, s);
239       bfd_size_type sec_end = sec_start + sec_size;
240
241       if (sec_end > pbp->endmem)
242         pbp->endmem = sec_end;
243
244       if (sec_start < pbp->startmem)
245         pbp->startmem = sec_start;
246     }
247 }
248
249 /* Create an instance of the simulator.  */
250
251 SIM_DESC
252 sim_open (SIM_OPEN_KIND kind, host_callback *callback, struct bfd *abfd,
253           char **argv)
254 {
255   char c;
256   int i;
257   USI startmem = 0;
258   USI endmem = CRIS_DEFAULT_MEM_SIZE;
259   USI endbrk = endmem;
260   USI stack_low = 0;
261   SIM_DESC sd = sim_state_alloc (kind, callback);
262
263   /* Can't initialize to "" below.  It's either a GCC bug in old
264      releases (up to and including 2.95.3 (.4 in debian) or a bug in the
265      standard ;-) that the rest of the elements won't be initialized.  */
266   bfd_byte sp_init[4] = {0, 0, 0, 0};
267
268   /* The cpu data is kept in a separately allocated chunk of memory.  */
269   if (sim_cpu_alloc_all (sd, 1, cgen_cpu_max_extra_bytes ()) != SIM_RC_OK)
270     {
271       free_state (sd);
272       return 0;
273     }
274
275   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
276     {
277       free_state (sd);
278       return 0;
279     }
280
281   /* getopt will print the error message so we just have to exit if this fails.
282      FIXME: Hmmm...  in the case of gdb we need getopt to call
283      print_filtered.  */
284   if (sim_parse_args (sd, argv) != SIM_RC_OK)
285     {
286       free_state (sd);
287       return 0;
288     }
289
290   /* If we have a binary program, endianness-setting would not be taken
291      from elsewhere unfortunately, so set it here.  At the time of this
292      writing, it isn't used until sim_config, but that might change so
293      set it here before memory is defined or touched.  */
294   current_target_byte_order = LITTLE_ENDIAN;
295
296   /* check for/establish the reference program image */
297   if (sim_analyze_program (sd,
298                            (STATE_PROG_ARGV (sd) != NULL
299                             ? *STATE_PROG_ARGV (sd)
300                             : NULL),
301                            abfd) != SIM_RC_OK)
302     {
303       free_state (sd);
304       return 0;
305     }
306
307   /* For CRIS simulator-specific use, we need to find out the bounds of
308      the program as well, which is not done by sim_analyze_program
309      above.  */
310   if (STATE_PROG_BFD (sd))
311     {
312       struct progbounds pb;
313
314       /* The sections should now be accessible using bfd functions.  */
315       pb.startmem = 0x7fffffff;
316       pb.endmem = 0;
317       bfd_map_over_sections (STATE_PROG_BFD (sd), get_progbounds, &pb);
318
319       /* We align the area that the program uses to page boundaries.  */
320       startmem = pb.startmem & ~8191;
321       endbrk = pb.endmem;
322       endmem = (endbrk + 8191) & ~8191;
323     }
324
325   /* Find out how much room is needed for the environment and argv, create
326      that memory and fill it.  Only do this when there's a program
327      specified.  */
328   if (STATE_PROG_BFD (sd) && !cris_bare_iron)
329     {
330       char *name = bfd_get_filename (STATE_PROG_BFD (sd));
331       char **my_environ = GET_ENVIRON ();
332       /* We use these maps to give the same behavior as the old xsim
333          simulator.  */
334       USI envtop = 0x40000000;
335       USI stacktop = 0x3e000000;
336       USI envstart;
337       int envc;
338       int len = strlen (name) + 1;
339       USI epp, epp0;
340       USI stacklen;
341       int i;
342       char **prog_argv = STATE_PROG_ARGV (sd);
343       int my_argc = 0;
344       /* All CPU:s have the same memory map, apparently.  */
345       SIM_CPU *cpu = STATE_CPU (sd, 0);
346       USI csp;
347       bfd_byte buf[4];
348
349       /* Count in the environment as well. */
350       for (envc = 0; my_environ[envc] != NULL; envc++)
351         len += strlen (my_environ[envc]) + 1;
352
353       for (i = 0; prog_argv[i] != NULL; my_argc++, i++)
354         len += strlen (prog_argv[i]) + 1;
355
356       envstart = (envtop - len) & ~8191;
357
358       /* Create read-only block for the environment strings.  */
359       sim_core_attach (sd, NULL, 0, access_read, 0,
360                        envstart, (len + 8191) & ~8191,
361                        0, NULL, NULL);
362
363       /* This shouldn't happen.  */
364       if (envstart < stacktop)
365         stacktop = envstart - 64 * 8192;
366
367       csp = stacktop;
368
369       /* Note that the linux kernel does not correctly compute the storage
370          needs for the static-exe AUX vector.  */
371       csp -= 4 * 4 * 2;
372
373       csp -= (envc + 1) * 4;
374       csp -= (my_argc + 1) * 4;
375       csp -= 4;
376
377       /* Write the target representation of the start-up-value for the
378          stack-pointer suitable for register initialization below.  */
379       bfd_putl32 (csp, sp_init);
380
381       /* If we make this 1M higher; say 8192*1024, we have to take
382          special precautions for pthreads, because pthreads assumes that
383          the memory that low isn't mmapped, and that it can mmap it
384          without fallback in case of failure (and we fail ungracefully
385          long before *that*: the memory isn't accounted for in our mmap
386          list).  */
387       stack_low = (csp - (7168*1024)) & ~8191;
388
389       stacklen = stacktop - stack_low;
390
391       /* Tee hee, we have an executable stack.  Well, it's necessary to
392          test GCC trampolines...  */
393       sim_core_attach (sd, NULL, 0, access_read_write_exec, 0,
394                        stack_low, stacklen,
395                        0, NULL, NULL);
396
397       epp = epp0 = envstart;
398
399       /* Can't use sim_core_write_unaligned_4 without everything
400          initialized when tracing, and then these writes would get into
401          the trace.  */
402 #define write_dword(addr, data)                                         \
403  do                                                                     \
404    {                                                                    \
405      USI data_ = data;                                                  \
406      USI addr_ = addr;                                                  \
407      bfd_putl32 (data_, buf);                                           \
408      if (sim_core_write_buffer (sd, cpu, 0, buf, addr_, 4) != 4)        \
409         goto abandon_chip;                                              \
410    }                                                                    \
411  while (0)
412
413       write_dword (csp, my_argc);
414       csp += 4;
415
416       for (i = 0; i < my_argc; i++, csp += 4)
417         {
418           size_t strln = strlen (prog_argv[i]) + 1;
419
420           if (sim_core_write_buffer (sd, cpu, 0, prog_argv[i], epp, strln)
421               != strln)
422           goto abandon_chip;
423
424           write_dword (csp, envstart + epp - epp0);
425           epp += strln;
426         }
427
428       write_dword (csp, 0);
429       csp += 4;
430
431       for (i = 0; i < envc; i++, csp += 4)
432         {
433           unsigned int strln = strlen (my_environ[i]) + 1;
434
435           if (sim_core_write_buffer (sd, cpu, 0, my_environ[i], epp, strln)
436               != strln)
437             goto abandon_chip;
438
439           write_dword (csp, envstart + epp - epp0);
440           epp += strln;
441         }
442
443       write_dword (csp, 0);
444       csp += 4;
445
446 #define NEW_AUX_ENT(nr, id, val)                        \
447  do                                                     \
448    {                                                    \
449      write_dword (csp + (nr) * 4 * 2, (id));            \
450      write_dword (csp + (nr) * 4 * 2 + 4, (val));       \
451    }                                                    \
452  while (0)
453
454       /* Note that there are some extra AUX entries for a dynlinked
455          program loaded image.  */
456
457       /* AUX entries always present. */
458       NEW_AUX_ENT (0, TARGET_AT_HWCAP, 0);
459       NEW_AUX_ENT (1, TARGET_AT_PAGESZ, 8192);
460       NEW_AUX_ENT (2, TARGET_AT_CLKTCK, 100);
461
462       csp += 4 * 2 * 3;
463       NEW_AUX_ENT (0, TARGET_AT_NULL, 0);
464 #undef NEW_AUX_ENT
465
466       /* Register R10 should hold 0 at static start (no initfunc), but
467          that's the default, so don't bother.  */
468     }
469
470   /* Allocate core managed memory if none specified by user.  */
471   if (sim_core_read_buffer (sd, NULL, read_map, &c, startmem, 1) == 0)
472     sim_do_commandf (sd, "memory region 0x%lx,0x%lx", startmem,
473                      endmem - startmem);
474
475   /* Allocate simulator I/O managed memory if none specified by user.  */
476   if (cris_have_900000xxif)
477     {
478       if (sim_core_read_buffer (sd, NULL, read_map, &c, 0x90000000, 1) == 0)
479         sim_core_attach (sd, NULL, 0, access_write, 0, 0x90000000, 0x100,
480                          0, &cris_devices, NULL);
481       else
482         {
483           (*callback->
484            printf_filtered) (callback,
485                              "Seeing --cris-900000xx with memory defined there\n");
486           goto abandon_chip;
487         }
488     }
489
490   /* Establish any remaining configuration options.  */
491   if (sim_config (sd) != SIM_RC_OK)
492     {
493     abandon_chip:
494       free_state (sd);
495       return 0;
496     }
497
498   if (sim_post_argv_init (sd) != SIM_RC_OK)
499     {
500       free_state (sd);
501       return 0;
502     }
503
504   /* Open a copy of the cpu descriptor table.  */
505   {
506     CGEN_CPU_DESC cd = cris_cgen_cpu_open_1 (STATE_ARCHITECTURE (sd)->printable_name,
507                                              CGEN_ENDIAN_LITTLE);
508     for (i = 0; i < MAX_NR_PROCESSORS; ++i)
509       {
510         SIM_CPU *cpu = STATE_CPU (sd, i);
511         CPU_CPU_DESC (cpu) = cd;
512         CPU_DISASSEMBLER (cpu) = cris_disassemble_insn;
513
514         /* See cris_option_handler for the reason why this is needed.  */
515         CPU_CRIS_MISC_PROFILE (cpu)->flags = STATE_TRACE_FLAGS (sd)[0];
516
517         /* Set SP to the stack we allocated above.  */
518         (* CPU_REG_STORE (cpu)) (cpu, H_GR_SP, (char *) sp_init, 4);
519
520         /* Set the simulator environment data.  */
521         cpu->highest_mmapped_page = NULL;
522         cpu->endmem = endmem;
523         cpu->endbrk = endbrk;
524         cpu->stack_low = stack_low;
525         cpu->syscalls = 0;
526         cpu->m1threads = 0;
527         cpu->threadno = 0;
528         cpu->max_threadid = 0;
529         cpu->thread_data = NULL;
530         memset (cpu->sighandler, 0, sizeof (cpu->sighandler));
531         cpu->make_thread_cpu_data = NULL;
532         cpu->thread_cpu_data_size = 0;
533 #if WITH_HW
534         cpu->deliver_interrupt = NULL;
535 #endif
536       }
537 #if WITH_HW
538     /* Always be cycle-accurate and call before/after functions if
539        with-hardware.  */
540     sim_profile_set_option (sd, "-model", PROFILE_MODEL_IDX, "on");
541 #endif
542   }
543
544   /* Initialize various cgen things not done by common framework.
545      Must be done after cris_cgen_cpu_open.  */
546   cgen_init (sd);
547
548   /* Store in a global so things like cris_dump_regs can be invoked
549      from the gdb command line.  */
550   current_state = sd;
551
552   cris_set_callbacks (callback);
553
554   return sd;
555 }
556
557 void
558 sim_close (SIM_DESC sd, int quitting ATTRIBUTE_UNUSED)
559 {
560   cris_cgen_cpu_close (CPU_CPU_DESC (STATE_CPU (sd, 0)));
561   sim_module_uninstall (sd);
562 }
563 \f
564 SIM_RC
565 sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
566                      char **argv ATTRIBUTE_UNUSED,
567                      char **envp ATTRIBUTE_UNUSED)
568 {
569   SIM_CPU *current_cpu = STATE_CPU (sd, 0);
570   SIM_ADDR addr;
571
572   if (abfd != NULL)
573     addr = bfd_get_start_address (abfd);
574   else
575     addr = 0;
576   sim_pc_set (current_cpu, addr);
577
578   /* Other simulators have #if 0:d code that says
579       STATE_ARGV (sd) = sim_copy_argv (argv);
580       STATE_ENVP (sd) = sim_copy_argv (envp);
581      Enabling that gives you not-found link-errors for sim_copy_argv.
582      FIXME: Do archaeology to find out more.  */
583
584   return SIM_RC_OK;
585 }
586
587 void
588 sim_do_command (SIM_DESC sd, char *cmd)
589 {
590   if (sim_args_command (sd, cmd) != SIM_RC_OK)
591     sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
592 }
593 \f
594 /* Disassemble an instruction.  */
595
596 static void
597 cris_disassemble_insn (SIM_CPU *cpu,
598                        const CGEN_INSN *insn ATTRIBUTE_UNUSED,
599                        const ARGBUF *abuf ATTRIBUTE_UNUSED,
600                        IADDR pc, char *buf)
601 {
602   disassembler_ftype pinsn;
603   struct disassemble_info disasm_info;
604   SFILE sfile;
605   SIM_DESC sd = CPU_STATE (cpu);
606
607   sfile.buffer = sfile.current = buf;
608   INIT_DISASSEMBLE_INFO (disasm_info, (FILE *) &sfile,
609                          (fprintf_ftype) sim_disasm_sprintf);
610   disasm_info.endian =
611     (bfd_big_endian (STATE_PROG_BFD (sd)) ? BFD_ENDIAN_BIG
612      : bfd_little_endian (STATE_PROG_BFD (sd)) ? BFD_ENDIAN_LITTLE
613      : BFD_ENDIAN_UNKNOWN);
614   /* We live with the cast until the prototype is fixed, or else we get a
615      warning because the functions differ in the signedness of one parameter.  */
616   disasm_info.read_memory_func =
617     sim_disasm_read_memory;
618   disasm_info.memory_error_func = sim_disasm_perror_memory;
619   disasm_info.application_data = (PTR) cpu;
620   pinsn = cris_get_disassembler (STATE_PROG_BFD (sd));
621   (*pinsn) (pc, &disasm_info);
622 }