#include "getopt.h"
#include "libiberty.h"
#include "bfd.h"
+#include "elf-bfd.h"
#include "gdb/callback.h" /* GDB simulator callback interface */
#include "gdb/remote-sim.h" /* GDB simulator interface */
PC = pc;
}
+static int mips_reg_fetch (SIM_CPU *, int, unsigned char *, int);
+static int mips_reg_store (SIM_CPU *, int, unsigned char *, int);
+
SIM_DESC
-sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
+sim_open (SIM_OPEN_KIND kind, host_callback *cb,
+ struct bfd *abfd, char * const *argv)
{
int i;
SIM_DESC sd = sim_state_alloc (kind, cb);
sim_add_option_table (sd, NULL, mips_options);
- /* getopt will print the error message so we just have to exit if this fails.
- FIXME: Hmmm... in the case of gdb we need getopt to call
- print_filtered. */
+ /* The parser will print an error message for us, so we silently return. */
if (sim_parse_args (sd, argv) != SIM_RC_OK)
{
/* Uninstall the modules to avoid memory leaks,
/* Look for largest memory region defined on command-line at
phys address 0. */
-#ifdef SIM_HAVE_FLATMEM
- mem_size = STATE_MEM_SIZE (sd);
-#endif
for (entry = STATE_MEMOPT (sd); entry != NULL; entry = entry->next)
{
/* If we find an entry at address 0, then we will end up
{
SIM_CPU *cpu = STATE_CPU (sd, i);
+ CPU_REG_FETCH (cpu) = mips_reg_fetch;
+ CPU_REG_STORE (cpu) = mips_reg_store;
CPU_PC_FETCH (cpu) = mips_pc_get;
CPU_PC_STORE (cpu) = mips_pc_set;
}
}
void
-sim_close (SIM_DESC sd, int quitting)
+mips_sim_close (SIM_DESC sd, int quitting)
{
-#ifdef DEBUG
- printf("DBG: sim_close: entered (quitting = %d)\n",quitting);
-#endif
-
-
- /* "quitting" is non-zero if we cannot hang on errors */
-
- /* shut down modules */
- sim_module_uninstall (sd);
-
- /* Ensure that any resources allocated through the callback
- mechanism are released: */
- sim_io_shutdown (sd);
-
#if WITH_TRACE_ANY_P
if (tracefh != NULL && tracefh != stderr)
fclose(tracefh);
tracefh = NULL;
#endif
-
- /* FIXME - free SD */
-
- return;
-}
-
-
-int
-sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size)
-{
- int index;
- sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
-
- /* Return the number of bytes written, or zero if error. */
-#ifdef DEBUG
- sim_io_printf(sd,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr),size);
-#endif
-
- /* We use raw read and write routines, since we do not want to count
- the GDB memory accesses in our statistics gathering. */
-
- for (index = 0; index < size; index++)
- {
- address_word vaddr = (address_word)addr + index;
- address_word paddr;
- int cca;
- if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isSTORE, &paddr, &cca, isRAW))
- break;
- if (sim_core_write_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1)
- break;
- }
-
- return(index);
-}
-
-int
-sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
-{
- int index;
- sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
-
- /* Return the number of bytes read, or zero if error. */
-#ifdef DEBUG
- sim_io_printf(sd,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr),size);
-#endif /* DEBUG */
-
- for (index = 0; (index < size); index++)
- {
- address_word vaddr = (address_word)addr + index;
- address_word paddr;
- int cca;
- if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isLOAD, &paddr, &cca, isRAW))
- break;
- if (sim_core_read_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1)
- break;
- }
-
- return(index);
}
-int
-sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
+static int
+mips_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
{
- sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
/* NOTE: gdb (the client) stores registers in target byte order
while the simulator uses host byte order */
-#ifdef DEBUG
- sim_io_printf(sd,"sim_store_register(%d,*memory=0x%s);\n",rn,pr_addr(*((SIM_ADDR *)memory)));
-#endif /* DEBUG */
/* Unfortunately this suffers from the same problem as the register
numbering one. We need to know what the width of each logical
if (cpu->register_widths[rn] == 0)
{
- sim_io_eprintf(sd,"Invalid register width for %d (register store ignored)\n",rn);
+ sim_io_eprintf (CPU_STATE (cpu), "Invalid register width for %d (register store ignored)\n", rn);
return 0;
}
-
-
if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
{
cpu->fpr_state[rn - FGR_BASE] = fmt_uninterpreted;
return 0;
}
-int
-sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
+static int
+mips_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
{
- sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
/* NOTE: gdb (the client) stores registers in target byte order
while the simulator uses host byte order */
-#ifdef DEBUG
-#if 0 /* FIXME: doesn't compile */
- sim_io_printf(sd,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn,pr_addr(registers[rn]));
-#endif
-#endif /* DEBUG */
if (cpu->register_widths[rn] == 0)
{
- sim_io_eprintf (sd, "Invalid register width for %d (register fetch ignored)\n",rn);
+ sim_io_eprintf (CPU_STATE (cpu), "Invalid register width for %d (register fetch ignored)\n", rn);
return 0;
}
-
-
/* Any floating point register */
if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
{
}
SIM_RC
-sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
+sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
+ char * const *argv, char * const *env)
{
#ifdef DEBUG
for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
{
sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
- CPU_PC_SET (cpu, (unsigned64) bfd_get_start_address (abfd));
+ sim_cia pc = bfd_get_start_address (abfd);
+
+ /* We need to undo brain-dead bfd behavior where it sign-extends
+ addresses that are supposed to be unsigned. See the mips bfd
+ sign_extend_vma setting. We have to check the ELF data itself
+ in order to handle o32 & n32 ABIs. */
+ if (abfd->tdata.elf_obj_data->elf_header->e_ident[EI_CLASS] ==
+ ELFCLASS32)
+ pc = (unsigned32) pc;
+
+ CPU_PC_SET (cpu, pc);
}
}
uword64 vaddr,
signed_word val)
{
- address_word paddr;
- int uncached;
+ address_word paddr = vaddr;
if ((vaddr & 3) != 0)
SignalExceptionAddressStore ();
else
{
- if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
- isTARGET, isREAL))
- {
- const uword64 mask = 7;
- uword64 memval;
- unsigned int byte;
-
- paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2));
- byte = (vaddr & mask) ^ (BigEndianCPU << 2);
- memval = ((uword64) val) << (8 * byte);
- StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr,
- isREAL);
- }
+ const uword64 mask = 7;
+ uword64 memval;
+ unsigned int byte;
+
+ paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2));
+ byte = (vaddr & mask) ^ (BigEndianCPU << 2);
+ memval = ((uword64) val) << (8 * byte);
+ StoreMemory (AccessLength_WORD, memval, 0, paddr, vaddr,
+ isREAL);
}
}
}
else
{
- address_word paddr;
- int uncached;
-
- if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
- isTARGET, isREAL))
- {
- const uword64 mask = 0x7;
- const unsigned int reverse = ReverseEndian ? 1 : 0;
- const unsigned int bigend = BigEndianCPU ? 1 : 0;
- uword64 memval;
- unsigned int byte;
-
- paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2));
- LoadMemory (&memval,NULL,uncached, AccessLength_WORD, paddr, vaddr,
- isDATA, isREAL);
- byte = (vaddr & mask) ^ (bigend << 2);
- return EXTEND32 (memval >> (8 * byte));
- }
+ address_word paddr = vaddr;
+ const uword64 mask = 0x7;
+ const unsigned int reverse = ReverseEndian ? 1 : 0;
+ const unsigned int bigend = BigEndianCPU ? 1 : 0;
+ uword64 memval;
+ unsigned int byte;
+
+ paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2));
+ LoadMemory (&memval, NULL, AccessLength_WORD, paddr, vaddr, isDATA,
+ isREAL);
+ byte = (vaddr & mask) ^ (bigend << 2);
+ return EXTEND32 (memval >> (8 * byte));
}
return 0;