Fix the detection of illegal memory accesses in the MSP430 simulator.

* msp430-sim.c (sim_open): Allocate memory regions matching those
	declared in the libgloss/msp430 linker scripts.
	Allow sim_load_file to fail.
	(get_op): Test the correct address bit when checking for out of
	range addresses.
	Include the address in the error message when an illegal access to
	the hardware multiplier is detected.
	(put_op): Test the correct address bit when checking for out of
	range addresses.
This commit is contained in:
Nick Clifton 2015-02-24 10:27:07 +00:00
parent 3ad797fd08
commit 10d602c7f9
2 changed files with 67 additions and 34 deletions

View file

@ -1,3 +1,15 @@
2015-02-24 Nick Clifton <nickc@redhat.com>
* msp430-sim.c (sim_open): Allocate memory regions matching those
declared in the libgloss/msp430 linker scripts.
Allow sim_load_file to fail.
(get_op): Test the correct address bit when checking for out of
range addresses.
Include the address in the error message when an illegal access to
the hardware multiplier is detected.
(put_op): Test the correct address bit when checking for out of
range addresses.
2014-08-19 Alan Modra <amodra@gmail.com>
* configure: Regenerate.

View file

@ -174,15 +174,18 @@ sim_open (SIM_OPEN_KIND kind,
CPU_REG_FETCH (MSP430_CPU (sd)) = msp430_reg_fetch;
CPU_REG_STORE (MSP430_CPU (sd)) = msp430_reg_store;
/* Allocate memory if none specified by user. */
if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x130, 1) == 0)
sim_do_commandf (sd, "memory-region 0,0x20");
/* Allocate memory if none specified by user.
Note - these values match the memory regions in the libgloss/msp430/msp430[xl]-sim.ld scripts. */
if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x2, 1) == 0)
sim_do_commandf (sd, "memory-region 0,0x20"); /* Needed by the GDB testsuite. */
if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x200, 1) == 0)
sim_do_commandf (sd, "memory-region 0x200,0xffe00");
sim_do_commandf (sd, "memory-region 0x200,0xfd00"); /* RAM and/or ROM */
if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0xfffe, 1) == 0)
sim_do_commandf (sd, "memory-region 0xfffe,2");
sim_do_commandf (sd, "memory-region 0xffc0,0x40"); /* VECTORS. */
if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x10000, 1) == 0)
sim_do_commandf (sd, "memory-region 0x10000,0x100000");
sim_do_commandf (sd, "memory-region 0x10000,0x80000"); /* HIGH FLASH RAM. */
if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x90000, 1) == 0)
sim_do_commandf (sd, "memory-region 0x90000,0x70000"); /* HIGH ROM. */
/* Check for/establish the a reference program image. */
if (sim_analyze_program (sd,
@ -200,11 +203,7 @@ sim_open (SIM_OPEN_KIND kind,
0 /* verbose */,
1 /* use LMA instead of VMA */,
loader_write_mem);
if (prog_bfd == NULL)
{
sim_state_free (sd);
return 0;
}
/* Allow prog_bfd to be NULL - this is needed by the GDB testsuite. */
/* Establish any remaining configuration options. */
if (sim_config (sd) != SIM_RC_OK)
@ -225,10 +224,13 @@ sim_open (SIM_OPEN_KIND kind,
msp430_trace_init (STATE_PROG_BFD (sd));
MSP430_CPU (sd)->state.cio_breakpoint = lookup_symbol (sd, "C$$IO$$");
MSP430_CPU (sd)->state.cio_buffer = lookup_symbol (sd, "__CIOBUF__");
if (MSP430_CPU (sd)->state.cio_buffer == -1)
MSP430_CPU (sd)->state.cio_buffer = lookup_symbol (sd, "_CIOBUF_");
if (prog_bfd != NULL)
{
MSP430_CPU (sd)->state.cio_breakpoint = lookup_symbol (sd, "C$$IO$$");
MSP430_CPU (sd)->state.cio_buffer = lookup_symbol (sd, "__CIOBUF__");
if (MSP430_CPU (sd)->state.cio_buffer == -1)
MSP430_CPU (sd)->state.cio_buffer = lookup_symbol (sd, "_CIOBUF_");
}
return sd;
}
@ -360,16 +362,25 @@ get_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n)
addr = op->addend;
if (op->reg != MSR_None)
{
int reg;
/* Index values are signed, but the sum is limited to 16
bits if the register < 64k, for MSP430 compatibility in
MSP430X chips. */
if (addr & 0x8000)
addr |= -1 << 16;
reg = REG_GET (op->reg);
int reg = REG_GET (op->reg);
int sign = opc->ofs_430x ? 20 : 16;
/* Index values are signed. */
if (addr & (1 << (sign - 1)))
addr |= -1 << sign;
addr += reg;
/* For MSP430 instructions the sum is limited to 16 bits if the
address in the index register is less than 64k even if we are
running on an MSP430X CPU. This is for MSP430 compatibility. */
if (reg < 0x10000 && ! opc->ofs_430x)
addr &= 0xffff;
{
if (addr >= 0x10000)
fprintf (stderr, " XXX WRAPPING ADDRESS %x on read\n", addr);
addr &= 0xffff;
}
}
addr &= 0xfffff;
switch (opc->size)
@ -407,7 +418,7 @@ get_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n)
case UNSIGN_32:
rv = zero_ext (HWMULT (sd, hwmult_result), 16);
break;
case SIGN_MAC_32:
case SIGN_MAC_32:
case SIGN_32:
rv = sign_ext (HWMULT (sd, hwmult_signed_result), 16);
break;
@ -468,7 +479,7 @@ get_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n)
break;
default:
fprintf (stderr, "unimplemented HW MULT read!\n");
fprintf (stderr, "unimplemented HW MULT read from %x!\n", addr);
break;
}
}
@ -477,6 +488,7 @@ get_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n)
trace_generic (sd, MSP430_CPU (sd), TRACE_MEMORY_IDX,
"GET: [%#x].%d -> %#x", addr, opc->size, rv);
break;
default:
fprintf (stderr, "invalid operand %d type %d\n", n, op->type);
abort ();
@ -544,16 +556,25 @@ put_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n, int val)
addr = op->addend;
if (op->reg != MSR_None)
{
int reg;
/* Index values are signed, but the sum is limited to 16
bits if the register < 64k, for MSP430 compatibility in
MSP430X chips. */
if (addr & 0x8000)
addr |= -1 << 16;
reg = REG_GET (op->reg);
int reg = REG_GET (op->reg);
int sign = opc->ofs_430x ? 20 : 16;
/* Index values are signed. */
if (addr & (1 << (sign - 1)))
addr |= -1 << sign;
addr += reg;
if (reg < 0x10000)
addr &= 0xffff;
/* For MSP430 instructions the sum is limited to 16 bits if the
address in the index register is less than 64k even if we are
running on an MSP430X CPU. This is for MSP430 compatibility. */
if (reg < 0x10000 && ! opc->ofs_430x)
{
if (addr >= 0x10000)
fprintf (stderr, " XXX WRAPPING ADDRESS %x on write\n", addr);
addr &= 0xffff;
}
}
addr &= 0xfffff;