X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Fmips%2Finterp.c;h=9dbac8c58fc76f8a3e54c9819037c25bc0a495b6;hb=41792d688a5a1f158d6e9ecda2b603ae122d69a1;hp=8a584d3cd244f2e3bd51489b0fc78bc807a0180e;hpb=6e4f085c7f459e0777a71bcb61ed3aa8257fa386;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/mips/interp.c b/sim/mips/interp.c index 8a584d3cd2..9dbac8c58f 100644 --- a/sim/mips/interp.c +++ b/sim/mips/interp.c @@ -55,6 +55,7 @@ code on the hardware. #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 */ @@ -342,8 +343,12 @@ mips_pc_set (sim_cpu *cpu, sim_cia pc) 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); @@ -373,9 +378,7 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv) 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, @@ -399,9 +402,6 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv) /* 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 @@ -806,6 +806,8 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv) { 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; } @@ -843,68 +845,11 @@ mips_sim_close (SIM_DESC sd, int quitting) #endif } -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) +static int +mips_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length) { - 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) -{ - 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 @@ -912,12 +857,10 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length) 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; @@ -981,26 +924,18 @@ sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length) 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) { @@ -1066,7 +1001,8 @@ sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length) } 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 @@ -1085,7 +1021,17 @@ sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env) 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); } } @@ -1494,26 +1440,21 @@ store_word (SIM_DESC sd, 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); } } @@ -1531,24 +1472,18 @@ load_word (SIM_DESC sd, } 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;