X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Fmips%2Finterp.c;h=9dbac8c58fc76f8a3e54c9819037c25bc0a495b6;hb=a78a19b15254de31c3d38b7e27469aaef0a30e97;hp=0ca6f1aef205646591080463865e18af7342ff25;hpb=26f8bf63bf36f9062a5cc1afacf71462a4abe0c8;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/mips/interp.c b/sim/mips/interp.c index 0ca6f1aef2..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, @@ -803,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; } @@ -840,15 +845,11 @@ mips_sim_close (SIM_DESC sd, int quitting) #endif } -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 @@ -856,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; @@ -925,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) { @@ -1010,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 @@ -1029,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); } }