Added functions to the C++ API, for the benefit of non-8-bit byte architectures.
New functions to give client applications to tools to discover target byte sizes
for addresses prior to ReadMemory. Also added GetPlatform and ReadMemory to the
SBTarget class, since they seemed to be useful utilities to have.
Each new API has had a test case added.
http://reviews.llvm.org/D5867
llvm-svn: 220372
diff --git a/lldb/test/python_api/section/Makefile b/lldb/test/python_api/section/Makefile
new file mode 100644
index 0000000..3735eda
--- /dev/null
+++ b/lldb/test/python_api/section/Makefile
@@ -0,0 +1,10 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/lldb/test/python_api/section/TestSectionAPI.py b/lldb/test/python_api/section/TestSectionAPI.py
new file mode 100755
index 0000000..5644bb4
--- /dev/null
+++ b/lldb/test/python_api/section/TestSectionAPI.py
@@ -0,0 +1,120 @@
+"""
+Test SBSection APIs.
+"""
+
+import unittest2
+from lldbtest import *
+
+class SectionAPITestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @python_api_test
+ @dsym_test
+ def test_get_target_byte_size_with_dsym(self):
+ d = {'EXE': 'a.out'}
+ self.buildDsym(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ target = self.create_simple_target('a.out')
+
+ # find the .data section of the main module
+ data_section = self.find_data_section(target)
+
+ self.assertEquals(data_section.target_byte_size, 1)
+
+ @python_api_test
+ @dwarf_test
+ def test_get_target_byte_size_with_dwarf(self):
+ d = {'EXE': 'b.out'}
+ self.buildDwarf(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ target = self.create_simple_target('b.out')
+
+ # find the .data section of the main module
+ data_section = self.find_data_section(target)
+
+ self.assertEquals(data_section.target_byte_size, 1)
+
+ def create_simple_target(self, fn):
+ exe = os.path.join(os.getcwd(), fn)
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+ return target
+
+ def find_data_section(self, target):
+ mod = target.GetModuleAtIndex(0)
+ data_section = None
+ for s in mod.sections:
+ if ".data" == s.name:
+ data_section = s
+ break
+
+ self.assertIsNotNone(data_section)
+ return data_section
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
+"""
+Test SBSection APIs.
+"""
+
+import unittest2
+from lldbtest import *
+
+class SectionAPITestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @python_api_test
+ @dsym_test
+ def test_get_target_byte_size_with_dsym(self):
+ d = {'EXE': 'a.out'}
+ self.buildDsym(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ target = self.create_simple_target('a.out')
+
+ # find the .data section of the main module
+ data_section = self.find_data_section(target)
+
+ self.assertEquals(data_section.target_byte_size, 1)
+
+ @python_api_test
+ @dwarf_test
+ def test_get_target_byte_size_with_dwarf(self):
+ d = {'EXE': 'b.out'}
+ self.buildDwarf(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ target = self.create_simple_target('b.out')
+
+ # find the .data section of the main module
+ data_section = self.find_data_section(target)
+
+ self.assertEquals(data_section.target_byte_size, 1)
+
+ def create_simple_target(self, fn):
+ exe = os.path.join(os.getcwd(), fn)
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+ return target
+
+ def find_data_section(self, target):
+ mod = target.GetModuleAtIndex(0)
+ data_section = None
+ for s in mod.sections:
+ if ".data" == s.name:
+ data_section = s
+ break
+
+ self.assertIsNotNone(data_section)
+ return data_section
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
diff --git a/lldb/test/python_api/section/main.c b/lldb/test/python_api/section/main.c
new file mode 100644
index 0000000..c2060b5
--- /dev/null
+++ b/lldb/test/python_api/section/main.c
@@ -0,0 +1,56 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+#include <string.h>
+
+// This simple program is to test the lldb Python API SBSection. It includes
+// somes global data, and so the build process produces a DATA section, which
+// the test code can use to query for the target byte size
+
+char my_global_var_of_char_type = 'X';
+
+int main (int argc, char const *argv[])
+{
+ // this code just "does something" with the global so that it is not
+ // optimised away
+ if (argc > 1 && strlen(argv[1]))
+ {
+ my_global_var_of_char_type += argv[1][0];
+ }
+
+ return my_global_var_of_char_type;
+}
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+#include <string.h>
+
+// This simple program is to test the lldb Python API SBSection. It includes
+// somes global data, and so the build process produces a DATA section, which
+// the test code can use to query for the target byte size
+
+char my_global_var_of_char_type = 'X';
+
+int main (int argc, char const *argv[])
+{
+ // this code just "does something" with the global so that it is not
+ // optimised away
+ if (argc > 1 && strlen(argv[1]))
+ {
+ my_global_var_of_char_type += argv[1][0];
+ }
+
+ return my_global_var_of_char_type;
+}
diff --git a/lldb/test/python_api/target/TestTargetAPI.py b/lldb/test/python_api/target/TestTargetAPI.py
index 9f51482..d57305c 100644
--- a/lldb/test/python_api/target/TestTargetAPI.py
+++ b/lldb/test/python_api/target/TestTargetAPI.py
@@ -104,12 +104,160 @@
self.buildDwarf()
self.resolve_symbol_context_with_address()
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @python_api_test
+ @dsym_test
+ def test_get_platform_with_dsym(self):
+ d = {'EXE': 'a.out'}
+ self.buildDsym(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ target = self.create_simple_target('a.out')
+ platform = target.platform
+ self.assertTrue(platform, VALID_PLATFORM)
+
+ @python_api_test
+ @dwarf_test
+ def test_get_platform_with_dwarf(self):
+ d = {'EXE': 'b.out'}
+ self.buildDwarf(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ target = self.create_simple_target('b.out')
+ platform = target.platform
+ self.assertTrue(platform, VALID_PLATFORM)
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @python_api_test
+ @dsym_test
+ def test_get_data_byte_size_with_dsym(self):
+ d = {'EXE': 'a.out'}
+ self.buildDsym(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ target = self.create_simple_target('a.out')
+ self.assertEquals(target.data_byte_size, 1)
+
+ @python_api_test
+ @dwarf_test
+ def test_get_data_byte_size_with_dwarf(self):
+ d = {'EXE': 'b.out'}
+ self.buildDwarf(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ target = self.create_simple_target('b.out')
+ self.assertEquals(target.data_byte_size, 1)
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @python_api_test
+ @dsym_test
+ def test_get_code_byte_size_with_dsym(self):
+ d = {'EXE': 'a.out'}
+ self.buildDsym(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ target = self.create_simple_target('a.out')
+ self.assertEquals(target.code_byte_size, 1)
+
+ @python_api_test
+ @dwarf_test
+ def test_get_code_byte_size_with_dwarf(self):
+ d = {'EXE': 'b.out'}
+ self.buildDwarf(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ target = self.create_simple_target('b.out')
+ self.assertEquals(target.code_byte_size, 1)
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @python_api_test
+ @dsym_test
+ def test_resolve_file_address_with_dsym(self):
+ d = {'EXE': 'a.out'}
+ self.buildDsym(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ target = self.create_simple_target('a.out')
+ self.resolve_file_address(target)
+
+ @python_api_test
+ @dwarf_test
+ def test_resolve_file_address_with_dwarf(self):
+ d = {'EXE': 'b.out'}
+ self.buildDwarf(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ target = self.create_simple_target('b.out')
+ self.resolve_file_address(target)
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @python_api_test
+ @dsym_test
+ def test_read_memory_with_dsym(self):
+ d = {'EXE': 'a.out'}
+ self.buildDsym(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ target = self.create_simple_target('a.out')
+ self.read_memory(target)
+
+ @python_api_test
+ @dwarf_test
+ def test_read_memory_with_dwarf(self):
+ d = {'EXE': 'b.out'}
+ self.buildDwarf(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ target = self.create_simple_target('b.out')
+ self.read_memory(target)
+
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to of function 'c'.
self.line1 = line_number('main.c', '// Find the line number for breakpoint 1 here.')
self.line2 = line_number('main.c', '// Find the line number for breakpoint 2 here.')
+ self.line_main = line_number("main.c", "// Set a break at entry to main.")
+
+ def read_memory(self, target):
+ breakpoint = target.BreakpointCreateByLocation("main.c", self.line_main)
+ self.assertTrue(breakpoint, VALID_BREAKPOINT)
+
+ # Launch the process, and do not stop at the entry point.
+ process = target.LaunchSimple (None, None, self.get_process_working_directory())
+
+ # find the file address in the .data section of the main
+ # module
+ data_section = self.find_data_section(target)
+ data_section_addr = data_section.file_addr
+ a = target.ResolveFileAddress(data_section_addr)
+
+ content = target.ReadMemory(a, 1, lldb.SBError())
+ self.assertEquals(len(content), 1)
+
+ def create_simple_target(self, fn):
+ exe = os.path.join(os.getcwd(), fn)
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+ return target
+
+ def resolve_file_address(self, target):
+ # find the file address in the .data section of the main
+ # module
+ data_section = self.find_data_section(target)
+ data_section_addr = data_section.file_addr
+
+ # resolve the above address, and compare the address produced
+ # by the resolution against the original address/section
+ res_file_addr = target.ResolveFileAddress(data_section_addr)
+ self.assertTrue(res_file_addr.IsValid())
+
+ self.assertEquals(data_section_addr, res_file_addr.file_addr)
+
+ data_section2 = res_file_addr.section
+ self.assertIsNotNone(data_section2)
+ self.assertEquals(data_section.name, data_section2.name)
+
+ def find_data_section(self, target):
+ mod = target.GetModuleAtIndex(0)
+ data_section = None
+ for s in mod.sections:
+ if ".data" == s.name:
+ data_section = s
+ break
+
+ self.assertIsNotNone(data_section)
+ return data_section
def find_global_variables(self, exe_name):
"""Exercise SBTaget.FindGlobalVariables() API."""
diff --git a/lldb/test/python_api/target/main.c b/lldb/test/python_api/target/main.c
index 7934d30..ba82a54 100644
--- a/lldb/test/python_api/target/main.c
+++ b/lldb/test/python_api/target/main.c
@@ -46,6 +46,7 @@
int main (int argc, char const *argv[])
{
+ // Set a break at entry to main.
int A1 = a(1); // a(1) -> b(1) -> c(1)
printf("a(1) returns %d\n", A1);