sim: mips: workaround 32-bit addr sign extensions

The mips bfd will sign extend 32-bit addresses into 64-bit values,
so if the entry happens to be 0x80000000 or higher, it is turned to
0xffffffff80000000 which points to memory that doesn't exist.

This wasn't an issue until commit 26f8bf63bf
as all addresses were automatically truncated there in the translate
function to 32-bits.  When we cleaned up that code, the full 64-bits
were checked leading to many test failures for mips-sde-elf targets
and such.
This commit is contained in:
Mike Frysinger 2016-01-12 01:39:47 -05:00
parent 4d625b70fc
commit b36d953bce
2 changed files with 18 additions and 1 deletions

View File

@ -1,3 +1,9 @@
2016-01-12 Mike Frysinger <vapier@gentoo.org>
* interp.c: Include elf-bfd.h.
(sim_create_inferior): Truncate pc to 32-bits when EI_CLASS is
ELFCLASS32.
2016-01-10 Mike Frysinger <vapier@gentoo.org>
* config.in, configure: Regenerate.

View File

@ -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 */
@ -1020,7 +1021,17 @@ sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
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);
}
}