]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/cris/sim-if.c
sim/testsuite/cris: As applicable, require simoption --cris-900000xx
[thirdparty/binutils-gdb.git] / sim / cris / sim-if.c
CommitLineData
f6bcefef 1/* Main simulator entry points specific to the CRIS.
4a94e368 2 Copyright (C) 2004-2022 Free Software Foundation, Inc.
f6bcefef
HPN
3 Contributed by Axis Communications.
4
5This file is part of the GNU simulators.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
4744ac1b
JB
9the Free Software Foundation; either version 3 of the License, or
10(at your option) any later version.
f6bcefef
HPN
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
4744ac1b
JB
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>. */
f6bcefef
HPN
19
20/* Based on the fr30 file, mixing in bits from the i960 and pruning of
21 dead code. */
22
6df01ab8
MF
23/* This must come before any other includes. */
24#include "defs.h"
25
8cfc9a18
MF
26#include <stdlib.h>
27#include <errno.h>
28#include <unistd.h>
29
f6bcefef
HPN
30#include "libiberty.h"
31#include "bfd.h"
80e5c09e 32#include "elf-bfd.h"
f6bcefef 33
8cfc9a18 34#include "sim/callback.h"
f6bcefef 35#include "sim-main.h"
f6bcefef 36#include "sim-options.h"
072d63a8 37#include "sim-hw.h"
f6bcefef 38#include "dis-asm.h"
c5a2e012 39#include "environ.h"
f6bcefef 40
f6bcefef
HPN
41/* Used with get_progbounds to find out how much memory is needed for the
42 program. We don't want to allocate more, since that could mask
43 invalid memory accesses program bugs. */
44struct progbounds {
45 USI startmem;
46 USI endmem;
80e5c09e
HPN
47 USI end_loadmem;
48 USI start_nonloadmem;
f6bcefef
HPN
49};
50
51static void free_state (SIM_DESC);
80e5c09e 52static void get_progbounds_iterator (bfd *, asection *, void *);
f6bcefef
HPN
53static SIM_RC cris_option_handler (SIM_DESC, sim_cpu *, int, char *, int);
54
55/* Since we don't build the cgen-opcode table, we use the old
56 disassembler. */
57static CGEN_DISASSEMBLER cris_disassemble_insn;
58
59/* By default, we set up stack and environment variables like the Linux
60 kernel. */
61static char cris_bare_iron = 0;
62
63/* Whether 0x9000000xx have simulator-specific meanings. */
aad3b3cb 64char cris_have_900000xxif = 0;
f6bcefef 65
c10b3605
HPN
66/* Used to optionally override the default start address of the
67 simulation. */
68static USI cris_start_address = 0xffffffffu;
69
70/* Used to optionally add offsets to the loaded image and its start
71 address. (Not used for the interpreter of dynamically loaded
72 programs or the DSO:s.) */
73static int cris_program_offset = 0;
74
466b1d33
HPN
75/* What to do when we face a more or less unknown syscall. */
76enum cris_unknown_syscall_action_type cris_unknown_syscall_action
77 = CRIS_USYSC_MSG_STOP;
78
f6bcefef
HPN
79/* CRIS-specific options. */
80typedef enum {
81 OPTION_CRIS_STATS = OPTION_START,
82 OPTION_CRIS_TRACE,
83 OPTION_CRIS_NAKED,
c10b3605
HPN
84 OPTION_CRIS_PROGRAM_OFFSET,
85 OPTION_CRIS_STARTADDR,
f6bcefef 86 OPTION_CRIS_900000XXIF,
466b1d33 87 OPTION_CRIS_UNKNOWN_SYSCALL
f6bcefef
HPN
88} CRIS_OPTIONS;
89
90static const OPTION cris_options[] =
91{
92 { {"cris-cycles", required_argument, NULL, OPTION_CRIS_STATS},
93 '\0', "basic|unaligned|schedulable|all",
94 "Dump execution statistics",
95 cris_option_handler, NULL },
96 { {"cris-trace", required_argument, NULL, OPTION_CRIS_TRACE},
97 '\0', "basic",
98 "Emit trace information while running",
99 cris_option_handler, NULL },
100 { {"cris-naked", no_argument, NULL, OPTION_CRIS_NAKED},
101 '\0', NULL, "Don't set up stack and environment",
102 cris_option_handler, NULL },
103 { {"cris-900000xx", no_argument, NULL, OPTION_CRIS_900000XXIF},
104 '\0', NULL, "Define addresses at 0x900000xx with simulator semantics",
105 cris_option_handler, NULL },
466b1d33
HPN
106 { {"cris-unknown-syscall", required_argument, NULL,
107 OPTION_CRIS_UNKNOWN_SYSCALL},
108 '\0', "stop|enosys|enosys-quiet", "Action at an unknown system call",
109 cris_option_handler, NULL },
c10b3605
HPN
110 { {"cris-program-offset", required_argument, NULL,
111 OPTION_CRIS_PROGRAM_OFFSET},
112 '\0', "OFFSET",
113 "Offset image addresses and default start address of a program",
114 cris_option_handler },
115 { {"cris-start-address", required_argument, NULL, OPTION_CRIS_STARTADDR},
116 '\0', "ADDRESS", "Set start address",
117 cris_option_handler },
f6bcefef
HPN
118 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
119};
120\f
f6bcefef
HPN
121/* Handle CRIS-specific options. */
122
123static SIM_RC
124cris_option_handler (SIM_DESC sd, sim_cpu *cpu ATTRIBUTE_UNUSED, int opt,
125 char *arg, int is_command ATTRIBUTE_UNUSED)
126{
127 /* The options are CRIS-specific, but cpu-specific option-handling is
128 broken; required to being with "--cpu0-". We store the flags in an
129 unused field in the global state structure and move the flags over
130 to the module-specific CPU data when we store things in the
131 cpu-specific structure. */
132 char *tracefp = STATE_TRACE_FLAGS (sd);
c10b3605 133 char *chp = arg;
f6bcefef
HPN
134
135 switch ((CRIS_OPTIONS) opt)
136 {
137 case OPTION_CRIS_STATS:
138 if (strcmp (arg, "basic") == 0)
139 *tracefp = FLAG_CRIS_MISC_PROFILE_SIMPLE;
140 else if (strcmp (arg, "unaligned") == 0)
141 *tracefp
142 = (FLAG_CRIS_MISC_PROFILE_UNALIGNED
143 | FLAG_CRIS_MISC_PROFILE_SIMPLE);
144 else if (strcmp (arg, "schedulable") == 0)
145 *tracefp
146 = (FLAG_CRIS_MISC_PROFILE_SCHEDULABLE
147 | FLAG_CRIS_MISC_PROFILE_SIMPLE);
148 else if (strcmp (arg, "all") == 0)
149 *tracefp = FLAG_CRIS_MISC_PROFILE_ALL;
150 else
151 {
466b1d33
HPN
152 /* Beware; the framework does not handle the error case;
153 we have to do it ourselves. */
154 sim_io_eprintf (sd, "Unknown option `--cris-cycles=%s'\n", arg);
f6bcefef
HPN
155 return SIM_RC_FAIL;
156 }
157 break;
158
159 case OPTION_CRIS_TRACE:
160 if (strcmp (arg, "basic") == 0)
161 *tracefp |= FLAG_CRIS_MISC_PROFILE_XSIM_TRACE;
162 else
163 {
164 sim_io_eprintf (sd, "Unknown option `--cris-trace=%s'\n", arg);
165 return SIM_RC_FAIL;
166 }
167 break;
168
169 case OPTION_CRIS_NAKED:
170 cris_bare_iron = 1;
171 break;
172
173 case OPTION_CRIS_900000XXIF:
174 cris_have_900000xxif = 1;
175 break;
176
c10b3605
HPN
177 case OPTION_CRIS_STARTADDR:
178 errno = 0;
179 cris_start_address = (USI) strtoul (chp, &chp, 0);
180
181 if (errno != 0 || *chp != 0)
182 {
183 sim_io_eprintf (sd, "Invalid option `--cris-start-address=%s'\n",
184 arg);
185 return SIM_RC_FAIL;
186 }
187 break;
188
189 case OPTION_CRIS_PROGRAM_OFFSET:
190 errno = 0;
191 cris_program_offset = (int) strtol (chp, &chp, 0);
192
193 if (errno != 0 || *chp != 0)
194 {
195 sim_io_eprintf (sd, "Invalid option `--cris-program-offset=%s'\n",
196 arg);
197 return SIM_RC_FAIL;
198 }
199 break;
200
466b1d33
HPN
201 case OPTION_CRIS_UNKNOWN_SYSCALL:
202 if (strcmp (arg, "enosys") == 0)
203 cris_unknown_syscall_action = CRIS_USYSC_MSG_ENOSYS;
204 else if (strcmp (arg, "enosys-quiet") == 0)
205 cris_unknown_syscall_action = CRIS_USYSC_QUIET_ENOSYS;
206 else if (strcmp (arg, "stop") == 0)
207 cris_unknown_syscall_action = CRIS_USYSC_MSG_STOP;
208 else
209 {
210 sim_io_eprintf (sd, "Unknown option `--cris-unknown-syscall=%s'\n",
211 arg);
212 return SIM_RC_FAIL;
213 }
214 break;
215
f6bcefef
HPN
216 default:
217 /* We'll actually never get here; the caller handles the error
218 case. */
219 sim_io_eprintf (sd, "Unknown option `%s'\n", arg);
220 return SIM_RC_FAIL;
221 }
222
223 /* Imply --profile-model=on. */
224 return sim_profile_set_option (sd, "-model", PROFILE_MODEL_IDX, "on");
225}
226
80e5c09e
HPN
227/* An ELF-specific simplified ../common/sim-load.c:sim_load_file,
228 using the program headers, not sections, in order to make sure that
229 the program headers themeselves are also loaded. The caller is
230 responsible for asserting that ABFD is an ELF file. */
231
232static bfd_boolean
233cris_load_elf_file (SIM_DESC sd, struct bfd *abfd, sim_write_fn do_write)
234{
235 Elf_Internal_Phdr *phdr;
236 int n_hdrs;
237 int i;
238 bfd_boolean verbose = STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG;
80e5c09e
HPN
239
240 phdr = elf_tdata (abfd)->phdr;
241 n_hdrs = elf_elfheader (abfd)->e_phnum;
242
243 /* We're only interested in PT_LOAD; all necessary information
244 should be covered by that. */
245 for (i = 0; i < n_hdrs; i++)
246 {
247 bfd_byte *buf;
248 bfd_vma lma = STATE_LOAD_AT_LMA_P (sd)
249 ? phdr[i].p_paddr : phdr[i].p_vaddr;
250
251 if (phdr[i].p_type != PT_LOAD)
252 continue;
253
254 buf = xmalloc (phdr[i].p_filesz);
255
256 if (verbose)
5ee0bc23
MF
257 sim_io_printf (sd,
258 "Loading segment at 0x%" BFD_VMA_FMT "x, size 0x%lx\n",
b3fbb288 259 lma, phdr[i].p_filesz);
80e5c09e
HPN
260
261 if (bfd_seek (abfd, phdr[i].p_offset, SEEK_SET) != 0
262 || (bfd_bread (buf, phdr[i].p_filesz, abfd) != phdr[i].p_filesz))
263 {
b3fbb288 264 sim_io_eprintf (sd,
5ee0bc23
MF
265 "%s: could not read segment at 0x%" BFD_VMA_FMT "x, "
266 "size 0x%lx\n",
b3fbb288 267 STATE_MY_NAME (sd), lma, phdr[i].p_filesz);
80e5c09e
HPN
268 free (buf);
269 return FALSE;
270 }
271
272 if (do_write (sd, lma, buf, phdr[i].p_filesz) != phdr[i].p_filesz)
273 {
b3fbb288 274 sim_io_eprintf (sd,
5ee0bc23
MF
275 "%s: could not load segment at 0x%" BFD_VMA_FMT "x, "
276 "size 0x%lx\n",
b3fbb288 277 STATE_MY_NAME (sd), lma, phdr[i].p_filesz);
80e5c09e
HPN
278 free (buf);
279 return FALSE;
280 }
281
282 free (buf);
283 }
284
285 return TRUE;
286}
287
f6bcefef
HPN
288/* Cover function of sim_state_free to free the cpu buffers as well. */
289
290static void
291free_state (SIM_DESC sd)
292{
293 if (STATE_MODULES (sd) != NULL)
294 sim_module_uninstall (sd);
295 sim_cpu_free_all (sd);
296 sim_state_free (sd);
297}
298
c10b3605
HPN
299/* Helper struct for cris_set_section_offset_iterator. */
300
301struct offsetinfo
302{
303 SIM_DESC sd;
304 int offset;
305};
306
307/* BFD section iterator to offset the LMA and VMA. */
308
309static void
310cris_set_section_offset_iterator (bfd *abfd, asection *s, void *vp)
311{
312 struct offsetinfo *p = (struct offsetinfo *) vp;
313 SIM_DESC sd = p->sd;
314 int offset = p->offset;
315
fd361982 316 if ((bfd_section_flags (s) & SEC_ALLOC))
c10b3605 317 {
fd361982 318 bfd_vma vma = bfd_section_vma (s);
c10b3605 319
fd361982 320 bfd_set_section_vma (s, vma + offset);
c10b3605
HPN
321 }
322
323 /* This seems clumsy and inaccurate, but let's stick to doing it the
324 same way as sim_analyze_program for consistency. */
fd361982
AM
325 if (strcmp (bfd_section_name (s), ".text") == 0)
326 STATE_TEXT_START (sd) = bfd_section_vma (s);
c10b3605
HPN
327}
328
329/* Adjust the start-address, LMA and VMA of a SD. Must be called
330 after sim_analyze_program. */
331
332static void
333cris_offset_sections (SIM_DESC sd, int offset)
334{
335 bfd_boolean ret;
336 struct bfd *abfd = STATE_PROG_BFD (sd);
337 asection *text;
338 struct offsetinfo oi;
339
340 /* Only happens for usage error. */
341 if (abfd == NULL)
342 return;
343
344 oi.sd = sd;
345 oi.offset = offset;
346
347 bfd_map_over_sections (abfd, cris_set_section_offset_iterator, &oi);
348 ret = bfd_set_start_address (abfd, bfd_get_start_address (abfd) + offset);
349
350 STATE_START_ADDR (sd) = bfd_get_start_address (abfd);
351}
352
80e5c09e
HPN
353/* BFD section iterator to find the highest and lowest allocated and
354 non-allocated section addresses (plus one). */
f6bcefef 355
80e5c09e
HPN
356static void
357get_progbounds_iterator (bfd *abfd ATTRIBUTE_UNUSED, asection *s, void *vp)
f6bcefef
HPN
358{
359 struct progbounds *pbp = (struct progbounds *) vp;
360
fd361982 361 if ((bfd_section_flags (s) & SEC_ALLOC))
f6bcefef 362 {
fd361982
AM
363 bfd_size_type sec_size = bfd_section_size (s);
364 bfd_size_type sec_start = bfd_section_vma (s);
f6bcefef
HPN
365 bfd_size_type sec_end = sec_start + sec_size;
366
367 if (sec_end > pbp->endmem)
368 pbp->endmem = sec_end;
369
370 if (sec_start < pbp->startmem)
371 pbp->startmem = sec_start;
80e5c09e 372
fd361982 373 if ((bfd_section_flags (s) & SEC_LOAD))
80e5c09e
HPN
374 {
375 if (sec_end > pbp->end_loadmem)
376 pbp->end_loadmem = sec_end;
377 }
378 else if (sec_start < pbp->start_nonloadmem)
379 pbp->start_nonloadmem = sec_start;
380 }
381}
382
383/* Get the program boundaries. Because not everything is covered by
384 sections in ELF, notably the program headers, we use the program
385 headers instead. */
386
387static void
388cris_get_progbounds (struct bfd *abfd, struct progbounds *pbp)
389{
390 Elf_Internal_Phdr *phdr;
391 int n_hdrs;
392 int i;
393
394 pbp->startmem = 0xffffffff;
395 pbp->endmem = 0;
396 pbp->end_loadmem = 0;
397 pbp->start_nonloadmem = 0xffffffff;
398
399 /* In case we're ever used for something other than ELF, use the
400 generic method. */
401 if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
402 {
403 bfd_map_over_sections (abfd, get_progbounds_iterator, pbp);
404 return;
405 }
406
407 phdr = elf_tdata (abfd)->phdr;
408 n_hdrs = elf_elfheader (abfd)->e_phnum;
409
410 /* We're only interested in PT_LOAD; all necessary information
411 should be covered by that. */
412 for (i = 0; i < n_hdrs; i++)
413 {
414 if (phdr[i].p_type != PT_LOAD)
415 continue;
416
417 if (phdr[i].p_paddr < pbp->startmem)
418 pbp->startmem = phdr[i].p_paddr;
419
420 if (phdr[i].p_paddr + phdr[i].p_memsz > pbp->endmem)
421 pbp->endmem = phdr[i].p_paddr + phdr[i].p_memsz;
422
423 if (phdr[i].p_paddr + phdr[i].p_filesz > pbp->end_loadmem)
424 pbp->end_loadmem = phdr[i].p_paddr + phdr[i].p_filesz;
425
426 if (phdr[i].p_memsz > phdr[i].p_filesz
427 && phdr[i].p_paddr + phdr[i].p_filesz < pbp->start_nonloadmem)
428 pbp->start_nonloadmem = phdr[i].p_paddr + phdr[i].p_filesz;
429 }
430}
431
432/* Parameter communication by static variables, hmm... Oh well, for
433 simplicity. */
434static bfd_vma exec_load_addr;
435static bfd_vma interp_load_addr;
436static bfd_vma interp_start_addr;
437
438/* Supposed to mimic Linux' "NEW_AUX_ENT (AT_PHDR, load_addr + exec->e_phoff)". */
439
440static USI
441aux_ent_phdr (struct bfd *ebfd)
442{
443 return elf_elfheader (ebfd)->e_phoff + exec_load_addr;
444}
445
446/* We just pass on the header info; we don't have our own idea of the
447 program header entry size. */
448
449static USI
450aux_ent_phent (struct bfd *ebfd)
451{
452 return elf_elfheader (ebfd)->e_phentsize;
453}
454
455/* Like "NEW_AUX_ENT(AT_PHNUM, exec->e_phnum)". */
456
457static USI
458aux_ent_phnum (struct bfd *ebfd)
459{
460 return elf_elfheader (ebfd)->e_phnum;
461}
462
463/* Like "NEW_AUX_ENT(AT_BASE, interp_load_addr)". */
464
465static USI
466aux_ent_base (struct bfd *ebfd)
467{
468 return interp_load_addr;
469}
470
471/* Like "NEW_AUX_ENT(AT_ENTRY, exec->e_entry)". */
472
473static USI
474aux_ent_entry (struct bfd *ebfd)
475{
476 ASSERT (elf_elfheader (ebfd)->e_entry == bfd_get_start_address (ebfd));
477 return elf_elfheader (ebfd)->e_entry;
478}
479
480/* Helper for cris_handle_interpreter: like sim_write, but load at
481 interp_load_addr offset. */
482
483static int
072d63a8 484cris_write_interp (SIM_DESC sd, SIM_ADDR mem, const unsigned char *buf, int length)
80e5c09e
HPN
485{
486 return sim_write (sd, mem + interp_load_addr, buf, length);
487}
488
489/* Cater to the presence of an interpreter: load it and set
490 interp_start_addr. Return FALSE if there was an error, TRUE if
491 everything went fine, including an interpreter being absent and
492 the program being in a non-ELF format. */
493
494static bfd_boolean
495cris_handle_interpreter (SIM_DESC sd, struct bfd *abfd)
496{
497 int i, n_hdrs;
80e5c09e
HPN
498 bfd_byte buf[4];
499 char *interp = NULL;
500 struct bfd *ibfd;
501 bfd_boolean ok = FALSE;
502 Elf_Internal_Phdr *phdr;
503
504 if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
505 return TRUE;
506
507 phdr = elf_tdata (abfd)->phdr;
508 n_hdrs = aux_ent_phnum (abfd);
509
510 /* Check the program headers for presence of an interpreter. */
511 for (i = 0; i < n_hdrs; i++)
512 {
513 int interplen;
514 bfd_size_type interpsiz, interp_filesiz;
515 struct progbounds interp_bounds;
516
517 if (phdr[i].p_type != PT_INTERP)
518 continue;
519
520 /* Get the name of the interpreter, prepended with the sysroot
521 (empty if absent). */
522 interplen = phdr[i].p_filesz;
523 interp = xmalloc (interplen + strlen (simulator_sysroot));
524 strcpy (interp, simulator_sysroot);
525
526 /* Read in the name. */
527 if (bfd_seek (abfd, phdr[i].p_offset, SEEK_SET) != 0
528 || (bfd_bread (interp + strlen (simulator_sysroot), interplen, abfd)
529 != interplen))
530 goto interpname_failed;
531
532 /* Like Linux, require the string to be 0-terminated. */
533 if (interp[interplen + strlen (simulator_sysroot) - 1] != 0)
534 goto interpname_failed;
535
536 /* Inspect the interpreter. */
537 ibfd = bfd_openr (interp, STATE_TARGET (sd));
538 if (ibfd == NULL)
539 goto interpname_failed;
540
c10b3605 541 /* The interpreter is at least something readable to BFD; make
80e5c09e
HPN
542 sure it's an ELF non-archive file. */
543 if (!bfd_check_format (ibfd, bfd_object)
544 || bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
545 goto interp_failed;
546
547 /* Check the layout of the interpreter. */
548 cris_get_progbounds (ibfd, &interp_bounds);
549
550 /* Round down to pagesize the start page and up the endpage.
551 Don't round the *load and *nonload members. */
552 interp_bounds.startmem &= ~8191;
553 interp_bounds.endmem = (interp_bounds.endmem + 8191) & ~8191;
554
555 /* Until we need a more dynamic solution, assume we can put the
556 interpreter at this fixed location. NB: this is not what
557 happens for Linux 2008-12-28, but it could and might and
558 perhaps should. */
559 interp_load_addr = 0x40000;
560 interpsiz = interp_bounds.endmem - interp_bounds.startmem;
561 interp_filesiz = interp_bounds.end_loadmem - interp_bounds.startmem;
562
563 /* If we have a non-DSO or interpreter starting at the wrong
564 address, bail. */
565 if (interp_bounds.startmem != 0
566 || interpsiz + interp_load_addr >= exec_load_addr)
567 goto interp_failed;
568
569 /* We don't have the API to get the address of a simulator
570 memory area, so we go via a temporary area. Luckily, the
571 interpreter is supposed to be small, less than 0x40000
572 bytes. */
5ee0bc23 573 sim_do_commandf (sd, "memory region 0x%" BFD_VMA_FMT "x,0x%lx",
80e5c09e
HPN
574 interp_load_addr, interpsiz);
575
576 /* Now that memory for the interpreter is defined, load it. */
577 if (!cris_load_elf_file (sd, ibfd, cris_write_interp))
578 goto interp_failed;
579
580 /* It's no use setting STATE_START_ADDR, because it gets
581 overwritten by a sim_analyze_program call in sim_load. Let's
582 just store it locally. */
583 interp_start_addr
584 = (bfd_get_start_address (ibfd)
585 - interp_bounds.startmem + interp_load_addr);
586
587 /* Linux cares only about the first PT_INTERP, so let's ignore
588 the rest. */
589 goto all_done;
f6bcefef 590 }
80e5c09e
HPN
591
592 /* Register R10 should hold 0 at static start (no finifunc), but
593 that's the default, so don't bother. */
594 return TRUE;
595
596 all_done:
597 ok = TRUE;
598
599 interp_failed:
600 bfd_close (ibfd);
601
602 interpname_failed:
603 if (!ok)
604 sim_io_eprintf (sd,
605 "%s: could not load ELF interpreter `%s' for program `%s'\n",
606 STATE_MY_NAME (sd),
607 interp == NULL ? "(what's-its-name)" : interp,
608 bfd_get_filename (abfd));
609 free (interp);
610 return ok;
f6bcefef
HPN
611}
612
1c636da0
MF
613extern const SIM_MACH * const cris_sim_machs[];
614
f6bcefef
HPN
615/* Create an instance of the simulator. */
616
617SIM_DESC
618sim_open (SIM_OPEN_KIND kind, host_callback *callback, struct bfd *abfd,
2e3d4f4d 619 char * const *argv)
f6bcefef
HPN
620{
621 char c;
622 int i;
623 USI startmem = 0;
624 USI endmem = CRIS_DEFAULT_MEM_SIZE;
625 USI endbrk = endmem;
626 USI stack_low = 0;
627 SIM_DESC sd = sim_state_alloc (kind, callback);
628
80e5c09e
HPN
629 static const struct auxv_entries_s
630 {
631 bfd_byte id;
632 USI (*efn) (struct bfd *ebfd);
633 USI val;
634 } auxv_entries[] =
635 {
a3d4b83b
HPN
636#define AUX_ENT(a, b) {a, NULL, b}
637#define AUX_ENTF(a, f) {a, f, 0}
80e5c09e
HPN
638 AUX_ENT (AT_HWCAP, 0),
639 AUX_ENT (AT_PAGESZ, 8192),
640 AUX_ENT (AT_CLKTCK, 100),
a3d4b83b
HPN
641 AUX_ENTF (AT_PHDR, aux_ent_phdr),
642 AUX_ENTF (AT_PHENT, aux_ent_phent),
643 AUX_ENTF (AT_PHNUM, aux_ent_phnum),
644 AUX_ENTF (AT_BASE, aux_ent_base),
80e5c09e 645 AUX_ENT (AT_FLAGS, 0),
a3d4b83b 646 AUX_ENTF (AT_ENTRY, aux_ent_entry),
80e5c09e
HPN
647
648 /* Or is root better? Maybe have it settable? */
649 AUX_ENT (AT_UID, 500),
650 AUX_ENT (AT_EUID, 500),
651 AUX_ENT (AT_GID, 500),
652 AUX_ENT (AT_EGID, 500),
a3d4b83b 653 AUX_ENT (AT_SECURE, 0),
80e5c09e
HPN
654 AUX_ENT (AT_NULL, 0)
655 };
656
f6bcefef
HPN
657 /* Can't initialize to "" below. It's either a GCC bug in old
658 releases (up to and including 2.95.3 (.4 in debian) or a bug in the
659 standard ;-) that the rest of the elements won't be initialized. */
660 bfd_byte sp_init[4] = {0, 0, 0, 0};
661
f9a4d543 662 /* Set default options before parsing user options. */
1c636da0 663 STATE_MACHS (sd) = cris_sim_machs;
d414eb3e 664 STATE_MODEL_NAME (sd) = "crisv32";
f9a4d543
MF
665 current_target_byte_order = BFD_ENDIAN_LITTLE;
666
f6bcefef 667 /* The cpu data is kept in a separately allocated chunk of memory. */
d5a71b11 668 if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
f6bcefef
HPN
669 {
670 free_state (sd);
671 return 0;
672 }
673
674 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
675 {
676 free_state (sd);
677 return 0;
678 }
679
9db2b719
MF
680 /* Add the CRIS-specific option list to the simulator. */
681 if (sim_add_option_table (sd, NULL, cris_options) != SIM_RC_OK)
682 {
683 free_state (sd);
684 return 0;
685 }
686
77cf2ef5 687 /* The parser will print an error message for us, so we silently return. */
f6bcefef
HPN
688 if (sim_parse_args (sd, argv) != SIM_RC_OK)
689 {
690 free_state (sd);
691 return 0;
692 }
693
f6bcefef 694 /* check for/establish the reference program image */
e8f20a28 695 if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
f6bcefef 696 {
a0956358
HPN
697 /* When there's an error, sim_analyze_program has already output
698 a message. Let's just clarify it, as "not an object file"
699 perhaps doesn't ring a bell. */
700 sim_io_eprintf (sd, "(not a CRIS program)\n");
80e5c09e
HPN
701 free_state (sd);
702 return 0;
703 }
704
705 /* We might get called with the caller expecting us to get hold of
706 the bfd for ourselves, which would happen at the
707 sim_analyze_program call above. */
708 if (abfd == NULL)
709 abfd = STATE_PROG_BFD (sd);
710
c10b3605
HPN
711 /* Adjust the addresses of the program at this point. Unfortunately
712 this does not affect ELF program headers, so we have to handle
713 that separately. */
714 cris_offset_sections (sd, cris_program_offset);
715
716 if (abfd != NULL && bfd_get_arch (abfd) == bfd_arch_unknown)
80e5c09e 717 {
e8f20a28 718 if (STATE_PROG_FILE (sd) != NULL)
a0956358 719 sim_io_eprintf (sd, "%s: `%s' is not a CRIS program\n",
e8f20a28 720 STATE_MY_NAME (sd), STATE_PROG_FILE (sd));
80e5c09e
HPN
721 else
722 sim_io_eprintf (sd, "%s: program to be run is not a CRIS program\n",
723 STATE_MY_NAME (sd));
f6bcefef
HPN
724 free_state (sd);
725 return 0;
726 }
727
728 /* For CRIS simulator-specific use, we need to find out the bounds of
729 the program as well, which is not done by sim_analyze_program
730 above. */
80e5c09e 731 if (abfd != NULL)
f6bcefef
HPN
732 {
733 struct progbounds pb;
734
735 /* The sections should now be accessible using bfd functions. */
80e5c09e 736 cris_get_progbounds (abfd, &pb);
f6bcefef
HPN
737
738 /* We align the area that the program uses to page boundaries. */
739 startmem = pb.startmem & ~8191;
740 endbrk = pb.endmem;
741 endmem = (endbrk + 8191) & ~8191;
742 }
743
744 /* Find out how much room is needed for the environment and argv, create
745 that memory and fill it. Only do this when there's a program
8cfc9a18
MF
746 specified.
747
748 TODO: Move this to sim_create_inferior and use STATE_PROG_ENVP. */
80e5c09e 749 if (abfd != NULL && !cris_bare_iron)
f6bcefef 750 {
b16c44de 751 const char *name = bfd_get_filename (abfd);
f6bcefef
HPN
752 /* We use these maps to give the same behavior as the old xsim
753 simulator. */
754 USI envtop = 0x40000000;
755 USI stacktop = 0x3e000000;
756 USI envstart;
757 int envc;
758 int len = strlen (name) + 1;
759 USI epp, epp0;
760 USI stacklen;
761 int i;
762 char **prog_argv = STATE_PROG_ARGV (sd);
763 int my_argc = 0;
f6bcefef
HPN
764 USI csp;
765 bfd_byte buf[4];
766
767 /* Count in the environment as well. */
c5a2e012
MF
768 for (envc = 0; environ[envc] != NULL; envc++)
769 len += strlen (environ[envc]) + 1;
f6bcefef
HPN
770
771 for (i = 0; prog_argv[i] != NULL; my_argc++, i++)
772 len += strlen (prog_argv[i]) + 1;
773
774 envstart = (envtop - len) & ~8191;
775
776 /* Create read-only block for the environment strings. */
777 sim_core_attach (sd, NULL, 0, access_read, 0,
778 envstart, (len + 8191) & ~8191,
779 0, NULL, NULL);
780
781 /* This shouldn't happen. */
782 if (envstart < stacktop)
783 stacktop = envstart - 64 * 8192;
784
785 csp = stacktop;
786
787 /* Note that the linux kernel does not correctly compute the storage
788 needs for the static-exe AUX vector. */
80e5c09e 789
13a590ca 790 csp -= ARRAY_SIZE (auxv_entries) * 4 * 2;
f6bcefef
HPN
791
792 csp -= (envc + 1) * 4;
793 csp -= (my_argc + 1) * 4;
794 csp -= 4;
795
796 /* Write the target representation of the start-up-value for the
797 stack-pointer suitable for register initialization below. */
798 bfd_putl32 (csp, sp_init);
799
800 /* If we make this 1M higher; say 8192*1024, we have to take
801 special precautions for pthreads, because pthreads assumes that
802 the memory that low isn't mmapped, and that it can mmap it
803 without fallback in case of failure (and we fail ungracefully
804 long before *that*: the memory isn't accounted for in our mmap
805 list). */
806 stack_low = (csp - (7168*1024)) & ~8191;
807
808 stacklen = stacktop - stack_low;
809
810 /* Tee hee, we have an executable stack. Well, it's necessary to
811 test GCC trampolines... */
812 sim_core_attach (sd, NULL, 0, access_read_write_exec, 0,
813 stack_low, stacklen,
814 0, NULL, NULL);
815
816 epp = epp0 = envstart;
817
818 /* Can't use sim_core_write_unaligned_4 without everything
819 initialized when tracing, and then these writes would get into
820 the trace. */
821#define write_dword(addr, data) \
822 do \
823 { \
824 USI data_ = data; \
825 USI addr_ = addr; \
826 bfd_putl32 (data_, buf); \
8b494522 827 if (sim_core_write_buffer (sd, NULL, NULL_CIA, buf, addr_, 4) != 4)\
f6bcefef
HPN
828 goto abandon_chip; \
829 } \
830 while (0)
831
832 write_dword (csp, my_argc);
833 csp += 4;
834
835 for (i = 0; i < my_argc; i++, csp += 4)
836 {
837 size_t strln = strlen (prog_argv[i]) + 1;
838
8b494522
MF
839 if (sim_core_write_buffer (sd, NULL, NULL_CIA, prog_argv[i], epp,
840 strln)
f6bcefef
HPN
841 != strln)
842 goto abandon_chip;
843
844 write_dword (csp, envstart + epp - epp0);
845 epp += strln;
846 }
847
848 write_dword (csp, 0);
849 csp += 4;
850
851 for (i = 0; i < envc; i++, csp += 4)
852 {
c5a2e012 853 unsigned int strln = strlen (environ[i]) + 1;
f6bcefef 854
c5a2e012 855 if (sim_core_write_buffer (sd, NULL, NULL_CIA, environ[i], epp, strln)
f6bcefef
HPN
856 != strln)
857 goto abandon_chip;
858
859 write_dword (csp, envstart + epp - epp0);
860 epp += strln;
861 }
862
863 write_dword (csp, 0);
864 csp += 4;
865
80e5c09e
HPN
866 /* The load address of the executable could presumably be
867 different than the lowest used memory address, but let's
868 stick to simplicity until needed. And
869 cris_handle_interpreter might change startmem and endmem, so
870 let's set it now. */
871 exec_load_addr = startmem;
f6bcefef 872
80e5c09e
HPN
873 if (!cris_handle_interpreter (sd, abfd))
874 goto abandon_chip;
f6bcefef 875
80e5c09e 876 if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
13a590ca 877 for (i = 0; i < ARRAY_SIZE (auxv_entries); i++)
80e5c09e
HPN
878 {
879 write_dword (csp, auxv_entries[i].id);
880 write_dword (csp + 4,
881 auxv_entries[i].efn != NULL
882 ? (*auxv_entries[i].efn) (abfd)
883 : auxv_entries[i].val);
884 csp += 4 + 4;
885 }
f6bcefef
HPN
886 }
887
888 /* Allocate core managed memory if none specified by user. */
889 if (sim_core_read_buffer (sd, NULL, read_map, &c, startmem, 1) == 0)
9d67b0a0 890 sim_do_commandf (sd, "memory region 0x%" PRIx32 ",0x%" PRIx32,
5ee0bc23 891 startmem, endmem - startmem);
f6bcefef
HPN
892
893 /* Allocate simulator I/O managed memory if none specified by user. */
894 if (cris_have_900000xxif)
34cf5112 895 sim_hw_parse (sd, "/core/%s/reg %#x %i", "cris_900000xx", 0x90000000, 0x100);
f6bcefef
HPN
896
897 /* Establish any remaining configuration options. */
898 if (sim_config (sd) != SIM_RC_OK)
899 {
900 abandon_chip:
901 free_state (sd);
902 return 0;
903 }
904
905 if (sim_post_argv_init (sd) != SIM_RC_OK)
906 {
907 free_state (sd);
908 return 0;
909 }
910
911 /* Open a copy of the cpu descriptor table. */
912 {
913 CGEN_CPU_DESC cd = cris_cgen_cpu_open_1 (STATE_ARCHITECTURE (sd)->printable_name,
914 CGEN_ENDIAN_LITTLE);
915 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
916 {
917 SIM_CPU *cpu = STATE_CPU (sd, i);
918 CPU_CPU_DESC (cpu) = cd;
919 CPU_DISASSEMBLER (cpu) = cris_disassemble_insn;
920
921 /* See cris_option_handler for the reason why this is needed. */
922 CPU_CRIS_MISC_PROFILE (cpu)->flags = STATE_TRACE_FLAGS (sd)[0];
923
924 /* Set SP to the stack we allocated above. */
072d63a8 925 (* CPU_REG_STORE (cpu)) (cpu, H_GR_SP, (unsigned char *) sp_init, 4);
f6bcefef
HPN
926
927 /* Set the simulator environment data. */
928 cpu->highest_mmapped_page = NULL;
929 cpu->endmem = endmem;
930 cpu->endbrk = endbrk;
931 cpu->stack_low = stack_low;
932 cpu->syscalls = 0;
933 cpu->m1threads = 0;
934 cpu->threadno = 0;
935 cpu->max_threadid = 0;
936 cpu->thread_data = NULL;
937 memset (cpu->sighandler, 0, sizeof (cpu->sighandler));
938 cpu->make_thread_cpu_data = NULL;
939 cpu->thread_cpu_data_size = 0;
aad3b3cb
HPN
940#if WITH_HW
941 cpu->deliver_interrupt = NULL;
942#endif
f6bcefef 943 }
aad3b3cb
HPN
944#if WITH_HW
945 /* Always be cycle-accurate and call before/after functions if
946 with-hardware. */
947 sim_profile_set_option (sd, "-model", PROFILE_MODEL_IDX, "on");
948#endif
f6bcefef
HPN
949 }
950
f6bcefef
HPN
951 cris_set_callbacks (callback);
952
953 return sd;
954}
f6bcefef
HPN
955\f
956SIM_RC
957sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
54f7a83a
MF
958 char * const *argv,
959 char * const *env)
f6bcefef
HPN
960{
961 SIM_CPU *current_cpu = STATE_CPU (sd, 0);
8cfc9a18 962 host_callback *cb = STATE_CALLBACK (sd);
f6bcefef
HPN
963 SIM_ADDR addr;
964
80e5c09e 965 if (sd != NULL)
c10b3605
HPN
966 addr = cris_start_address != (SIM_ADDR) -1
967 ? cris_start_address
968 : (interp_start_addr != 0
969 ? interp_start_addr
970 : bfd_get_start_address (abfd));
f6bcefef
HPN
971 else
972 addr = 0;
973 sim_pc_set (current_cpu, addr);
974
0e967299
MF
975 /* Standalone mode (i.e. `run`) will take care of the argv for us in
976 sim_open() -> sim_parse_args(). But in debug mode (i.e. 'target sim'
977 with `gdb`), we need to handle it because the user can change the
978 argv on the fly via gdb's 'run'. */
979 if (STATE_PROG_ARGV (sd) != argv)
980 {
981 freeargv (STATE_PROG_ARGV (sd));
982 STATE_PROG_ARGV (sd) = dupargv (argv);
983 }
f6bcefef 984
54f7a83a
MF
985 if (STATE_PROG_ENVP (sd) != env)
986 {
987 freeargv (STATE_PROG_ENVP (sd));
988 STATE_PROG_ENVP (sd) = dupargv (env);
989 }
990
8cfc9a18
MF
991 cb->argv = STATE_PROG_ARGV (sd);
992 cb->envp = STATE_PROG_ENVP (sd);
993
f6bcefef
HPN
994 return SIM_RC_OK;
995}
f6bcefef
HPN
996\f
997/* Disassemble an instruction. */
998
999static void
1000cris_disassemble_insn (SIM_CPU *cpu,
1001 const CGEN_INSN *insn ATTRIBUTE_UNUSED,
1002 const ARGBUF *abuf ATTRIBUTE_UNUSED,
1003 IADDR pc, char *buf)
1004{
1005 disassembler_ftype pinsn;
1006 struct disassemble_info disasm_info;
1007 SFILE sfile;
1008 SIM_DESC sd = CPU_STATE (cpu);
1009
1010 sfile.buffer = sfile.current = buf;
1011 INIT_DISASSEMBLE_INFO (disasm_info, (FILE *) &sfile,
1012 (fprintf_ftype) sim_disasm_sprintf);
80e5c09e
HPN
1013 disasm_info.endian = BFD_ENDIAN_LITTLE;
1014 disasm_info.read_memory_func = sim_disasm_read_memory;
f6bcefef
HPN
1015 disasm_info.memory_error_func = sim_disasm_perror_memory;
1016 disasm_info.application_data = (PTR) cpu;
1017 pinsn = cris_get_disassembler (STATE_PROG_BFD (sd));
1018 (*pinsn) (pc, &disasm_info);
1019}