def setUp(self):
self.server = target.server()
self.gdb = testlib.Gdb()
+ # For now gdb has to be told what the architecture is when it's not
+ # given an ELF file.
+ self.gdb.command("set arch riscv:rv%d" % target.xlen)
+
self.gdb.command("target extended-remote localhost:%d" % self.server.port)
# 0x13 is nop
def setUp(self):
self.server = target.server()
self.gdb = testlib.Gdb()
+ self.gdb.command("set arch riscv:rv%d" % target.xlen)
self.gdb.command("target extended-remote localhost:%d" % self.server.port)
def access_test(self, size, data_type):
+ self.assertEqual(self.gdb.p("sizeof(%s)" % data_type),
+ size)
a = 0x86753095555aaaa & ((1<<(size*8))-1)
b = 0xdeadbeef12345678 & ((1<<(size*8))-1)
self.gdb.p("*((%s*)0x%x) = 0x%x" % (data_type, target.ram, a))
self.access_test(2, 'short')
def test_32(self):
- self.access_test(4, 'long')
+ self.access_test(4, 'int')
def test_64(self):
self.access_test(8, 'long long')
def setUp(self):
self.server = target.server()
self.gdb = testlib.Gdb()
+ self.gdb.command("set arch riscv:rv%d" % target.xlen)
self.gdb.command("target extended-remote localhost:%d" % self.server.port)
def test_instant_halt(self):
class DebugTest(DeleteServer):
def setUp(self):
- self.binary = target.compile("programs/debug.c", "programs/checksum.c")
+ # Include malloc so that gdb can make function calls. I suspect this
+ # malloc will silently blow through the memory set aside for it, so be
+ # careful.
+ self.binary = target.compile("programs/debug.c", "programs/checksum.c",
+ "programs/tiny-malloc.c", "-DDEFINE_MALLOC", "-DDEFINE_FREE")
self.server = target.server()
self.gdb = testlib.Gdb()
self.gdb.command("file %s" % self.binary)
self.gdb.load()
self.gdb.b("_exit")
- def exit(self):
+ def exit(self, expected_result = 0xc86455d4):
output = self.gdb.c()
self.assertIn("Breakpoint", output)
- #TODO self.assertIn("_exit", output)
- #TODO self.assertEqual(self.gdb.p("status"), 0xc86455d4)
- # Use a0 until gdb can resolve "status"
- self.assertEqual(self.gdb.p("$a0") & 0xffffffff, 0xc86455d4)
+ self.assertIn("_exit", output)
+ self.assertEqual(self.gdb.p("status"), expected_result)
+
+ def test_function_call(self):
+ self.gdb.b("main:start")
+ self.gdb.c()
+ text = "Howdy, Earth!"
+ gdb_length = self.gdb.p('strlen("%s")' % text)
+ self.assertEqual(gdb_length, len(text))
+ self.exit()
+
+ def test_change_string(self):
+ text = "This little piggy went to the market."
+ self.gdb.b("main:start")
+ self.gdb.c()
+ self.gdb.p('fox = "%s"' % text)
+ self.exit(0x43b497b8)
def test_turbostep(self):
"""Single step a bunch of times."""
self.exit()
def test_hwbp_1(self):
+ if target.instruction_hardware_breakpoint_count < 1:
+ return
+
self.gdb.hbreak("rot13")
# The breakpoint should be hit exactly 2 times.
for i in range(2):
self.exit()
def test_hwbp_2(self):
+ if target.instruction_hardware_breakpoint_count < 2:
+ return
+
self.gdb.hbreak("main")
self.gdb.hbreak("rot13")
# We should hit 3 breakpoints.
output = self.gdb.c()
self.assertIn("Cannot insert hardware breakpoint", output)
+ # Clean up, otherwise the hardware breakpoints stay set and future
+ # tests may fail.
+ self.gdb.command("D")
def test_registers(self):
# Get to a point in the code where some registers have actually been
def test_step(self):
main = self.gdb.p("$pc")
- for expected in (4, 0xc, 0x10, 0x18, 0x14, 0x14):
+ for expected in (4, 8, 0xc, 0x10, 0x18, 0x1c, 0x28, 0x20, 0x2c, 0x2c):
self.gdb.stepi()
pc = self.gdb.p("$pc")
- self.assertEqual(pc - main, expected)
+ self.assertEqual("%x" % pc, "%x" % (expected + main))
class RegsTest(DeleteServer):
def setUp(self):
class DownloadTest(DeleteServer):
def setUp(self):
- length = 2**20
+ length = min(2**20, target.ram_size - 2048)
fd = file("download.c", "w")
fd.write("#include <stdint.h>\n")
fd.write("unsigned int crc32a(uint8_t *message, unsigned int size);\n")
def test_mprv(self):
"""Test that the debugger can access memory when MPRV is set."""
self.gdb.c(wait=False)
+ time.sleep(0.5)
self.gdb.interrupt()
output = self.gdb.command("p/x *(int*)(((char*)&data)-0x80000000)")
self.assertIn("0xbead", output)
name = "spike"
xlen = 64
ram = 0x80010000
+ ram_size = 5 * 1024 * 1024
+ instruction_hardware_breakpoint_count = 0
def server(self):
return testlib.Spike(parsed.cmd, halted=True)
directory = "spike"
xlen = 32
ram = 0x80010000
+ ram_size = 5 * 1024 * 1024
+ instruction_hardware_breakpoint_count = 0
def server(self):
return testlib.Spike(parsed.cmd, halted=True, xlen=32)
name = "m2gl_m2s"
xlen = 32
ram = 0x80000000
+ ram_size = 16 * 1024
+ instruction_hardware_breakpoint_count = 2
def server(self):
return testlib.Openocd(cmd=parsed.cmd,