[Lldb-commits] [lldb] r220372 - Added functions to the C++ API, for the benefit of non-8-bit byte architectures.

Matthew Gardiner mg11 at csr.com
Wed Oct 22 00:22:57 PDT 2014


Author: mg11
Date: Wed Oct 22 02:22:56 2014
New Revision: 220372

URL: http://llvm.org/viewvc/llvm-project?rev=220372&view=rev
Log:
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


Added:
    lldb/trunk/test/python_api/section/
    lldb/trunk/test/python_api/section/Makefile
    lldb/trunk/test/python_api/section/TestSectionAPI.py   (with props)
    lldb/trunk/test/python_api/section/main.c
Modified:
    lldb/trunk/include/lldb/API/SBSection.h
    lldb/trunk/include/lldb/API/SBTarget.h
    lldb/trunk/include/lldb/Target/Target.h
    lldb/trunk/scripts/Python/interface/SBSection.i
    lldb/trunk/scripts/Python/interface/SBTarget.i
    lldb/trunk/source/API/SBSection.cpp
    lldb/trunk/source/API/SBTarget.cpp
    lldb/trunk/source/Target/Target.cpp
    lldb/trunk/test/lldbtest.py
    lldb/trunk/test/python_api/target/TestTargetAPI.py
    lldb/trunk/test/python_api/target/main.c

Modified: lldb/trunk/include/lldb/API/SBSection.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBSection.h?rev=220372&r1=220371&r2=220372&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBSection.h (original)
+++ lldb/trunk/include/lldb/API/SBSection.h Wed Oct 22 02:22:56 2014
@@ -71,6 +71,18 @@ public:
     SectionType
     GetSectionType ();
 
+    //------------------------------------------------------------------
+    /// Return the size of a target's byte represented by this section
+    /// in numbers of host bytes. Note that certain architectures have
+    /// varying minimum addressable unit (i.e. byte) size for their 
+    /// CODE or DATA buses.
+    ///
+    /// @return
+    ///     The number of host (8-bit) bytes needed to hold a target byte
+    //------------------------------------------------------------------
+    uint32_t
+    GetTargetByteSize ();
+
     bool
     operator == (const lldb::SBSection &rhs);
 

Modified: lldb/trunk/include/lldb/API/SBTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=220372&r1=220371&r2=220372&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBTarget.h (original)
+++ lldb/trunk/include/lldb/API/SBTarget.h Wed Oct 22 02:22:56 2014
@@ -22,6 +22,8 @@
 
 namespace lldb {
 
+class SBPlatform;
+
 class SBLaunchInfo
 {
 public:
@@ -309,6 +311,18 @@ public:
     GetProcess ();
 
     //------------------------------------------------------------------
+    /// Return the platform object associated with the target.
+    ///
+    /// After return, the platform object should be checked for
+    /// validity.
+    ///
+    /// @return
+    ///     A platform object.
+    //------------------------------------------------------------------
+    lldb::SBPlatform
+    GetPlatform ();
+
+    //------------------------------------------------------------------
     /// Install any binaries that need to be installed.
     ///
     /// This function does nothing when debugging on the host system.
@@ -564,6 +578,26 @@ public:
     GetTriple ();
 
     //------------------------------------------------------------------
+    /// Architecture data byte width accessor
+    ///
+    /// @return
+    /// The size in 8-bit (host) bytes of a minimum addressable
+    /// unit from the Architecture's data bus
+    //------------------------------------------------------------------
+    uint32_t
+    GetDataByteSize ();
+
+    //------------------------------------------------------------------
+    /// Architecture code byte width accessor
+    ///
+    /// @return
+    /// The size in 8-bit (host) bytes of a minimum addressable
+    /// unit from the Architecture's code bus
+    //------------------------------------------------------------------
+    uint32_t
+    GetCodeByteSize ();
+
+    //------------------------------------------------------------------
     /// Set the base load address for a module section.
     ///
     /// @param[in] section
@@ -728,6 +762,17 @@ public:
     Clear ();
 
     //------------------------------------------------------------------
+    /// Resolve a current file address into a section offset address.
+    ///
+    /// @param[in] file_addr
+    ///
+    /// @return
+    ///     An SBAddress which will be valid if...
+    //------------------------------------------------------------------
+    lldb::SBAddress
+    ResolveFileAddress (lldb::addr_t file_addr);
+
+    //------------------------------------------------------------------
     /// Resolve a current load address into a section offset address.
     ///
     /// @param[in] vm_addr
@@ -772,6 +817,31 @@ public:
     ResolveSymbolContextForAddress (const SBAddress& addr, 
                                     uint32_t resolve_scope);
 
+    //------------------------------------------------------------------
+    /// Read target memory. If a target process is running then memory  
+    /// is read from here. Otherwise the memory is read from the object
+    /// files. For a target whose bytes are sized as a multiple of host
+    /// bytes, the data read back will preserve the target's byte order.
+    ///
+    /// @param[in] addr
+    ///     A target address to read from. 
+    ///
+    /// @param[out] buf
+    ///     The buffer to read memory into. 
+    ///
+    /// @param[in] size
+    ///     The maximum number of host bytes to read in the buffer passed
+    ///     into this call
+    ///
+    /// @param[out] error
+    ///     Error information is written here if the memory read fails.
+    ///
+    /// @return
+    ///     The amount of data read in host bytes.
+    //------------------------------------------------------------------
+    size_t
+    ReadMemory (const SBAddress addr, void *buf, size_t size, lldb::SBError &error);
+
     lldb::SBBreakpoint
     BreakpointCreateByLocation (const char *file, uint32_t line);
 

Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=220372&r1=220371&r2=220372&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Wed Oct 22 02:22:56 2014
@@ -1133,6 +1133,9 @@ public:
     Error
     Install(ProcessLaunchInfo *launch_info);
     
+    bool
+    ResolveFileAddress (lldb::addr_t load_addr,
+                        Address &so_addr);
     
     bool
     ResolveLoadAddress (lldb::addr_t load_addr,

Modified: lldb/trunk/scripts/Python/interface/SBSection.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBSection.i?rev=220372&r1=220371&r2=220372&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBSection.i (original)
+++ lldb/trunk/scripts/Python/interface/SBSection.i Wed Oct 22 02:22:56 2014
@@ -90,6 +90,20 @@ public:
     SectionType
     GetSectionType ();
 
+    %feature("docstring", "
+    //------------------------------------------------------------------
+    /// Return the size of a target's byte represented by this section
+    /// in numbers of host bytes. Note that certain architectures have
+    /// varying minimum addressable unit (i.e. byte) size for their 
+    /// CODE or DATA buses.
+    ///
+    /// @return
+    ///     The number of host (8-bit) bytes needed to hold a target byte
+    //------------------------------------------------------------------
+    ") GetTargetByteSize;
+    uint32_t
+    GetTargetByteSize ();
+
     bool
     GetDescription (lldb::SBStream &description);
     
@@ -127,6 +141,9 @@ public:
         __swig_getmethods__["type"] = GetSectionType
         if _newclass: type = property(GetSectionType, None, doc='''A read only property that returns an lldb enumeration value (see enumerations that start with "lldb.eSectionType") that represents the type of this section (code, data, etc.).''')
 
+        __swig_getmethods__["target_byte_size"] = GetTargetByteSize
+        if _newclass: target_byte_size = property(GetTargetByteSize, None, doc='''A read only property that returns the size of a target byte represented by this section as a number of host bytes.''')
+
     %}
 
 private:

Modified: lldb/trunk/scripts/Python/interface/SBTarget.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBTarget.i?rev=220372&r1=220371&r2=220372&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBTarget.i (original)
+++ lldb/trunk/scripts/Python/interface/SBTarget.i Wed Oct 22 02:22:56 2014
@@ -282,6 +282,21 @@ public:
     lldb::SBProcess
     GetProcess ();
 
+
+    %feature("docstring", "
+    //------------------------------------------------------------------
+    /// Return the platform object associated with the target.
+    ///
+    /// After return, the platform object should be checked for
+    /// validity.
+    ///
+    /// @return
+    ///     A platform object.
+    //------------------------------------------------------------------
+    ") GetPlatform;
+    lldb::SBPlatform
+    GetPlatform ();
+
     %feature("docstring", "
     //------------------------------------------------------------------
     /// Install any binaries that need to be installed.
@@ -579,6 +594,30 @@ public:
     const char *
     GetTriple ();
 
+    %feature("docstring", "
+    //------------------------------------------------------------------
+    /// Architecture data byte width accessor
+    ///
+    /// @return
+    /// The size in 8-bit (host) bytes of a minimum addressable
+    /// unit from the Architecture's data bus
+    //------------------------------------------------------------------
+    ") GetDataByteSize;
+    uint32_t
+    GetDataByteSize ();
+
+    %feature("docstring", "
+    //------------------------------------------------------------------
+    /// Architecture code byte width accessor
+    ///
+    /// @return
+    /// The size in 8-bit (host) bytes of a minimum addressable
+    /// unit from the Architecture's code bus
+    //------------------------------------------------------------------
+    ") GetCodeByteSize;
+    uint32_t
+    GetCodeByteSize ();
+
     lldb::SBError
     SetSectionLoadAddress (lldb::SBSection section,
                            lldb::addr_t section_base_addr);
@@ -676,6 +715,19 @@ public:
     void
     Clear ();
 
+     %feature("docstring", "
+    //------------------------------------------------------------------
+    /// Resolve a current file address into a section offset address.
+    ///
+    /// @param[in] file_addr
+    ///
+    /// @return
+    ///     An SBAddress which will be valid if...
+    //------------------------------------------------------------------
+    ") ResolveFileAddress;
+    lldb::SBAddress
+    ResolveFileAddress (lldb::addr_t file_addr);
+
     lldb::SBAddress
     ResolveLoadAddress (lldb::addr_t vm_addr);
               
@@ -686,6 +738,33 @@ public:
     ResolveSymbolContextForAddress (const SBAddress& addr, 
                                     uint32_t resolve_scope);
 
+     %feature("docstring", "
+    //------------------------------------------------------------------
+    /// Read target memory. If a target process is running then memory  
+    /// is read from here. Otherwise the memory is read from the object
+    /// files. For a target whose bytes are sized as a multiple of host
+    /// bytes, the data read back will preserve the target's byte order.
+    ///
+    /// @param[in] addr
+    ///     A target address to read from. 
+    ///
+    /// @param[out] buf
+    ///     The buffer to read memory into. 
+    ///
+    /// @param[in] size
+    ///     The maximum number of host bytes to read in the buffer passed
+    ///     into this call
+    ///
+    /// @param[out] error
+    ///     Error information is written here if the memory read fails.
+    ///
+    /// @return
+    ///     The amount of data read in host bytes.
+    //------------------------------------------------------------------
+    ") ReadMemory;
+    size_t
+    ReadMemory (const SBAddress addr, void *buf, size_t size, lldb::SBError &error);
+
     lldb::SBBreakpoint
     BreakpointCreateByLocation (const char *file, uint32_t line);
 
@@ -904,6 +983,15 @@ public:
         
         __swig_getmethods__["triple"] = GetTriple
         if _newclass: triple = property(GetTriple, None, doc='''A read only property that returns the target triple (arch-vendor-os) for this target as a string.''')
+
+        __swig_getmethods__["data_byte_size"] = GetDataByteSize
+        if _newclass: addr_size = property(GetDataByteSize, None, doc='''A read only property that returns the size in host bytes of a byte in the data address space for this target.''')
+
+        __swig_getmethods__["code_byte_size"] = GetCodeByteSize
+        if _newclass: addr_size = property(GetCodeByteSize, None, doc='''A read only property that returns the size in host bytes of a byte in the code address space for this target.''')
+
+        __swig_getmethods__["platform"] = GetPlatform
+        if _newclass: platform = property(GetPlatform, None, doc='''A read only property that returns the platform associated with with this target.''')
     %}
 
 };

Modified: lldb/trunk/source/API/SBSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBSection.cpp?rev=220372&r1=220371&r2=220372&view=diff
==============================================================================
--- lldb/trunk/source/API/SBSection.cpp (original)
+++ lldb/trunk/source/API/SBSection.cpp Wed Oct 22 02:22:56 2014
@@ -250,6 +250,14 @@ SBSection::GetSectionType ()
     return eSectionTypeInvalid;
 }
 
+uint32_t
+SBSection::GetTargetByteSize ()
+{
+    SectionSP section_sp (GetSP());
+    if (section_sp.get())
+        return section_sp->GetTargetByteSize();
+    return 0;
+}
 
 bool
 SBSection::operator == (const SBSection &rhs)

Modified: lldb/trunk/source/API/SBTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=220372&r1=220371&r2=220372&view=diff
==============================================================================
--- lldb/trunk/source/API/SBTarget.cpp (original)
+++ lldb/trunk/source/API/SBTarget.cpp Wed Oct 22 02:22:56 2014
@@ -587,6 +587,19 @@ SBTarget::GetProcess ()
     return sb_process;
 }
 
+SBPlatform
+SBTarget::GetPlatform ()
+{
+    TargetSP target_sp(GetSP());
+    if (!target_sp)
+        return SBPlatform();
+
+    SBPlatform platform;
+    platform.m_opaque_sp = target_sp->GetPlatform();
+
+    return platform;
+}
+
 SBDebugger
 SBTarget::GetDebugger () const
 {
@@ -1231,6 +1244,22 @@ SBTarget::ResolveLoadAddress (lldb::addr
     return sb_addr;
 }
 
+lldb::SBAddress
+SBTarget::ResolveFileAddress (lldb::addr_t file_addr)
+{
+    lldb::SBAddress sb_addr;
+    Address &addr = sb_addr.ref();
+    TargetSP target_sp(GetSP());
+    if (target_sp)
+    {
+        Mutex::Locker api_locker (target_sp->GetAPIMutex());
+        if (target_sp->ResolveFileAddress (file_addr, addr))
+            return sb_addr;
+    }
+
+    addr.SetRawAddress(file_addr);
+    return sb_addr;
+}
 
 lldb::SBAddress
 SBTarget::ResolvePastLoadAddress (uint32_t stop_id, lldb::addr_t vm_addr)
@@ -1265,6 +1294,29 @@ SBTarget::ResolveSymbolContextForAddress
     return sc;
 }
 
+size_t
+SBTarget::ReadMemory (const SBAddress addr,
+                      void *buf,
+                      size_t size,
+                      lldb::SBError &error)
+{
+    SBError sb_error;
+    size_t bytes_read = 0;
+    TargetSP target_sp(GetSP());
+    if (target_sp)
+    {
+        Mutex::Locker api_locker (target_sp->GetAPIMutex());
+        lldb_private::Address addr_priv(addr.GetFileAddress(), NULL);
+        lldb_private::Error err_priv;    
+        bytes_read = target_sp->ReadMemory(addr_priv, false, buf, size, err_priv);
+        if(err_priv.Fail())
+        {
+            sb_error.SetError(err_priv.GetError(), err_priv.GetType());
+        }
+    }
+
+    return bytes_read;
+}
 
 SBBreakpoint
 SBTarget::BreakpointCreateByLocation (const char *file,
@@ -2061,6 +2113,28 @@ SBTarget::GetTriple ()
 }
 
 uint32_t
+SBTarget::GetDataByteSize ()
+{
+    TargetSP target_sp(GetSP());
+    if (target_sp)
+    {
+        return target_sp->GetArchitecture().GetDataByteSize() ;
+    }
+    return 0;
+}
+
+uint32_t
+SBTarget::GetCodeByteSize ()
+{
+    TargetSP target_sp(GetSP());
+    if (target_sp)
+    {
+        return target_sp->GetArchitecture().GetCodeByteSize() ;
+    }
+    return 0;
+}
+
+uint32_t
 SBTarget::GetAddressByteSize()
 {
     TargetSP target_sp(GetSP());

Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=220372&r1=220371&r2=220372&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Wed Oct 22 02:22:56 2014
@@ -2284,6 +2284,12 @@ Target::ResolveLoadAddress (addr_t load_
 }
 
 bool
+Target::ResolveFileAddress (lldb::addr_t file_addr, Address &resolved_addr)
+{
+    return m_images.ResolveFileAddress(file_addr, resolved_addr);
+}
+
+bool
 Target::SetSectionLoadAddress (const SectionSP &section_sp, addr_t new_section_load_addr, bool warn_multiple)
 {
     const addr_t old_section_load_addr = m_section_load_history.GetSectionLoadAddress (SectionLoadHistory::eStopIDNow, section_sp);

Modified: lldb/trunk/test/lldbtest.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=220372&r1=220371&r2=220372&view=diff
==============================================================================
--- lldb/trunk/test/lldbtest.py (original)
+++ lldb/trunk/test/lldbtest.py Wed Oct 22 02:22:56 2014
@@ -137,6 +137,8 @@ VALID_SYMBOL = "Got a valid symbol"
 
 VALID_TARGET = "Got a valid target"
 
+VALID_PLATFORM = "Got a valid platform"
+
 VALID_TYPE = "Got a valid type"
 
 VALID_VARIABLE = "Got a valid variable"

Added: lldb/trunk/test/python_api/section/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/section/Makefile?rev=220372&view=auto
==============================================================================
--- lldb/trunk/test/python_api/section/Makefile (added)
+++ lldb/trunk/test/python_api/section/Makefile Wed Oct 22 02:22:56 2014
@@ -0,0 +1,10 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/test/python_api/section/TestSectionAPI.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/section/TestSectionAPI.py?rev=220372&view=auto
==============================================================================
--- lldb/trunk/test/python_api/section/TestSectionAPI.py (added)
+++ lldb/trunk/test/python_api/section/TestSectionAPI.py Wed Oct 22 02:22:56 2014
@@ -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()

Propchange: lldb/trunk/test/python_api/section/TestSectionAPI.py
------------------------------------------------------------------------------
    svn:executable = *

Added: lldb/trunk/test/python_api/section/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/section/main.c?rev=220372&view=auto
==============================================================================
--- lldb/trunk/test/python_api/section/main.c (added)
+++ lldb/trunk/test/python_api/section/main.c Wed Oct 22 02:22:56 2014
@@ -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;
+}

Modified: lldb/trunk/test/python_api/target/TestTargetAPI.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/target/TestTargetAPI.py?rev=220372&r1=220371&r2=220372&view=diff
==============================================================================
--- lldb/trunk/test/python_api/target/TestTargetAPI.py (original)
+++ lldb/trunk/test/python_api/target/TestTargetAPI.py Wed Oct 22 02:22:56 2014
@@ -104,12 +104,160 @@ class TargetAPITestCase(TestBase):
         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."""

Modified: lldb/trunk/test/python_api/target/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/target/main.c?rev=220372&r1=220371&r2=220372&view=diff
==============================================================================
--- lldb/trunk/test/python_api/target/main.c (original)
+++ lldb/trunk/test/python_api/target/main.c Wed Oct 22 02:22:56 2014
@@ -46,6 +46,7 @@ int c(int val)
 
 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);
     





More information about the lldb-commits mailing list