bhushan updated this revision to Diff 45364.
bhushan added a comment.

As suggested by Greg, added new function `matchArchitectures(archs)` which 
handles "archs".
This function can be used by other decorator functions for testing "archs".


Repository:
  rL LLVM

http://reviews.llvm.org/D16049

Files:
  include/lldb/API/SBInstruction.h
  
packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/Makefile
  
packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/TestAvoidBreakpointInDelaySlot.py
  
packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/main.c
  packages/Python/lldbsuite/test/lldbtest.py
  scripts/interface/SBInstruction.i
  source/API/SBInstruction.cpp
  source/Target/Target.cpp

Index: packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/main.c
===================================================================
--- /dev/null
+++ packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/main.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+foo (int a, int b)
+{
+    int c;
+    if (a<=b)
+        c=b-a;
+    else
+        c=b+a;
+    return c;
+}
+
+int main()
+{
+    int a=7, b=8, c;
+    
+    c = foo(a, b);
+
+return 0;
+}
+
Index: packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/TestAvoidBreakpointInDelaySlot.py
===================================================================
--- /dev/null
+++ packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/TestAvoidBreakpointInDelaySlot.py
@@ -0,0 +1,82 @@
+"""
+Test specific to MIPS 
+"""
+
+import os, time
+import re
+import unittest2
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+class AvoidBreakpointInDelaySlotAPITestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @skipUnlessArch(archs=re.compile('mips*'))
+    def test(self):
+        self.build()
+        exe = os.path.join(os.getcwd(), "a.out")
+        self.expect("file " + exe,
+                    patterns = [ "Current executable set to .*a.out.*" ])
+        
+        # Create a target by the debugger.
+        target = self.dbg.CreateTarget(exe)
+        self.assertTrue(target, VALID_TARGET)
+
+        breakpoint = target.BreakpointCreateByName('main', 'a.out')
+        self.assertTrue(breakpoint and
+                        breakpoint.GetNumLocations() == 1,
+                        VALID_BREAKPOINT)
+
+        # Now launch the process, and do not stop at entry point.
+        process = target.LaunchSimple (None, None, self.get_process_working_directory())
+        self.assertTrue(process, PROCESS_IS_VALID)
+
+        list = target.FindFunctions('foo', lldb.eFunctionNameTypeAuto)
+        self.assertTrue(list.GetSize() == 1)
+        sc = list.GetContextAtIndex(0)
+        self.assertTrue(sc.GetSymbol().GetName() == "foo")
+        function = sc.GetFunction()
+        self.assertTrue(function)
+        self.function(function, target)
+
+    def function (self, function, target):
+        """Iterate over instructions in function and place a breakpoint on delay slot instruction"""
+        # Get the list of all instructions in the function
+        insts = function.GetInstructions(target)
+        print insts
+        i = 0
+        for inst in insts:
+            if (inst.HasDelaySlot()):
+                # Remember the address of branch instruction.
+                branchinstaddress = inst.GetAddress().GetLoadAddress(target)
+
+                # Get next instruction i.e delay slot instruction.
+                delayinst = insts.GetInstructionAtIndex(i+1)
+                delayinstaddr = delayinst.GetAddress().GetLoadAddress(target)
+
+                # Set breakpoint on delay slot instruction
+                breakpoint = target.BreakpointCreateByAddress(delayinstaddr)
+
+                # Verify the breakpoint.
+                self.assertTrue(breakpoint and
+                                breakpoint.GetNumLocations() == 1,
+                                VALID_BREAKPOINT)
+                # Get the location from breakpoint
+                location = breakpoint.GetLocationAtIndex(0)
+
+                # Get the address where breakpoint is actually set.
+                bpaddr = location.GetLoadAddress()
+		
+                # Breakpoint address should be adjusted to the address of branch instruction.
+                self.assertTrue(branchinstaddress ==  bpaddr)
+                i += 1
+            else:
+                i += 1
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()
Index: packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/Makefile
===================================================================
--- /dev/null
+++ packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
+
Index: source/Target/Target.cpp
===================================================================
--- source/Target/Target.cpp
+++ source/Target/Target.cpp
@@ -2442,18 +2442,18 @@
             SymbolContext sc;
             uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
             temp_addr_module_sp->ResolveSymbolContextForAddress(resolved_addr, resolve_scope, sc);
+            Address sym_addr;
             if (sc.function)
-            {
-                function_start = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(this);
-                if (function_start == LLDB_INVALID_ADDRESS)
-                    function_start = sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
-            }
+                sym_addr = sc.function->GetAddressRange().GetBaseAddress();
             else if (sc.symbol)
-            {
-                Address sym_addr = sc.symbol->GetAddress();
+                sym_addr = sc.symbol->GetAddress();
+
+            function_start = sym_addr.GetLoadAddress(this);
+            if (function_start == LLDB_INVALID_ADDRESS)
                 function_start = sym_addr.GetFileAddress();
-            }
-            current_offset = addr - function_start;
+
+            if (function_start)
+                current_offset = addr - function_start;
         }
 
         // If breakpoint address is start of function then we dont have to do anything.
Index: source/API/SBInstruction.cpp
===================================================================
--- source/API/SBInstruction.cpp
+++ source/API/SBInstruction.cpp
@@ -160,6 +160,14 @@
     return false;
 }
 
+bool
+SBInstruction::HasDelaySlot ()
+{
+    if (m_opaque_sp)
+        return m_opaque_sp->HasDelaySlot ();
+    return false;
+}
+
 void
 SBInstruction::SetOpaque (const lldb::InstructionSP &inst_sp)
 {
Index: scripts/interface/SBInstruction.i
===================================================================
--- scripts/interface/SBInstruction.i
+++ scripts/interface/SBInstruction.i
@@ -51,6 +51,9 @@
     bool
     DoesBranch ();
 
+    bool
+    HasDelaySlot ();
+
     void
     Print (FILE *out);
 
Index: packages/Python/lldbsuite/test/lldbtest.py
===================================================================
--- packages/Python/lldbsuite/test/lldbtest.py
+++ packages/Python/lldbsuite/test/lldbtest.py
@@ -635,6 +635,14 @@
     else:
         return list_or_lambda is None or value is None or list_or_lambda == value
 
+def matchArchitectures(archs, actual_arch):
+    retype = type(re.compile('hello, world'))
+    list_passes = isinstance(archs, list) and actual_arch in archs
+    basestring_passes = isinstance(archs, basestring) and actual_arch == archs
+    regex_passes = isinstance(archs, retype) and re.match(archs, actual_arch)
+
+    return (list_passes or basestring_passes or regex_passes)
+
 # provide a function to xfail on defined oslist, compiler version, and archs
 # if none is specified for any argument, that argument won't be checked and thus means for all
 # for example,
@@ -1028,18 +1036,17 @@
     return unittest2.skipUnless(getHostPlatform() in oslist,
                                 "requires on of %s" % (", ".join(oslist)))
 
-def skipUnlessArch(archlist):
+def skipUnlessArch(archs):
     """Decorate the item to skip tests unless running on one of the listed architectures."""
     def myImpl(func):
         if isinstance(func, type) and issubclass(func, unittest2.TestCase):
             raise Exception("@skipUnlessArch can only be used to decorate a test method")
 
         @wraps(func)
         def wrapper(*args, **kwargs):
             self = args[0]
-            if self.getArchitecture() not in archlist:
-                self.skipTest("skipping for architecture %s (requires one of %s)" % 
-                    (self.getArchitecture(), ", ".join(archlist)))
+            if not matchArchitectures(archs, self.getArchitecture()):
+                self.skipTest("skipping for architecture %s" % (self.getArchitecture())) 
             else:
                 func(*args, **kwargs)
         return wrapper
Index: include/lldb/API/SBInstruction.h
===================================================================
--- include/lldb/API/SBInstruction.h
+++ include/lldb/API/SBInstruction.h
@@ -60,6 +60,9 @@
     bool
     DoesBranch ();
 
+    bool
+    HasDelaySlot ();
+
     void
     Print (FILE *out);
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to