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