1"""
2Test specific to MIPS
3"""
4
5import re
6import lldb
7from lldbsuite.test.decorators import *
8from lldbsuite.test.lldbtest import *
9from lldbsuite.test import lldbutil
10
11
12class AvoidBreakpointInDelaySlotAPITestCase(TestBase):
13    @skipIf(archs=no_match(re.compile("mips*")))
14    def test(self):
15        self.build()
16        exe = self.getBuildArtifact("a.out")
17        self.expect("file " + exe, patterns=["Current executable set to .*a.out.*"])
18
19        # Create a target by the debugger.
20        target = self.dbg.CreateTarget(exe)
21        self.assertTrue(target, VALID_TARGET)
22
23        breakpoint = target.BreakpointCreateByName("main", "a.out")
24        self.assertTrue(
25            breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT
26        )
27
28        # Now launch the process, and do not stop at entry point.
29        process = target.LaunchSimple(None, None, self.get_process_working_directory())
30        self.assertTrue(process, PROCESS_IS_VALID)
31
32        list = target.FindFunctions("foo", lldb.eFunctionNameTypeAuto)
33        self.assertEqual(list.GetSize(), 1)
34        sc = list.GetContextAtIndex(0)
35        self.assertEqual(sc.GetSymbol().GetName(), "foo")
36        function = sc.GetFunction()
37        self.assertTrue(function)
38        self.function(function, target)
39
40    def function(self, function, target):
41        """Iterate over instructions in function and place a breakpoint on delay slot instruction"""
42        # Get the list of all instructions in the function
43        insts = function.GetInstructions(target)
44        print(insts)
45        i = 0
46        for inst in insts:
47            if inst.HasDelaySlot():
48                # Remember the address of branch instruction.
49                branchinstaddress = inst.GetAddress().GetLoadAddress(target)
50
51                # Get next instruction i.e delay slot instruction.
52                delayinst = insts.GetInstructionAtIndex(i + 1)
53                delayinstaddr = delayinst.GetAddress().GetLoadAddress(target)
54
55                # Set breakpoint on delay slot instruction
56                breakpoint = target.BreakpointCreateByAddress(delayinstaddr)
57
58                # Verify the breakpoint.
59                self.assertTrue(
60                    breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT
61                )
62                # Get the location from breakpoint
63                location = breakpoint.GetLocationAtIndex(0)
64
65                # Get the address where breakpoint is actually set.
66                bpaddr = location.GetLoadAddress()
67
68                # Breakpoint address should be adjusted to the address of
69                # branch instruction.
70                self.assertEqual(branchinstaddress, bpaddr)
71                i += 1
72            else:
73                i += 1
74