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