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