summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBhushan D. Attarde <Bhushan.Attarde@imgtec.com>2016-01-27 10:16:30 +0000
committerBhushan D. Attarde <Bhushan.Attarde@imgtec.com>2016-01-27 10:16:30 +0000
commitdf5f0b448cc10e4877f319e9ddd4704fd389f418 (patch)
tree980dff3690dd64fec4c367716e67818e9707b4d0
parent5e45630edfbca796d662253ed25f0538cbfef948 (diff)
downloadbcm5719-llvm-df5f0b448cc10e4877f319e9ddd4704fd389f418.tar.gz
bcm5719-llvm-df5f0b448cc10e4877f319e9ddd4704fd389f418.zip
[LLDB][MIPS] A small fix in GetBreakableLoadAddress() for MIPS
SUMMARY: Get the load address for the address given by symbol and function. Earlier, this was done for function only, this patch does it for symbol too. This patch also adds TestAvoidBreakpointInDelaySlot.py to test this change. Reviewers: clayborg Subscribers: labath, zturner, mohit.bhakkad, sagar, jaydeep, lldb-commits Differential Revision: http://reviews.llvm.org/D16049 llvm-svn: 258919
-rw-r--r--lldb/include/lldb/API/SBInstruction.h3
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/Makefile6
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/TestAvoidBreakpointInDelaySlot.py82
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/main.c21
-rw-r--r--lldb/packages/Python/lldbsuite/test/lldbtest.py15
-rw-r--r--lldb/scripts/interface/SBInstruction.i3
-rw-r--r--lldb/source/API/SBInstruction.cpp8
-rw-r--r--lldb/source/Target/Target.cpp18
8 files changed, 143 insertions, 13 deletions
diff --git a/lldb/include/lldb/API/SBInstruction.h b/lldb/include/lldb/API/SBInstruction.h
index c4bded59576..2bacc2b9774 100644
--- a/lldb/include/lldb/API/SBInstruction.h
+++ b/lldb/include/lldb/API/SBInstruction.h
@@ -60,6 +60,9 @@ public:
bool
DoesBranch ();
+ bool
+ HasDelaySlot ();
+
void
Print (FILE *out);
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/Makefile
new file mode 100644
index 00000000000..77aa24afc0f
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
+
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/TestAvoidBreakpointInDelaySlot.py b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/TestAvoidBreakpointInDelaySlot.py
new file mode 100644
index 00000000000..bab56e21040
--- /dev/null
+++ b/lldb/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()
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/main.c b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_in_delayslot/main.c
new file mode 100644
index 00000000000..bc3eceea769
--- /dev/null
+++ b/lldb/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;
+}
+
diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index 015615bd875..c57279c8d02 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -636,6 +636,14 @@ def check_list_or_lambda(list_or_lambda, value):
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,
@@ -1029,7 +1037,7 @@ def skipUnlessHostPlatform(oslist):
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):
@@ -1038,9 +1046,8 @@ def skipUnlessArch(archlist):
@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
diff --git a/lldb/scripts/interface/SBInstruction.i b/lldb/scripts/interface/SBInstruction.i
index 421990646a1..d5b60201e95 100644
--- a/lldb/scripts/interface/SBInstruction.i
+++ b/lldb/scripts/interface/SBInstruction.i
@@ -51,6 +51,9 @@ public:
bool
DoesBranch ();
+ bool
+ HasDelaySlot ();
+
void
Print (FILE *out);
diff --git a/lldb/source/API/SBInstruction.cpp b/lldb/source/API/SBInstruction.cpp
index 36be9480186..a17f3f8dbd5 100644
--- a/lldb/source/API/SBInstruction.cpp
+++ b/lldb/source/API/SBInstruction.cpp
@@ -160,6 +160,14 @@ SBInstruction::DoesBranch ()
return false;
}
+bool
+SBInstruction::HasDelaySlot ()
+{
+ if (m_opaque_sp)
+ return m_opaque_sp->HasDelaySlot ();
+ return false;
+}
+
void
SBInstruction::SetOpaque (const lldb::InstructionSP &inst_sp)
{
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 4ddabf537c0..f3461a0f0df 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -2442,18 +2442,18 @@ Target::GetBreakableLoadAddress (lldb::addr_t addr)
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.
OpenPOWER on IntegriCloud