[Lldb-commits] [lldb] r193380 - Added the ability to get the SDK path for a target using the platform plugins. If LLDB lives inside an Xcode.app bundle, it will select the SDK in the Xcode bundle, else it will use the currently selected Xcode.

Greg Clayton gclayton at apple.com
Thu Oct 24 15:54:08 PDT 2013


Author: gclayton
Date: Thu Oct 24 17:54:08 2013
New Revision: 193380

URL: http://llvm.org/viewvc/llvm-project?rev=193380&view=rev
Log:
Added the ability to get the SDK path for a target using the platform plugins. If LLDB lives inside an Xcode.app bundle, it will select the SDK in the Xcode bundle, else it will use the currently selected Xcode.

Also added the DWARFDataExtractor classes to the Xcode project file.


Modified:
    lldb/trunk/include/lldb/Symbol/ObjectFile.h
    lldb/trunk/include/lldb/Target/Platform.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.h

Modified: lldb/trunk/include/lldb/Symbol/ObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ObjectFile.h?rev=193380&r1=193379&r2=193380&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ObjectFile.h (original)
+++ lldb/trunk/include/lldb/Symbol/ObjectFile.h Thu Oct 24 17:54:08 2013
@@ -640,6 +640,72 @@ public:
         }
         return 0;
     }
+    
+    //------------------------------------------------------------------
+    /// Get the minimum OS version this object file can run on.
+    ///
+    /// Some object files have information that specifies the minimum OS
+    /// version that they can be used on.
+    ///
+    /// If \a versions is NULL, or if \a num_versions is 0, the return
+    /// value will indicate how many version numbers are available in
+    /// this object file. Then a subsequent call can be made to this
+    /// function with a value of \a versions and \a num_versions that
+    /// has enough storage to store some or all version numbers.
+    ///
+    /// @param[out] versions
+    ///     A pointer to an array of uint32_t types that is \a num_versions
+    ///     long. If this value is NULL, the return value will indicate
+    ///     how many version numbers are required for a subsequent call
+    ///     to this function so that all versions can be retrieved. If
+    ///     the value is non-NULL, then at most \a num_versions of the
+    ///     existing versions numbers will be filled into \a versions.
+    ///     If there is no version information available, \a versions
+    ///     will be filled with \a num_versions UINT32_MAX values
+    ///     and zero will be returned.
+    ///
+    /// @param[in] num_versions
+    ///     The maximum number of entries to fill into \a versions. If
+    ///     this value is zero, then the return value will indicate
+    ///     how many version numbers there are in total so another call
+    ///     to this function can be make with adequate storage in
+    ///     \a versions to get all of the version numbers. If \a
+    ///     num_versions is less than the actual number of version
+    ///     numbers in this object file, only \a num_versions will be
+    ///     filled into \a versions (if \a versions is non-NULL).
+    ///
+    /// @return
+    ///     This function always returns the number of version numbers
+    ///     that this object file has regardless of the number of
+    ///     version numbers that were copied into \a versions.
+    //------------------------------------------------------------------
+    virtual uint32_t
+    GetMinimumOSVersion (uint32_t *versions, uint32_t num_versions)
+    {
+        if (versions && num_versions)
+        {
+            for (uint32_t i=0; i<num_versions; ++i)
+                versions[i] = UINT32_MAX;
+        }
+        return 0;
+    }
+
+    //------------------------------------------------------------------
+    /// Get the SDK OS version this object file was built with.
+    ///
+    /// The versions arguments and returns values are the same as the
+    /// GetMinimumOSVersion()
+    //------------------------------------------------------------------
+    virtual uint32_t
+    GetSDKVersion (uint32_t *versions, uint32_t num_versions)
+    {
+        if (versions && num_versions)
+        {
+            for (uint32_t i=0; i<num_versions; ++i)
+                versions[i] = UINT32_MAX;
+        }
+        return 0;
+    }
 
     //------------------------------------------------------------------
     // Member Functions

Modified: lldb/trunk/include/lldb/Target/Platform.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Platform.h?rev=193380&r1=193379&r2=193380&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Platform.h (original)
+++ lldb/trunk/include/lldb/Target/Platform.h Thu Oct 24 17:54:08 2013
@@ -460,6 +460,15 @@ namespace lldb_private {
         virtual lldb::BreakpointSP
         SetThreadCreationBreakpoint (Target &target);
         
+        //------------------------------------------------------------------
+        // Given a target, find the local SDK directory if one exists on the
+        // current host.
+        //------------------------------------------------------------------
+        virtual lldb_private::ConstString
+        GetSDKDirectory (lldb_private::Target &target)
+        {
+            return lldb_private::ConstString();
+        }
 
         const std::string &
         GetRemoteURL () const

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=193380&r1=193379&r2=193380&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Thu Oct 24 17:54:08 2013
@@ -427,6 +427,8 @@
 		26A527C414E24F5F00F3A14A /* ThreadMachCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 26A527C014E24F5F00F3A14A /* ThreadMachCore.h */; };
 		26A69C5F137A17A500262477 /* RegisterValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C6886E137880C400407EDF /* RegisterValue.cpp */; };
 		26A7A035135E6E4200FB369E /* OptionValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A7A034135E6E4200FB369E /* OptionValue.cpp */; };
+		26AB92121819D74600E63F3E /* DWARFDataExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26AB92101819D74600E63F3E /* DWARFDataExtractor.cpp */; };
+		26AB92131819D74600E63F3E /* DWARFDataExtractor.h in Headers */ = {isa = PBXBuildFile; fileRef = 26AB92111819D74600E63F3E /* DWARFDataExtractor.h */; };
 		26ACEC2815E077AE00E94760 /* Property.h in Headers */ = {isa = PBXBuildFile; fileRef = 26ACEC2715E077AE00E94760 /* Property.h */; };
 		26B1EFAE154638AF00E2DAC7 /* DWARFDeclContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26B1EFAC154638AF00E2DAC7 /* DWARFDeclContext.cpp */; };
 		26B1EFAF154638AF00E2DAC7 /* DWARFDeclContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 26B1EFAD154638AF00E2DAC7 /* DWARFDeclContext.h */; };
@@ -1081,6 +1083,8 @@
 		26A527C014E24F5F00F3A14A /* ThreadMachCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadMachCore.h; sourceTree = "<group>"; };
 		26A7A034135E6E4200FB369E /* OptionValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OptionValue.cpp; path = source/Interpreter/OptionValue.cpp; sourceTree = "<group>"; };
 		26A7A036135E6E5300FB369E /* OptionValue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OptionValue.h; path = include/lldb/Interpreter/OptionValue.h; sourceTree = "<group>"; };
+		26AB92101819D74600E63F3E /* DWARFDataExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DWARFDataExtractor.cpp; sourceTree = "<group>"; };
+		26AB92111819D74600E63F3E /* DWARFDataExtractor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DWARFDataExtractor.h; sourceTree = "<group>"; };
 		26ACEC2715E077AE00E94760 /* Property.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Property.h; path = include/lldb/Interpreter/Property.h; sourceTree = "<group>"; };
 		26B167A41123BF5500DC7B4F /* ThreadSafeValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadSafeValue.h; path = include/lldb/Core/ThreadSafeValue.h; sourceTree = "<group>"; };
 		26B1EFAC154638AF00E2DAC7 /* DWARFDeclContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DWARFDeclContext.cpp; sourceTree = "<group>"; };
@@ -2036,6 +2040,8 @@
 				260C89B610F57C5600BB2B04 /* DWARFAttribute.h */,
 				260C89B710F57C5600BB2B04 /* DWARFCompileUnit.cpp */,
 				260C89B810F57C5600BB2B04 /* DWARFCompileUnit.h */,
+				26AB92101819D74600E63F3E /* DWARFDataExtractor.cpp */,
+				26AB92111819D74600E63F3E /* DWARFDataExtractor.h */,
 				260C89B910F57C5600BB2B04 /* DWARFDebugAbbrev.cpp */,
 				260C89BA10F57C5600BB2B04 /* DWARFDebugAbbrev.h */,
 				260C89BB10F57C5600BB2B04 /* DWARFDebugAranges.cpp */,
@@ -3584,6 +3590,7 @@
 				AF254E32170CCC33007AE5C9 /* PlatformDarwinKernel.h in Headers */,
 				2694E99E14FC0BB30076DE67 /* PlatformFreeBSD.h in Headers */,
 				2694E9A514FC0BBD0076DE67 /* PlatformLinux.h in Headers */,
+				26AB92131819D74600E63F3E /* DWARFDataExtractor.h in Headers */,
 				2663E379152BD1890091EC22 /* ReadWriteLock.h in Headers */,
 				945759681534941F005A9070 /* PlatformPOSIX.h in Headers */,
 				26B1EFAF154638AF00E2DAC7 /* DWARFDeclContext.h in Headers */,
@@ -4193,6 +4200,7 @@
 				268900E613353E6F00698AC0 /* Variable.cpp in Sources */,
 				268900E713353E6F00698AC0 /* VariableList.cpp in Sources */,
 				268900E813353E6F00698AC0 /* ABI.cpp in Sources */,
+				26AB92121819D74600E63F3E /* DWARFDataExtractor.cpp in Sources */,
 				268900E913353E6F00698AC0 /* CPPLanguageRuntime.cpp in Sources */,
 				268900EA13353E6F00698AC0 /* DynamicLoader.cpp in Sources */,
 				268900EB13353E6F00698AC0 /* ExecutionContext.cpp in Sources */,

Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=193380&r1=193379&r2=193380&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Thu Oct 24 17:54:08 2013
@@ -4516,6 +4516,130 @@ ObjectFileMachO::GetLLDBSharedCacheUUID
     return uuid;
 }
 
+uint32_t
+ObjectFileMachO::GetMinimumOSVersion (uint32_t *versions, uint32_t num_versions)
+{
+    if (m_min_os_versions.empty())
+    {
+        lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
+        bool success = false;
+        for (uint32_t i=0; success == false && i < m_header.ncmds; ++i)
+        {
+            const lldb::offset_t load_cmd_offset = offset;
+            
+            version_min_command lc;
+            if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
+                break;
+            if (lc.cmd == LC_VERSION_MIN_MACOSX || lc.cmd == LC_VERSION_MIN_IPHONEOS)
+            {
+                if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2))
+                {
+                    const uint32_t xxxx = lc.version >> 16;
+                    const uint32_t yy = (lc.version >> 8) & 0xffu;
+                    const uint32_t zz = lc.version  & 0xffu;
+                    if (xxxx)
+                    {
+                        m_min_os_versions.push_back(xxxx);
+                        if (yy)
+                        {
+                            m_min_os_versions.push_back(yy);
+                            if (zz)
+                                m_min_os_versions.push_back(zz);
+                        }
+                    }
+                    success = true;
+                }
+            }
+            offset = load_cmd_offset + lc.cmdsize;
+        }
+        
+        if (success == false)
+        {
+            // Push an invalid value so we don't keep trying to
+            m_min_os_versions.push_back(UINT32_MAX);
+        }
+    }
+    
+    if (m_min_os_versions.size() > 1 || m_min_os_versions[0] != UINT32_MAX)
+    {
+        if (versions != NULL && num_versions > 0)
+        {
+            for (size_t i=0; i<num_versions; ++i)
+            {
+                if (i < m_min_os_versions.size())
+                    versions[i] = m_min_os_versions[i];
+                else
+                    versions[i] = 0;
+            }
+        }
+        return m_min_os_versions.size();
+    }
+    // Call the superclasses version that will empty out the data
+    return ObjectFile::GetMinimumOSVersion (versions, num_versions);
+}
+
+uint32_t
+ObjectFileMachO::GetSDKVersion(uint32_t *versions, uint32_t num_versions)
+{
+    if (m_sdk_versions.empty())
+    {
+        lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
+        bool success = false;
+        for (uint32_t i=0; success == false && i < m_header.ncmds; ++i)
+        {
+            const lldb::offset_t load_cmd_offset = offset;
+            
+            version_min_command lc;
+            if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
+                break;
+            if (lc.cmd == LC_VERSION_MIN_MACOSX || lc.cmd == LC_VERSION_MIN_IPHONEOS)
+            {
+                if (m_data.GetU32 (&offset, &lc.version, (sizeof(lc) / sizeof(uint32_t)) - 2))
+                {
+                    const uint32_t xxxx = lc.reserved >> 16;
+                    const uint32_t yy = (lc.reserved >> 8) & 0xffu;
+                    const uint32_t zz = lc.reserved  & 0xffu;
+                    if (xxxx)
+                    {
+                        m_sdk_versions.push_back(xxxx);
+                        if (yy)
+                        {
+                            m_sdk_versions.push_back(yy);
+                            if (zz)
+                                m_sdk_versions.push_back(zz);
+                        }
+                    }
+                    success = true;
+                }
+            }
+            offset = load_cmd_offset + lc.cmdsize;
+        }
+        
+        if (success == false)
+        {
+            // Push an invalid value so we don't keep trying to
+            m_sdk_versions.push_back(UINT32_MAX);
+        }
+    }
+    
+    if (m_sdk_versions.size() > 1 || m_sdk_versions[0] != UINT32_MAX)
+    {
+        if (versions != NULL && num_versions > 0)
+        {
+            for (size_t i=0; i<num_versions; ++i)
+            {
+                if (i < m_sdk_versions.size())
+                    versions[i] = m_sdk_versions[i];
+                else
+                    versions[i] = 0;
+            }
+        }
+        return m_sdk_versions.size();
+    }
+    // Call the superclasses version that will empty out the data
+    return ObjectFile::GetSDKVersion (versions, num_versions);
+}
+
 
 //------------------------------------------------------------------
 // PluginInterface protocol

Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h?rev=193380&r1=193379&r2=193380&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h Thu Oct 24 17:54:08 2013
@@ -152,6 +152,12 @@ public:
     virtual uint32_t
     GetVersion (uint32_t *versions, uint32_t num_versions);
 
+    virtual uint32_t
+    GetMinimumOSVersion (uint32_t *versions, uint32_t num_versions);
+    
+    virtual uint32_t
+    GetSDKVersion (uint32_t *versions, uint32_t num_versions);
+
 protected:
 
     static bool
@@ -192,6 +198,8 @@ protected:
     llvm::MachO::dysymtab_command m_dysymtab;
     std::vector<llvm::MachO::segment_command_64> m_mach_segments;
     std::vector<llvm::MachO::section_64> m_mach_sections;
+    std::vector<uint32_t> m_min_os_versions;
+    std::vector<uint32_t> m_sdk_versions;
     typedef lldb_private::RangeVector<uint32_t, uint32_t> FileRangeArray;
     lldb_private::Address  m_entry_point_address;
     FileRangeArray m_thread_context_offsets;

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp?rev=193380&r1=193379&r2=193380&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp Thu Oct 24 17:54:08 2013
@@ -31,6 +31,7 @@
 #include "lldb/Core/StreamString.h"
 #include "lldb/Host/FileSpec.h"
 #include "lldb/Host/Host.h"
+#include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
 
@@ -165,8 +166,83 @@ PlatformMacOSX::~PlatformMacOSX()
 {
 }
 
+ConstString
+PlatformMacOSX::GetSDKDirectory (lldb_private::Target &target)
+{
+    ModuleSP exe_module_sp (target.GetExecutableModule());
+    if (exe_module_sp)
+    {
+        ObjectFile *objfile = exe_module_sp->GetObjectFile();
+        if (objfile)
+        {
+            std::string xcode_contents_path;
+            std::string default_xcode_sdk;
+            FileSpec fspec;
+            uint32_t versions[2];
+            if (objfile->GetSDKVersion(versions, sizeof(versions)))
+            {
+                if (Host::GetLLDBPath (ePathTypeLLDBShlibDir, fspec))
+                {
+                    std::string path;
+                    xcode_contents_path = fspec.GetPath();
+                    size_t pos = xcode_contents_path.find("/Xcode.app/Contents/");
+                    if (pos != std::string::npos)
+                    {
+                        // LLDB.framework is inside an Xcode app bundle, we can locate the SDK from here
+                        xcode_contents_path.erase(pos + strlen("/Xcode.app/Contents/"));
+                    }
+                    else
+                    {
+                        xcode_contents_path.clear();
+                        // Use the selected Xcode
+                        int status = 0;
+                        int signo = 0;
+                        std::string output;
+                        const char *command = "xcrun -sdk macosx --show-sdk-path";
+                        lldb_private::Error error = RunShellCommand (command,   // shell command to run
+                                                                     NULL,      // current working directory
+                                                                     &status,   // Put the exit status of the process in here
+                                                                     &signo,    // Put the signal that caused the process to exit in here
+                                                                     &output,   // Get the output from the command and place it in this string
+                                                                     3);        // Timeout in seconds to wait for shell program to finish
+                        if (status == 0 && !output.empty())
+                        {
+                            size_t first_non_newline = output.find_last_not_of("\r\n");
+                            if (first_non_newline != std::string::npos)
+                                output.erase(first_non_newline+1);
+                            default_xcode_sdk = output;
+                           
+                            pos = default_xcode_sdk.find("/Xcode.app/Contents/");
+                            if (pos != std::string::npos)
+                                xcode_contents_path = default_xcode_sdk.substr(0, pos + strlen("/Xcode.app/Contents/"));
+                        }
+                    }
+                }
+
+                if (!xcode_contents_path.empty())
+                {
+                    StreamString sdk_path;
+                    sdk_path.Printf("%sDeveloper/Platforms/MacOSX.platform/Developer/SDKs/MacOSX%u.%u.sdk", xcode_contents_path.c_str(), versions[0], versions[1]);
+                    fspec.SetFile(sdk_path.GetString().c_str(), false);
+                    if (fspec.Exists())
+                        return ConstString(sdk_path.GetString().c_str());
+                }
+                
+                if (!default_xcode_sdk.empty())
+                {
+                    fspec.SetFile(default_xcode_sdk.c_str(), false);
+                    if (fspec.Exists())
+                        return ConstString(default_xcode_sdk.c_str());
+                }
+            }
+        }
+    }
+    return ConstString();
+}
+
+
 Error
-PlatformMacOSX::GetSymbolFile (const FileSpec &platform_file, 
+PlatformMacOSX::GetSymbolFile (const FileSpec &platform_file,
                                const UUID *uuid_ptr,
                                FileSpec &local_file)
 {

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.h?rev=193380&r1=193379&r2=193380&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.h (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformMacOSX.h Thu Oct 24 17:54:08 2013
@@ -95,6 +95,9 @@ public:
     GetSupportedArchitectureAtIndex (uint32_t idx, 
                                      lldb_private::ArchSpec &arch);
 
+    virtual lldb_private::ConstString
+    GetSDKDirectory (lldb_private::Target &target);
+
 private:
     DISALLOW_COPY_AND_ASSIGN (PlatformMacOSX);
 





More information about the lldb-commits mailing list