1/* run front end support for arm 2 Copyright (C) 1995-2023 Free Software Foundation, Inc. 3 4 This file is part of ARM SIM. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 19/* This file provides the interface between the simulator and 20 run.c and gdb (when the simulator is linked with gdb). 21 All simulator interaction should go through this file. */ 22 23/* This must come before any other includes. */ 24#include "defs.h" 25 26#include <stdio.h> 27#include <stdarg.h> 28#include <stdlib.h> 29#include <string.h> 30#include <bfd.h> 31#include <signal.h> 32#include "sim/callback.h" 33#include "sim/sim.h" 34#include "sim-main.h" 35#include "sim-options.h" 36#include "armemu.h" 37#include "dbg_rdi.h" 38#include "ansidecl.h" 39#include "gdb/sim-arm.h" 40#include "gdb/signals.h" 41#include "libiberty.h" 42#include "iwmmxt.h" 43#include "maverick.h" 44 45/* TODO: This should get pulled from the SIM_DESC. */ 46host_callback *sim_callback; 47 48/* TODO: This should get merged into sim_cpu. */ 49struct ARMul_State *state; 50 51/* Memory size in bytes. */ 52/* TODO: Memory should be converted to the common memory module. */ 53static int mem_size = (1 << 21); 54 55int stop_simulator; 56 57#include "dis-asm.h" 58 59/* TODO: Tracing should be converted to common tracing module. */ 60int trace = 0; 61int disas = 0; 62int trace_funcs = 0; 63 64static struct disassemble_info info; 65static char opbuf[1000]; 66 67static int ATTRIBUTE_PRINTF (2, 3) 68op_printf (char *buf, const char *fmt, ...) 69{ 70 int ret; 71 va_list ap; 72 73 va_start (ap, fmt); 74 ret = vsprintf (opbuf + strlen (opbuf), fmt, ap); 75 va_end (ap); 76 return ret; 77} 78 79static int ATTRIBUTE_PRINTF (3, 4) 80op_styled_printf (char *buf, enum disassembler_style style, 81 const char *fmt, ...) 82{ 83 int ret; 84 va_list ap; 85 86 va_start (ap, fmt); 87 ret = vsprintf (opbuf + strlen (opbuf), fmt, ap); 88 va_end (ap); 89 return ret; 90} 91 92static int 93sim_dis_read (bfd_vma memaddr ATTRIBUTE_UNUSED, 94 bfd_byte * ptr, 95 unsigned int length, 96 struct disassemble_info * info) 97{ 98 ARMword val = (ARMword) *((ARMword *) info->application_data); 99 100 while (length--) 101 { 102 * ptr ++ = val & 0xFF; 103 val >>= 8; 104 } 105 return 0; 106} 107 108void 109print_insn (ARMword instr) 110{ 111 int size; 112 disassembler_ftype disassemble_fn; 113 114 opbuf[0] = 0; 115 info.application_data = & instr; 116 disassemble_fn = disassembler (bfd_arch_arm, 0, 0, NULL); 117 size = disassemble_fn (0, & info); 118 fprintf (stderr, " %*s\n", size, opbuf); 119} 120 121static void 122init (void) 123{ 124 static int done; 125 126 if (!done) 127 { 128 ARMul_EmulateInit (); 129 state = ARMul_NewState (); 130 state->bigendSig = (CURRENT_TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? HIGH : LOW); 131 ARMul_MemoryInit (state, mem_size); 132 ARMul_OSInit (state); 133 state->verbose = 0; 134 done = 1; 135 } 136} 137 138void 139ARMul_ConsolePrint (ARMul_State * state, 140 const char * format, 141 ...) 142{ 143 va_list ap; 144 145 if (state->verbose) 146 { 147 va_start (ap, format); 148 vprintf (format, ap); 149 va_end (ap); 150 } 151} 152 153int 154sim_write (SIM_DESC sd ATTRIBUTE_UNUSED, 155 SIM_ADDR addr, 156 const void * buffer, 157 int size) 158{ 159 int i; 160 const unsigned char * data = buffer; 161 162 init (); 163 164 for (i = 0; i < size; i++) 165 ARMul_SafeWriteByte (state, addr + i, data[i]); 166 167 return size; 168} 169 170int 171sim_read (SIM_DESC sd ATTRIBUTE_UNUSED, 172 SIM_ADDR addr, 173 void * buffer, 174 int size) 175{ 176 int i; 177 unsigned char * data = buffer; 178 179 init (); 180 181 for (i = 0; i < size; i++) 182 data[i] = ARMul_SafeReadByte (state, addr + i); 183 184 return size; 185} 186 187int 188sim_stop (SIM_DESC sd ATTRIBUTE_UNUSED) 189{ 190 state->Emulate = STOP; 191 stop_simulator = 1; 192 return 1; 193} 194 195void 196sim_resume (SIM_DESC sd ATTRIBUTE_UNUSED, 197 int step, 198 int siggnal ATTRIBUTE_UNUSED) 199{ 200 state->EndCondition = 0; 201 stop_simulator = 0; 202 203 if (step) 204 { 205 state->Reg[15] = ARMul_DoInstr (state); 206 if (state->EndCondition == 0) 207 state->EndCondition = RDIError_BreakpointReached; 208 } 209 else 210 { 211 state->NextInstr = RESUME; /* treat as PC change */ 212 state->Reg[15] = ARMul_DoProg (state); 213 } 214 215 FLUSHPIPE; 216} 217 218SIM_RC 219sim_create_inferior (SIM_DESC sd ATTRIBUTE_UNUSED, 220 struct bfd * abfd, 221 char * const *argv, 222 char * const *env) 223{ 224 int argvlen = 0; 225 int mach; 226 char * const *arg; 227 228 init (); 229 230 if (abfd != NULL) 231 { 232 ARMul_SetPC (state, bfd_get_start_address (abfd)); 233 mach = bfd_get_mach (abfd); 234 } 235 else 236 { 237 ARMul_SetPC (state, 0); /* ??? */ 238 mach = 0; 239 } 240 241#ifdef MODET 242 if (abfd != NULL && (bfd_get_start_address (abfd) & 1)) 243 SETT; 244#endif 245 246 switch (mach) 247 { 248 default: 249 (*sim_callback->printf_filtered) 250 (sim_callback, 251 "Unknown machine type '%d'; please update sim_create_inferior.\n", 252 mach); 253 /* fall through */ 254 255 case 0: 256 /* We wouldn't set the machine type with earlier toolchains, so we 257 explicitly select a processor capable of supporting all ARMs in 258 32bit mode. */ 259 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_v6_Prop); 260 break; 261 262#if 1 263 case bfd_mach_arm_6T2: 264 case bfd_mach_arm_7: 265 case bfd_mach_arm_7EM: 266 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_v6_Prop); 267 break; 268#endif 269 270 case bfd_mach_arm_XScale: 271 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_v6_Prop); 272 break; 273 274 case bfd_mach_arm_iWMMXt2: 275 case bfd_mach_arm_iWMMXt: 276 { 277 extern int SWI_vector_installed; 278 ARMword i; 279 280 if (! SWI_vector_installed) 281 { 282 /* Intialise the hardware vectors to zero. */ 283 if (! SWI_vector_installed) 284 for (i = ARMul_ResetV; i <= ARMFIQV; i += 4) 285 ARMul_WriteWord (state, i, 0); 286 287 /* ARM_WriteWord will have detected the write to the SWI vector, 288 but we want SWI_vector_installed to remain at 0 so that thumb 289 mode breakpoints will work. */ 290 SWI_vector_installed = 0; 291 } 292 } 293 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_iWMMXt_Prop); 294 break; 295 296 case bfd_mach_arm_ep9312: 297 ARMul_SelectProcessor (state, ARM_v4_Prop | ARM_ep9312_Prop); 298 break; 299 300 case bfd_mach_arm_5: 301 if (bfd_family_coff (abfd)) 302 { 303 /* This is a special case in order to support COFF based ARM toolchains. 304 The COFF header does not have enough room to store all the different 305 kinds of ARM cpu, so the XScale, v5T and v5TE architectures all default 306 to v5. (See coff_set_flags() in bdf/coffcode.h). So if we see a v5 307 machine type here, we assume it could be any of the above architectures 308 and so select the most feature-full. */ 309 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop); 310 break; 311 } 312 /* Otherwise drop through. */ 313 314 case bfd_mach_arm_5T: 315 ARMul_SelectProcessor (state, ARM_v5_Prop); 316 break; 317 318 case bfd_mach_arm_5TE: 319 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop); 320 break; 321 322 case bfd_mach_arm_4: 323 case bfd_mach_arm_4T: 324 ARMul_SelectProcessor (state, ARM_v4_Prop); 325 break; 326 327 case bfd_mach_arm_3: 328 case bfd_mach_arm_3M: 329 ARMul_SelectProcessor (state, ARM_Lock_Prop); 330 break; 331 332 case bfd_mach_arm_2: 333 case bfd_mach_arm_2a: 334 ARMul_SelectProcessor (state, ARM_Fix26_Prop); 335 break; 336 } 337 338 memset (& info, 0, sizeof (info)); 339 INIT_DISASSEMBLE_INFO (info, stdout, op_printf, op_styled_printf); 340 info.read_memory_func = sim_dis_read; 341 info.arch = bfd_get_arch (abfd); 342 info.mach = bfd_get_mach (abfd); 343 info.endian_code = BFD_ENDIAN_LITTLE; 344 if (info.mach == 0) 345 info.arch = bfd_arch_arm; 346 disassemble_init_for_target (& info); 347 348 if (argv != NULL) 349 { 350 /* Set up the command line by laboriously stringing together 351 the environment carefully picked apart by our caller. */ 352 353 /* Free any old stuff. */ 354 if (state->CommandLine != NULL) 355 { 356 free (state->CommandLine); 357 state->CommandLine = NULL; 358 } 359 360 /* See how much we need. */ 361 for (arg = argv; *arg != NULL; arg++) 362 argvlen += strlen (*arg) + 1; 363 364 /* Allocate it. */ 365 state->CommandLine = malloc (argvlen + 1); 366 if (state->CommandLine != NULL) 367 { 368 arg = argv; 369 state->CommandLine[0] = '\0'; 370 371 for (arg = argv; *arg != NULL; arg++) 372 { 373 strcat (state->CommandLine, *arg); 374 strcat (state->CommandLine, " "); 375 } 376 } 377 } 378 379 if (env != NULL) 380 { 381 /* Now see if there's a MEMSIZE spec in the environment. */ 382 while (*env) 383 { 384 if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0) 385 { 386 char *end_of_num; 387 388 /* Set up memory limit. */ 389 state->MemSize = 390 strtoul (*env + sizeof ("MEMSIZE=") - 1, &end_of_num, 0); 391 } 392 env++; 393 } 394 } 395 396 return SIM_RC_OK; 397} 398 399static int 400frommem (struct ARMul_State *state, const unsigned char *memory) 401{ 402 if (state->bigendSig == HIGH) 403 return (memory[0] << 24) | (memory[1] << 16) 404 | (memory[2] << 8) | (memory[3] << 0); 405 else 406 return (memory[3] << 24) | (memory[2] << 16) 407 | (memory[1] << 8) | (memory[0] << 0); 408} 409 410static void 411tomem (struct ARMul_State *state, 412 unsigned char *memory, 413 int val) 414{ 415 if (state->bigendSig == HIGH) 416 { 417 memory[0] = val >> 24; 418 memory[1] = val >> 16; 419 memory[2] = val >> 8; 420 memory[3] = val >> 0; 421 } 422 else 423 { 424 memory[3] = val >> 24; 425 memory[2] = val >> 16; 426 memory[1] = val >> 8; 427 memory[0] = val >> 0; 428 } 429} 430 431static int 432arm_reg_store (SIM_CPU *cpu, int rn, const void *buf, int length) 433{ 434 init (); 435 436 switch ((enum sim_arm_regs) rn) 437 { 438 case SIM_ARM_R0_REGNUM: 439 case SIM_ARM_R1_REGNUM: 440 case SIM_ARM_R2_REGNUM: 441 case SIM_ARM_R3_REGNUM: 442 case SIM_ARM_R4_REGNUM: 443 case SIM_ARM_R5_REGNUM: 444 case SIM_ARM_R6_REGNUM: 445 case SIM_ARM_R7_REGNUM: 446 case SIM_ARM_R8_REGNUM: 447 case SIM_ARM_R9_REGNUM: 448 case SIM_ARM_R10_REGNUM: 449 case SIM_ARM_R11_REGNUM: 450 case SIM_ARM_R12_REGNUM: 451 case SIM_ARM_R13_REGNUM: 452 case SIM_ARM_R14_REGNUM: 453 case SIM_ARM_R15_REGNUM: /* PC */ 454 case SIM_ARM_FP0_REGNUM: 455 case SIM_ARM_FP1_REGNUM: 456 case SIM_ARM_FP2_REGNUM: 457 case SIM_ARM_FP3_REGNUM: 458 case SIM_ARM_FP4_REGNUM: 459 case SIM_ARM_FP5_REGNUM: 460 case SIM_ARM_FP6_REGNUM: 461 case SIM_ARM_FP7_REGNUM: 462 case SIM_ARM_FPS_REGNUM: 463 ARMul_SetReg (state, state->Mode, rn, frommem (state, buf)); 464 break; 465 466 case SIM_ARM_PS_REGNUM: 467 state->Cpsr = frommem (state, buf); 468 ARMul_CPSRAltered (state); 469 break; 470 471 case SIM_ARM_MAVERIC_COP0R0_REGNUM: 472 case SIM_ARM_MAVERIC_COP0R1_REGNUM: 473 case SIM_ARM_MAVERIC_COP0R2_REGNUM: 474 case SIM_ARM_MAVERIC_COP0R3_REGNUM: 475 case SIM_ARM_MAVERIC_COP0R4_REGNUM: 476 case SIM_ARM_MAVERIC_COP0R5_REGNUM: 477 case SIM_ARM_MAVERIC_COP0R6_REGNUM: 478 case SIM_ARM_MAVERIC_COP0R7_REGNUM: 479 case SIM_ARM_MAVERIC_COP0R8_REGNUM: 480 case SIM_ARM_MAVERIC_COP0R9_REGNUM: 481 case SIM_ARM_MAVERIC_COP0R10_REGNUM: 482 case SIM_ARM_MAVERIC_COP0R11_REGNUM: 483 case SIM_ARM_MAVERIC_COP0R12_REGNUM: 484 case SIM_ARM_MAVERIC_COP0R13_REGNUM: 485 case SIM_ARM_MAVERIC_COP0R14_REGNUM: 486 case SIM_ARM_MAVERIC_COP0R15_REGNUM: 487 memcpy (& DSPregs [rn - SIM_ARM_MAVERIC_COP0R0_REGNUM], 488 buf, sizeof (struct maverick_regs)); 489 return sizeof (struct maverick_regs); 490 491 case SIM_ARM_MAVERIC_DSPSC_REGNUM: 492 memcpy (&DSPsc, buf, sizeof DSPsc); 493 return sizeof DSPsc; 494 495 case SIM_ARM_IWMMXT_COP0R0_REGNUM: 496 case SIM_ARM_IWMMXT_COP0R1_REGNUM: 497 case SIM_ARM_IWMMXT_COP0R2_REGNUM: 498 case SIM_ARM_IWMMXT_COP0R3_REGNUM: 499 case SIM_ARM_IWMMXT_COP0R4_REGNUM: 500 case SIM_ARM_IWMMXT_COP0R5_REGNUM: 501 case SIM_ARM_IWMMXT_COP0R6_REGNUM: 502 case SIM_ARM_IWMMXT_COP0R7_REGNUM: 503 case SIM_ARM_IWMMXT_COP0R8_REGNUM: 504 case SIM_ARM_IWMMXT_COP0R9_REGNUM: 505 case SIM_ARM_IWMMXT_COP0R10_REGNUM: 506 case SIM_ARM_IWMMXT_COP0R11_REGNUM: 507 case SIM_ARM_IWMMXT_COP0R12_REGNUM: 508 case SIM_ARM_IWMMXT_COP0R13_REGNUM: 509 case SIM_ARM_IWMMXT_COP0R14_REGNUM: 510 case SIM_ARM_IWMMXT_COP0R15_REGNUM: 511 case SIM_ARM_IWMMXT_COP1R0_REGNUM: 512 case SIM_ARM_IWMMXT_COP1R1_REGNUM: 513 case SIM_ARM_IWMMXT_COP1R2_REGNUM: 514 case SIM_ARM_IWMMXT_COP1R3_REGNUM: 515 case SIM_ARM_IWMMXT_COP1R4_REGNUM: 516 case SIM_ARM_IWMMXT_COP1R5_REGNUM: 517 case SIM_ARM_IWMMXT_COP1R6_REGNUM: 518 case SIM_ARM_IWMMXT_COP1R7_REGNUM: 519 case SIM_ARM_IWMMXT_COP1R8_REGNUM: 520 case SIM_ARM_IWMMXT_COP1R9_REGNUM: 521 case SIM_ARM_IWMMXT_COP1R10_REGNUM: 522 case SIM_ARM_IWMMXT_COP1R11_REGNUM: 523 case SIM_ARM_IWMMXT_COP1R12_REGNUM: 524 case SIM_ARM_IWMMXT_COP1R13_REGNUM: 525 case SIM_ARM_IWMMXT_COP1R14_REGNUM: 526 case SIM_ARM_IWMMXT_COP1R15_REGNUM: 527 return Store_Iwmmxt_Register (rn - SIM_ARM_IWMMXT_COP0R0_REGNUM, buf); 528 529 default: 530 return 0; 531 } 532 533 return length; 534} 535 536static int 537arm_reg_fetch (SIM_CPU *cpu, int rn, void *buf, int length) 538{ 539 unsigned char *memory = buf; 540 ARMword regval; 541 int len = length; 542 543 init (); 544 545 switch ((enum sim_arm_regs) rn) 546 { 547 case SIM_ARM_R0_REGNUM: 548 case SIM_ARM_R1_REGNUM: 549 case SIM_ARM_R2_REGNUM: 550 case SIM_ARM_R3_REGNUM: 551 case SIM_ARM_R4_REGNUM: 552 case SIM_ARM_R5_REGNUM: 553 case SIM_ARM_R6_REGNUM: 554 case SIM_ARM_R7_REGNUM: 555 case SIM_ARM_R8_REGNUM: 556 case SIM_ARM_R9_REGNUM: 557 case SIM_ARM_R10_REGNUM: 558 case SIM_ARM_R11_REGNUM: 559 case SIM_ARM_R12_REGNUM: 560 case SIM_ARM_R13_REGNUM: 561 case SIM_ARM_R14_REGNUM: 562 case SIM_ARM_R15_REGNUM: /* PC */ 563 regval = ARMul_GetReg (state, state->Mode, rn); 564 break; 565 566 case SIM_ARM_FP0_REGNUM: 567 case SIM_ARM_FP1_REGNUM: 568 case SIM_ARM_FP2_REGNUM: 569 case SIM_ARM_FP3_REGNUM: 570 case SIM_ARM_FP4_REGNUM: 571 case SIM_ARM_FP5_REGNUM: 572 case SIM_ARM_FP6_REGNUM: 573 case SIM_ARM_FP7_REGNUM: 574 case SIM_ARM_FPS_REGNUM: 575 memset (memory, 0, length); 576 return 0; 577 578 case SIM_ARM_PS_REGNUM: 579 regval = ARMul_GetCPSR (state); 580 break; 581 582 case SIM_ARM_MAVERIC_COP0R0_REGNUM: 583 case SIM_ARM_MAVERIC_COP0R1_REGNUM: 584 case SIM_ARM_MAVERIC_COP0R2_REGNUM: 585 case SIM_ARM_MAVERIC_COP0R3_REGNUM: 586 case SIM_ARM_MAVERIC_COP0R4_REGNUM: 587 case SIM_ARM_MAVERIC_COP0R5_REGNUM: 588 case SIM_ARM_MAVERIC_COP0R6_REGNUM: 589 case SIM_ARM_MAVERIC_COP0R7_REGNUM: 590 case SIM_ARM_MAVERIC_COP0R8_REGNUM: 591 case SIM_ARM_MAVERIC_COP0R9_REGNUM: 592 case SIM_ARM_MAVERIC_COP0R10_REGNUM: 593 case SIM_ARM_MAVERIC_COP0R11_REGNUM: 594 case SIM_ARM_MAVERIC_COP0R12_REGNUM: 595 case SIM_ARM_MAVERIC_COP0R13_REGNUM: 596 case SIM_ARM_MAVERIC_COP0R14_REGNUM: 597 case SIM_ARM_MAVERIC_COP0R15_REGNUM: 598 memcpy (memory, & DSPregs [rn - SIM_ARM_MAVERIC_COP0R0_REGNUM], 599 sizeof (struct maverick_regs)); 600 return sizeof (struct maverick_regs); 601 602 case SIM_ARM_MAVERIC_DSPSC_REGNUM: 603 memcpy (memory, & DSPsc, sizeof DSPsc); 604 return sizeof DSPsc; 605 606 case SIM_ARM_IWMMXT_COP0R0_REGNUM: 607 case SIM_ARM_IWMMXT_COP0R1_REGNUM: 608 case SIM_ARM_IWMMXT_COP0R2_REGNUM: 609 case SIM_ARM_IWMMXT_COP0R3_REGNUM: 610 case SIM_ARM_IWMMXT_COP0R4_REGNUM: 611 case SIM_ARM_IWMMXT_COP0R5_REGNUM: 612 case SIM_ARM_IWMMXT_COP0R6_REGNUM: 613 case SIM_ARM_IWMMXT_COP0R7_REGNUM: 614 case SIM_ARM_IWMMXT_COP0R8_REGNUM: 615 case SIM_ARM_IWMMXT_COP0R9_REGNUM: 616 case SIM_ARM_IWMMXT_COP0R10_REGNUM: 617 case SIM_ARM_IWMMXT_COP0R11_REGNUM: 618 case SIM_ARM_IWMMXT_COP0R12_REGNUM: 619 case SIM_ARM_IWMMXT_COP0R13_REGNUM: 620 case SIM_ARM_IWMMXT_COP0R14_REGNUM: 621 case SIM_ARM_IWMMXT_COP0R15_REGNUM: 622 case SIM_ARM_IWMMXT_COP1R0_REGNUM: 623 case SIM_ARM_IWMMXT_COP1R1_REGNUM: 624 case SIM_ARM_IWMMXT_COP1R2_REGNUM: 625 case SIM_ARM_IWMMXT_COP1R3_REGNUM: 626 case SIM_ARM_IWMMXT_COP1R4_REGNUM: 627 case SIM_ARM_IWMMXT_COP1R5_REGNUM: 628 case SIM_ARM_IWMMXT_COP1R6_REGNUM: 629 case SIM_ARM_IWMMXT_COP1R7_REGNUM: 630 case SIM_ARM_IWMMXT_COP1R8_REGNUM: 631 case SIM_ARM_IWMMXT_COP1R9_REGNUM: 632 case SIM_ARM_IWMMXT_COP1R10_REGNUM: 633 case SIM_ARM_IWMMXT_COP1R11_REGNUM: 634 case SIM_ARM_IWMMXT_COP1R12_REGNUM: 635 case SIM_ARM_IWMMXT_COP1R13_REGNUM: 636 case SIM_ARM_IWMMXT_COP1R14_REGNUM: 637 case SIM_ARM_IWMMXT_COP1R15_REGNUM: 638 return Fetch_Iwmmxt_Register (rn - SIM_ARM_IWMMXT_COP0R0_REGNUM, memory); 639 640 default: 641 return 0; 642 } 643 644 while (len) 645 { 646 tomem (state, memory, regval); 647 648 len -= 4; 649 memory += 4; 650 regval = 0; 651 } 652 653 return length; 654} 655 656typedef struct 657{ 658 char * swi_option; 659 unsigned int swi_mask; 660} swi_options; 661 662#define SWI_SWITCH "--swi-support" 663 664static swi_options options[] = 665 { 666 { "none", 0 }, 667 { "demon", SWI_MASK_DEMON }, 668 { "angel", SWI_MASK_ANGEL }, 669 { "redboot", SWI_MASK_REDBOOT }, 670 { "all", -1 }, 671 { "NONE", 0 }, 672 { "DEMON", SWI_MASK_DEMON }, 673 { "ANGEL", SWI_MASK_ANGEL }, 674 { "REDBOOT", SWI_MASK_REDBOOT }, 675 { "ALL", -1 } 676 }; 677 678 679static int 680sim_target_parse_command_line (int argc, char ** argv) 681{ 682 int i; 683 684 for (i = 1; i < argc; i++) 685 { 686 char * ptr = argv[i]; 687 int arg; 688 689 if ((ptr == NULL) || (* ptr != '-')) 690 break; 691 692 if (strcmp (ptr, "-t") == 0) 693 { 694 trace = 1; 695 continue; 696 } 697 698 if (strcmp (ptr, "-z") == 0) 699 { 700 /* Remove this option from the argv array. */ 701 for (arg = i; arg < argc; arg ++) 702 { 703 free (argv[arg]); 704 argv[arg] = argv[arg + 1]; 705 } 706 argc --; 707 i --; 708 trace_funcs = 1; 709 continue; 710 } 711 712 if (strcmp (ptr, "-d") == 0) 713 { 714 /* Remove this option from the argv array. */ 715 for (arg = i; arg < argc; arg ++) 716 { 717 free (argv[arg]); 718 argv[arg] = argv[arg + 1]; 719 } 720 argc --; 721 i --; 722 disas = 1; 723 continue; 724 } 725 726 if (strncmp (ptr, SWI_SWITCH, sizeof SWI_SWITCH - 1) != 0) 727 continue; 728 729 if (ptr[sizeof SWI_SWITCH - 1] == 0) 730 { 731 /* Remove this option from the argv array. */ 732 for (arg = i; arg < argc; arg ++) 733 { 734 free (argv[arg]); 735 argv[arg] = argv[arg + 1]; 736 } 737 argc --; 738 739 ptr = argv[i]; 740 } 741 else 742 ptr += sizeof SWI_SWITCH; 743 744 swi_mask = 0; 745 746 while (* ptr) 747 { 748 int i; 749 750 for (i = ARRAY_SIZE (options); i--;) 751 if (strncmp (ptr, options[i].swi_option, 752 strlen (options[i].swi_option)) == 0) 753 { 754 swi_mask |= options[i].swi_mask; 755 ptr += strlen (options[i].swi_option); 756 757 if (* ptr == ',') 758 ++ ptr; 759 760 break; 761 } 762 763 if (i < 0) 764 break; 765 } 766 767 if (* ptr != 0) 768 fprintf (stderr, "Ignoring swi options: %s\n", ptr); 769 770 /* Remove this option from the argv array. */ 771 for (arg = i; arg < argc; arg ++) 772 { 773 free (argv[arg]); 774 argv[arg] = argv[arg + 1]; 775 } 776 argc --; 777 i --; 778 } 779 return argc; 780} 781 782static void 783sim_target_parse_arg_array (char ** argv) 784{ 785 sim_target_parse_command_line (countargv (argv), argv); 786} 787 788static sim_cia 789arm_pc_get (sim_cpu *cpu) 790{ 791 return PC; 792} 793 794static void 795arm_pc_set (sim_cpu *cpu, sim_cia pc) 796{ 797 ARMul_SetPC (state, pc); 798} 799 800static void 801free_state (SIM_DESC sd) 802{ 803 if (STATE_MODULES (sd) != NULL) 804 sim_module_uninstall (sd); 805 sim_cpu_free_all (sd); 806 sim_state_free (sd); 807} 808 809SIM_DESC 810sim_open (SIM_OPEN_KIND kind, 811 host_callback *cb, 812 struct bfd *abfd, 813 char * const *argv) 814{ 815 int i; 816 char **argv_copy; 817 SIM_DESC sd = sim_state_alloc (kind, cb); 818 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 819 820 /* Set default options before parsing user options. */ 821 current_alignment = STRICT_ALIGNMENT; 822 823 /* The cpu data is kept in a separately allocated chunk of memory. */ 824 if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK) 825 { 826 free_state (sd); 827 return 0; 828 } 829 830 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) 831 { 832 free_state (sd); 833 return 0; 834 } 835 836 /* The parser will print an error message for us, so we silently return. */ 837 if (sim_parse_args (sd, argv) != SIM_RC_OK) 838 { 839 free_state (sd); 840 return 0; 841 } 842 843 /* Check for/establish the a reference program image. */ 844 if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK) 845 { 846 free_state (sd); 847 return 0; 848 } 849 850 /* Configure/verify the target byte order and other runtime 851 configuration options. */ 852 if (sim_config (sd) != SIM_RC_OK) 853 { 854 sim_module_uninstall (sd); 855 return 0; 856 } 857 858 if (sim_post_argv_init (sd) != SIM_RC_OK) 859 { 860 /* Uninstall the modules to avoid memory leaks, 861 file descriptor leaks, etc. */ 862 sim_module_uninstall (sd); 863 return 0; 864 } 865 866 /* CPU specific initialization. */ 867 for (i = 0; i < MAX_NR_PROCESSORS; ++i) 868 { 869 SIM_CPU *cpu = STATE_CPU (sd, i); 870 871 CPU_REG_FETCH (cpu) = arm_reg_fetch; 872 CPU_REG_STORE (cpu) = arm_reg_store; 873 CPU_PC_FETCH (cpu) = arm_pc_get; 874 CPU_PC_STORE (cpu) = arm_pc_set; 875 } 876 877 sim_callback = cb; 878 879 /* Copy over the argv contents so we can modify them. */ 880 argv_copy = dupargv (argv); 881 882 sim_target_parse_arg_array (argv_copy); 883 884 if (argv_copy[1] != NULL) 885 { 886 int i; 887 888 /* Scan for memory-size switches. */ 889 for (i = 0; (argv_copy[i] != NULL) && (argv_copy[i][0] != 0); i++) 890 if (argv_copy[i][0] == '-' && argv_copy[i][1] == 'm') 891 { 892 if (argv_copy[i][2] != '\0') 893 mem_size = atoi (&argv_copy[i][2]); 894 else if (argv_copy[i + 1] != NULL) 895 { 896 mem_size = atoi (argv_copy[i + 1]); 897 i++; 898 } 899 else 900 { 901 sim_callback->printf_filtered (sim_callback, 902 "Missing argument to -m option\n"); 903 return NULL; 904 } 905 } 906 } 907 908 freeargv (argv_copy); 909 910 return sd; 911} 912 913void 914sim_stop_reason (SIM_DESC sd ATTRIBUTE_UNUSED, 915 enum sim_stop *reason, 916 int *sigrc) 917{ 918 if (stop_simulator) 919 { 920 *reason = sim_stopped; 921 *sigrc = GDB_SIGNAL_INT; 922 } 923 else if (state->EndCondition == 0) 924 { 925 *reason = sim_exited; 926 *sigrc = state->Reg[0] & 255; 927 } 928 else 929 { 930 *reason = sim_stopped; 931 if (state->EndCondition == RDIError_BreakpointReached) 932 *sigrc = GDB_SIGNAL_TRAP; 933 else if ( state->EndCondition == RDIError_DataAbort 934 || state->EndCondition == RDIError_AddressException) 935 *sigrc = GDB_SIGNAL_BUS; 936 else 937 *sigrc = 0; 938 } 939} 940