def test(self): self.gdb.command("rwatch *((&data)+1)") output = self.gdb.c() assertIn("read_loop", output) assertEqual(self.gdb.p("$a0"), self.gdb.p("(&data)+1")) self.exit()
def test(self): self.gdb.b("main") output = self.gdb.c() assertIn(" main ", output) self.gdb.b("trap_entry") output = self.gdb.c() assertIn(" trap_entry ", output) assertEqual(self.gdb.p("$mip") & 0x80, 0x80) assertEqual(self.gdb.p("interrupt_count"), 0) # You'd expect local to still be 0, but it looks like spike doesn't # jump to the interrupt handler immediately after the write to # mtimecmp. assertLess(self.gdb.p("local"), 1000) self.gdb.command("delete breakpoints") for _ in range(10): self.gdb.c(wait=False) time.sleep(2) self.gdb.interrupt() interrupt_count = self.gdb.p("interrupt_count") local = self.gdb.p("local") if interrupt_count > 1000 and \ local > 1000: return assertGreater(interrupt_count, 1000) assertGreater(local, 1000)
def exit(self, expected_result=10): self.gdb.command("delete") self.gdb.b("_exit") output = self.gdb.c() assertIn("Breakpoint", output) assertIn("_exit", output) assertEqual(self.gdb.p("status"), expected_result)
def test(self): # Get to a point in the code where some registers have actually been # used. self.gdb.b("rot13") self.gdb.c() self.gdb.c() # Try both forms to test gdb. for cmd in ("info all-registers", "info registers all"): output = self.gdb.command(cmd) for reg in ('zero', 'ra', 'sp', 'gp', 'tp'): assertIn(reg, output) #TODO # mcpuid is one of the few registers that should have the high bit set # (for rv64). # Leave this commented out until gdb and spike agree on the encoding of # mcpuid (which is going to be renamed to misa in any case). #assertRegexpMatches(output, ".*mcpuid *0x80") #TODO: # The instret register should always be changing. #last_instret = None #for _ in range(5): # instret = self.gdb.p("$instret") # assertNotEqual(instret, last_instret) # last_instret = instret # self.gdb.stepi() self.exit()
def test(self): self.gdb.b("main") self.gdb.b("rot13") output = self.gdb.c() assertIn(", main ", output) output = self.gdb.c() assertIn(", rot13 ", output)
def test(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)") assertIn("0xbead", output)
def test(self): self.gdb.command("watch *((&data)+3)") output = self.gdb.c() assertIn("write_loop", output) assertEqual(self.gdb.p("$a0"), self.gdb.p("(&data)+3")) self.exit()
def setup(self): self.gdb.load() main_bp = self.gdb.b("main") output = self.gdb.c() assertIn("Breakpoint ", output) assertIn("main", output) self.gdb.command("delete %d" % main_bp) self.gdb.b("handle_trap")
def test(self): """Test reading/writing priv.""" for privilege in range(4): self.gdb.p("$priv=%d" % privilege) self.gdb.stepi() actual = self.gdb.p("$priv") assertIn(actual, self.supported) if privilege in self.supported: assertEqual(actual, privilege)
def run(self): for i in range(30): self.gdb.hbreak("*rot13 + %d" % (i * 4)) output = self.gdb.c() 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(self): bp = self.gdb.b("main") output = self.gdb.c() assertIn(", main ", output) self.gdb.command("delete %d" % bp) bp = self.gdb.b("rot13") output = self.gdb.c() assertIn(", rot13 ", output) self.gdb.command("delete %d" % bp)
def test(self): self.gdb.b("rot13") # The breakpoint should be hit exactly 2 times. for _ in range(2): output = self.gdb.c() self.gdb.p("$pc") assertIn("Breakpoint ", output) assertIn("rot13 ", output) self.exit()
def test(self): self.gdb.command("b just_before_read_loop") self.gdb.c() read_loop = self.gdb.p("&read_loop") self.gdb.command("rwatch data") self.gdb.c() # Accept hitting the breakpoint before or after the load instruction. assertIn(self.gdb.p("$pc"), [read_loop, read_loop + 4]) assertEqual(self.gdb.p("$a0"), self.gdb.p("&data"))
def test(self): for i in range(30): self.gdb.hbreak("*rot13 + %d" % (i * 4)) output = self.gdb.c(checkOutput=False) 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(self): self.write_nops(4) regs = self.cli.reg() assertIn("x18", regs) self.cli.command("reg x18 0x11782") self.cli.command("step 0x%x" % self.target.ram) assertEqual(self.cli.reg("x18"), 0x11782)
def test(self): self.gdb.command("hbreak write_load_trigger") self.gdb.b("clear_triggers") self.gdb.p("$pc=write_store_trigger") output = self.gdb.c() assertIn("write_load_trigger", output) self.check_triggers((1 << 6) | (1 << 1), 0xdeadbee0) output = self.gdb.c() assertIn("clear_triggers", output) self.check_triggers((1 << 6) | (1 << 0), 0xfeedac00)
def test_translation(self): self.gdb.b("error") self.gdb.b("handle_trap") self.gdb.b("main:active") output = self.gdb.c() assertIn(" main ", output) assertEqual(0xdeadbeef, self.gdb.p("physical[0]")) assertEqual(0x55667788, self.gdb.p("physical[1]")) assertEqual(0xdeadbeef, self.gdb.p("virtual[0]")) assertEqual(0x55667788, self.gdb.p("virtual[1]"))
def setup(self): # TODO: If we use a random hart, then we get into trouble because # gdb_read_memory_packet() ignores which hart is currently selected, so # we end up reading satp from hart 0 when the address translation might # be set up on hart 1 only. self.gdb.select_hart(self.target.harts[0]) self.gdb.load() self.gdb.b("main") output = self.gdb.c() assertIn(" main ", output)
def test(self): self.gdb.command("hbreak write_load_trigger") self.gdb.b("clear_triggers") self.gdb.p("$pc=write_store_trigger") output = self.gdb.c() assertIn("write_load_trigger", output) self.check_triggers((1<<6) | (1<<1), 0xdeadbee0) output = self.gdb.c() assertIn("clear_triggers", output) self.check_triggers((1<<6) | (1<<0), 0xfeedac00)
def test(self): """Test a store address breakpoint on the first instruction executed out of debug mode.""" self.gdb.command("b just_before_write_loop") self.gdb.c() write_loop = self.gdb.p("&write_loop") self.gdb.command("watch data") self.gdb.c() # Accept hitting the breakpoint before or after the store instruction. assertIn(self.gdb.p("$pc"), [write_loop, write_loop + 4]) assertEqual(self.gdb.p("$a0"), self.gdb.p("&data"))
def test(self): """Test reading/writing priv.""" # Leave the PC at _start, where the first 4 instructions should be # legal in any mode. for privilege in range(4): self.gdb.p("$priv=%d" % privilege) self.gdb.stepi() actual = self.gdb.p("$priv") assertIn(actual, self.supported) if privilege in self.supported: assertEqual(actual, privilege)
def test(self): if self.target.instruction_hardware_breakpoint_count < 1: return 'not_applicable' self.gdb.hbreak("rot13") # The breakpoint should be hit exactly 2 times. for _ in range(2): output = self.gdb.c() self.gdb.p("$pc") assertRegexpMatches(output, r"[bB]reakpoint") assertIn("rot13 ", output) self.exit()
def test(self): """Sending gdb ^C while the program is running should cause it to halt.""" temp = tempfile.NamedTemporaryFile(suffix=".data") self.gdb.b("main:begin") self.gdb.c() self.gdb.p('filename="%s"' % temp.name) self.exit() contents = open(temp.name, "r").readlines() assertIn("Hello, world!\n", contents)
def test(self): if self.target.instruction_hardware_breakpoint_count < 2: return 'not_applicable' self.gdb.hbreak("main") self.gdb.hbreak("rot13") # We should hit 3 breakpoints. for expected in ("main", "rot13", "rot13"): output = self.gdb.c() self.gdb.p("$pc") assertRegexpMatches(output, r"[bB]reakpoint") assertIn("%s " % expected, output) self.exit()
def test(self): """Assert that reset is really resetting what it should.""" self.gdb.command("monitor reset halt") self.gdb.command("flushregs") threads = self.gdb.threads() pcs = [] for t in threads: self.gdb.thread(t) pcs.append(self.gdb.p("$pc")) for pc in pcs: assertIn(pc, self.hart.reset_vectors) # mcycle and minstret have no defined reset value. mstatus = self.gdb.p("$mstatus") assertEqual(mstatus & (MSTATUS_MIE | MSTATUS_MPRV | MSTATUS_VM), 0)
def test(self): for i in range(30): self.gdb.hbreak("*rot13 + %d" % (i * 4)) output = self.gdb.c(checkOutput=False) assertIn("Cannot insert hardware breakpoint", output) # There used to be a bug where this would fail if done twice in a row. output = self.gdb.c(checkOutput=False) assertIn("Cannot insert hardware breakpoint", output) # Clean up, otherwise the hardware breakpoints stay set and future # tests may fail. self.gdb.command("delete") self.gdb.b("_exit") self.exit()
def test(self): if self.gdb.one_hart_per_gdb(): raise TestNotApplicable # Set breakpoint near '_start' label to increase the chances of a # situation when all harts hit breakpoint immediately and # simultaneously. self.gdb.b("set_trap_handler") # Check that all harts hit breakpoint one by one. for _ in range(len(self.target.harts)): output = self.gdb.c() assertIn("hit Breakpoint", output) assertIn("set_trap_handler", output) assertNotIn("received signal SIGTRAP", output)
def test(self): if self.gdb.one_hart_per_gdb(): return 'not_applicable' # Set breakpoint near '_start' label to increase the chances of a # situation when all harts hit breakpoint immediately and # simultaneously. self.gdb.b("set_trap_handler") # Check that all harts hit breakpoint one by one. for _ in range(len(self.target.harts)): output = self.gdb.c() assertIn("hit Breakpoint", output) assertIn("set_trap_handler", output) assertNotIn("received signal SIGTRAP", output)
def check_custom(self, magic): regs = {k: v for k, v in self.gdb.info_registers("all").iteritems() if k.startswith("custom")} assertEqual(set(regs.keys()), set(("custom1", "custom12345", "custom12346", "custom12347", "custom12348"))) for name, value in regs.iteritems(): number = int(name[6:]) if number % 2: expect = number + magic assertIn(value, (expect, expect + (1<<32))) else: assertIn("Could not fetch register", value)
def test(self): # If we want this test to run from flash, we can't have any software # breakpoints set. self.gdb.command("hbreak write_load_trigger") self.gdb.p("$pc=write_store_trigger") output = self.gdb.c() assertIn("write_load_trigger", output) self.check_triggers((1<<6) | (1<<1), 0xdeadbee0) self.gdb.command("delete") self.gdb.command("hbreak clear_triggers") output = self.gdb.c() assertIn("clear_triggers", output) self.check_triggers((1<<6) | (1<<0), 0xfeedac00) self.gdb.command("delete") self.exit()
def test(self): if self.hart.instruction_hardware_breakpoint_count < 2: raise TestNotApplicable self.gdb.command("delete") self.gdb.hbreak("main") self.gdb.hbreak("rot13") # We should hit 3 breakpoints. for expected in ("main", "rot13", "rot13"): output = self.gdb.c() self.gdb.p("$pc") assertRegexpMatches(output, r"[bB]reakpoint") assertIn("%s " % expected, output) self.gdb.command("delete") self.gdb.b("_exit") self.exit()
def test(self): # If we want this test to run from flash, we can't have any software # breakpoints set. self.gdb.command("hbreak write_load_trigger") self.gdb.p("$pc=write_store_trigger") output = self.gdb.c() assertIn("write_load_trigger", output) self.check_triggers((1 << 6) | (1 << 1), 0xdeadbee0) self.gdb.command("delete") self.gdb.command("hbreak clear_triggers") output = self.gdb.c() assertIn("clear_triggers", output) self.check_triggers((1 << 6) | (1 << 0), 0xfeedac00) self.gdb.command("delete") self.exit()
def test(self): regs = [("x%d" % n) for n in range(2, 32)] self.gdb.p("$pc=write_regs") for i, r in enumerate(regs): self.gdb.p("$%s=%d" % (r, (0xdeadbeef<<i)+17)) self.gdb.p("$x1=data") self.gdb.command("b all_done") output = self.gdb.c() assertIn("Breakpoint ", output) # Just to get this data in the log. self.gdb.command("x/30gx data") self.gdb.command("info registers") for n in range(len(regs)): assertEqual(self.gdb.x("data+%d" % (8*n), 'g'), ((0xdeadbeef<<n)+17) & ((1<<self.target.xlen)-1))
def test(self): regs = [("x%d" % n) for n in range(2, 32)] self.gdb.p("$pc=write_regs") for i, r in enumerate(regs): self.gdb.p("$%s=%d" % (r, (0xdeadbeef<<i)+17)) self.gdb.p("$x1=&data") self.gdb.command("b all_done") output = self.gdb.c() assertIn("Breakpoint ", output) # Just to get this data in the log. self.gdb.command("x/30gx &data") self.gdb.command("info registers") for n in range(len(regs)): assertEqual(self.gdb.x("(char*)(&data)+%d" % (8*n), 'g'), ((0xdeadbeef<<n)+17) & ((1<<self.hart.xlen)-1))
def test(self): """Test reading/writing priv.""" # Disable physical memory protection by allowing U mode access to all # memory. self.gdb.p("$pmpcfg0=0xf") # TOR, R, W, X self.gdb.p("$pmpaddr0=0x%x" % ((self.hart.ram + self.hart.ram_size) >> 2)) # Leave the PC at _start, where the first 4 instructions should be # legal in any mode. for privilege in range(4): self.gdb.p("$priv=%d" % privilege) self.gdb.stepi() actual = self.gdb.p("$priv") assertIn(actual, self.supported) if privilege in self.supported: assertEqual(actual, privilege)
def test(self): if self.hart.instruction_hardware_breakpoint_count < 1: return 'not_applicable' if not self.hart.honors_tdata1_hmode: # Run to main before setting the breakpoint, because startup code # will otherwise clear the trigger that we set. self.gdb.b("main") self.gdb.c() self.gdb.hbreak("rot13") # The breakpoint should be hit exactly 2 times. for _ in range(2): output = self.gdb.c() self.gdb.p("$pc") assertRegexpMatches(output, r"[bB]reakpoint") assertIn("rot13 ", output) self.exit()
def test(self): if self.hart.instruction_hardware_breakpoint_count < 1: return 'not_applicable' if not self.hart.honors_tdata1_hmode: # Run to main before setting the breakpoint, because startup code # will otherwise clear the trigger that we set. self.gdb.b("main") self.gdb.c() self.gdb.command("delete") self.gdb.hbreak("rot13") # The breakpoint should be hit exactly 2 times. for _ in range(2): output = self.gdb.c() self.gdb.p("$pc") assertRegexpMatches(output, r"[bB]reakpoint") assertIn("rot13 ", output) self.gdb.b("_exit") self.exit()
def test(self): """Test a store address breakpoint on the first instruction executed out of debug mode.""" self.gdb.command("b just_before_write_loop") self.gdb.c() write_loop = self.gdb.p("&write_loop") data = self.gdb.p("&data") self.gdb.command("watch *0x%x" % data) output = self.gdb.c() if "_exit (status=0)" in output: # We ran to _exit. It looks as if we didn't hit the trigger at all. # However this can be "correct" behavior. gdb's definition of # "watch" is to run until the value in memory changes. To do this # it reads the memory value when the trigger is set, and then when # the halt happens. Because our triggers can fire just before the # write happens, when gdb does this check the memory hasn't # changed. So it silently resumes running. # https://github.com/riscv/riscv-openocd/issues/295 tracks this # problem. Until it's fixed, we're going to allow running to _exit. return # Accept hitting the breakpoint before or after the store instruction. assertIn(self.gdb.p("$pc"), [write_loop, write_loop + 4]) assertEqual(self.gdb.p("$a0"), self.gdb.p("&data"))
def test(self): self.gdb.b("main") output = self.gdb.c() assertIn("Breakpoint", output) assertIn("main", output) self.gdb.watch("counter == 5") # Watchpoint hits when counter becomes 5. output = self.gdb.c() assertEqual(self.gdb.p("counter"), 5) # Watchpoint hits when counter no longer is 5. output = self.gdb.c() assertEqual(self.gdb.p("counter"), 6) # The watchpoint is going out of scope output = self.gdb.c() assertIn("Watchpoint", output) assertIn("deleted", output) self.exit()
def test(self): mainbp = self.gdb.b("main") output = self.gdb.c() assertIn("Breakpoint", output) assertIn("main", output) self.gdb.command("delete %d" % mainbp) self.gdb.watch("counter == 5") # Watchpoint hits when counter becomes 5. output = self.gdb.c() assertEqual(self.gdb.p("counter"), 5) # Watchpoint hits when counter no longer is 5. output = self.gdb.c() assertEqual(self.gdb.p("counter"), 6) # The watchpoint is going out of scope output = self.gdb.c() assertIn("Watchpoint", output) assertIn("deleted", output) self.exit()
def test(self): threads = self.gdb.threads() if len(threads) < 2: return 'not_applicable' for t in threads: self.gdb.thread(t) self.gdb.p("$pc=_start") # Run to main self.gdb.b("main") self.gdb.c() for t in self.gdb.threads(): assertIn("main", t.frame) self.gdb.command("delete breakpoints") # Run through the entire loop. self.gdb.b("main_end") self.gdb.c() hart_ids = [] for t in self.gdb.threads(): assertIn("main_end", t.frame) # Check register values. self.gdb.thread(t) hart_id = self.gdb.p("$x1") assertNotIn(hart_id, hart_ids) hart_ids.append(hart_id) for n in range(2, 32): value = self.gdb.p("$x%d" % n) assertEqual(value, hart_ids[-1] + n - 1) # Confirmed that we read different register values for different harts. # Write a new value to x1, and run through the add sequence again. for t in threads: self.gdb.thread(t) self.gdb.p("$x1=0x%x" % (int(t.id) * 0x800)) self.gdb.p("$pc=main_post_csrr") self.gdb.c() for t in self.gdb.threads(): assertIn("main_end", t.frame) # Check register values. self.gdb.thread(t) for n in range(1, 32): value = self.gdb.p("$x%d" % n) assertEqual(value, int(t.id) * 0x800 + n - 1)
def test(self): # Run to main for hart in self.target.harts: self.gdb.select_hart(hart) self.gdb.b("main") self.gdb.c() assertIn("main", self.gdb.where()) self.gdb.command("delete breakpoints") # Run through the entire loop. for hart in self.target.harts: self.gdb.select_hart(hart) self.gdb.b("main_end") self.gdb.c() assertIn("main_end", self.gdb.where()) hart_ids = [] for hart in self.target.harts: self.gdb.select_hart(hart) # Check register values. x1 = self.gdb.p("$x1") hart_id = self.gdb.p("$mhartid") assertEqual(x1, hart_id) assertNotIn(hart_id, hart_ids) hart_ids.append(hart_id) for n in range(2, 32): value = self.gdb.p("$x%d" % n) assertEqual(value, hart_ids[-1] + n - 1) # Confirmed that we read different register values for different harts. # Write a new value to x1, and run through the add sequence again. for hart in self.target.harts: self.gdb.select_hart(hart) self.gdb.p("$x1=0x%x" % (hart.index * 0x800)) self.gdb.p("$pc=main_post_csrr") self.gdb.c() for hart in self.target.harts: self.gdb.select_hart(hart) assertIn("main", self.gdb.where()) # Check register values. for n in range(1, 32): value = self.gdb.p("$x%d" % n) assertEqual(value, hart.index * 0x800 + n - 1)
def exit(self): self.gdb.command("delete") self.gdb.b("_exit") output = self.gdb.c() assertIn("Breakpoint", output) assertIn("_exit", output)
def exit(self, expected_result=0xc86455d4): output = self.gdb.c() assertIn("Breakpoint", output) assertIn("_exit", output) assertEqual(self.gdb.p("status"), expected_result)
def exit(self): output = self.gdb.c() assertIn("Breakpoint", output) assertIn("_exit", output)
def test(self): self.gdb.b("main") output = self.gdb.c() assertIn("Breakpoint", output) assertIn("main", output) self.gdb.swatch("counter == 5") # The watchpoint is triggered when the expression changes output = self.gdb.c() assertIn("Watchpoint", output) assertIn("counter == 5", output) output = self.gdb.p_raw("counter") assertIn("5", output) output = self.gdb.c() assertIn("Watchpoint", output) assertIn("counter == 5", output) output = self.gdb.p_raw("counter") assertIn("6", output) output = self.gdb.c() # The watchpoint is going out of scope assertIn("Watchpoint", output) assertIn("deleted", output) self.exit()