diff options
Diffstat (limited to 'lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp')
-rw-r--r-- | lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp | 291 |
1 files changed, 290 insertions, 1 deletions
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index fb48c01230b..acf99be1388 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -1181,4 +1181,293 @@ void PlatformDarwin::CalculateTrapHandlerSymbolNames () { m_trap_handlers.push_back (ConstString ("_sigtramp")); -} +} + + +static const char *const sdk_strings[] = { + "MacOSX", + "iPhoneSimulator", + "iPhoneOS", +}; + +static FileSpec +GetXcodeContentsPath () +{ + const char substr[] = ".app/Contents/"; + + // First, try based on the current shlib's location + + { + FileSpec fspec; + + if (HostInfo::GetLLDBPath (lldb::ePathTypeLLDBShlibDir, fspec)) + { + std::string path_to_shlib = fspec.GetPath(); + size_t pos = path_to_shlib.rfind(substr); + if (pos != std::string::npos) + { + path_to_shlib.erase(pos + strlen(substr)); + return FileSpec(path_to_shlib.c_str(), false); + } + } + } + + // Fall back to using xcrun + + { + int status = 0; + int signo = 0; + std::string output; + const char *command = "xcrun -sdk macosx --show-sdk-path"; + lldb_private::Error error = Host::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); + } + + size_t pos = output.rfind(substr); + if (pos != std::string::npos) + { + output.erase(pos + strlen(substr)); + return FileSpec(output.c_str(), false); + } + } + } + + return FileSpec(); +} + +bool +PlatformDarwin::SDKSupportsModules (SDKType sdk_type, uint32_t major, uint32_t minor, uint32_t micro) +{ + switch (sdk_type) + { + default: + return false; + case SDKType::MacOSX: + if (major > 10 || (major == 10 && minor >= 10)) + return true; + break; + case SDKType::iPhoneOS: + case SDKType::iPhoneSimulator: + if (major >= 8) + return true; + break; + } + + return false; +} + +bool +PlatformDarwin::SDKSupportsModules (SDKType desired_type, const FileSpec &sdk_path) +{ + ConstString last_path_component = sdk_path.GetLastPathComponent(); + + if (last_path_component) + { + const llvm::StringRef sdk_name = last_path_component.GetStringRef(); + + llvm::StringRef version_part; + + if (sdk_name.startswith(sdk_strings[(int)desired_type])) + { + version_part = sdk_name.drop_front(strlen(sdk_strings[(int)desired_type])); + } + else + { + return false; + } + + const size_t major_dot_offset = version_part.find('.'); + if (major_dot_offset == llvm::StringRef::npos) + return false; + + const llvm::StringRef major_version = version_part.slice(0, major_dot_offset); + const llvm::StringRef minor_part = version_part.drop_front(major_dot_offset + 1); + + const size_t minor_dot_offset = minor_part.find('.'); + if (minor_dot_offset == llvm::StringRef::npos) + return false; + + const llvm::StringRef minor_version = minor_part.slice(0, minor_dot_offset); + + unsigned int major = 0; + unsigned int minor = 0; + unsigned int micro = 0; + + if (major_version.getAsInteger(10, major)) + return false; + + if (minor_version.getAsInteger(10, minor)) + return false; + + return SDKSupportsModules(desired_type, major, minor, micro); + } + + return false; +} + +FileSpec::EnumerateDirectoryResult +PlatformDarwin::DirectoryEnumerator(void *baton, + FileSpec::FileType file_type, + const FileSpec &spec) +{ + SDKEnumeratorInfo *enumerator_info = static_cast<SDKEnumeratorInfo*>(baton); + + if (SDKSupportsModules(enumerator_info->sdk_type, spec)) + { + enumerator_info->found_path = spec; + return FileSpec::EnumerateDirectoryResult::eEnumerateDirectoryResultNext; + } + + return FileSpec::EnumerateDirectoryResult::eEnumerateDirectoryResultNext; +}; + +FileSpec +PlatformDarwin::FindSDKInXcodeForModules (SDKType sdk_type, + const FileSpec &sdks_spec) +{ + // Look inside Xcode for the required installed iOS SDK version + + if (!sdks_spec.IsDirectory()) + return FileSpec(); + + const bool find_directories = true; + const bool find_files = false; + const bool find_other = true; // include symlinks + + SDKEnumeratorInfo enumerator_info; + + enumerator_info.sdk_type = sdk_type; + + FileSpec::EnumerateDirectory(sdks_spec.GetPath().c_str(), + find_directories, + find_files, + find_other, + DirectoryEnumerator, + &enumerator_info); + + if (enumerator_info.found_path.IsDirectory()) + return enumerator_info.found_path; + else + return FileSpec(); +} + +FileSpec +PlatformDarwin::GetSDKDirectoryForModules (SDKType sdk_type) +{ + switch (sdk_type) + { + default: + return FileSpec(); + case SDKType::MacOSX: + case SDKType::iPhoneSimulator: + case SDKType::iPhoneOS: + break; + } + + FileSpec sdks_spec = GetXcodeContentsPath(); + sdks_spec.AppendPathComponent("Developer"); + sdks_spec.AppendPathComponent("Platforms"); + + switch (sdk_type) + { + default: + return FileSpec(); + case SDKType::MacOSX: + sdks_spec.AppendPathComponent("MacOSX.platform"); + break; + case SDKType::iPhoneSimulator: + sdks_spec.AppendPathComponent("iPhoneSimulator.platform"); + break; + case SDKType::iPhoneOS: + sdks_spec.AppendPathComponent("iPhoneOS.platform"); + break; + } + + sdks_spec.AppendPathComponent("Developer"); + sdks_spec.AppendPathComponent("SDKs"); + + if (sdk_type == SDKType::MacOSX) + { + uint32_t major = 0; + uint32_t minor = 0; + uint32_t micro = 0; + + if (HostInfo::GetOSVersion(major, minor, micro)) + { + if (SDKSupportsModules(SDKType::MacOSX, major, minor, micro)) + { + // We slightly prefer the exact SDK for this machine. See if it is there. + + FileSpec native_sdk_spec = sdks_spec; + StreamString native_sdk_name; + native_sdk_name.Printf("MacOSX%u.%u.sdk", major, minor); + native_sdk_spec.AppendPathComponent(native_sdk_name.GetString().c_str()); + + if (native_sdk_spec.Exists()) + { + return native_sdk_spec; + } + } + } + } + + return FindSDKInXcodeForModules(sdk_type, sdks_spec); +} + +void +PlatformDarwin::AddClangModuleCompilationOptionsForSDKType (std::vector<std::string> &options, SDKType sdk_type) +{ + const std::vector<std::string> apple_arguments = + { + "-x", "objective-c++", + "-fobjc-arc", + "-fblocks", + "-D_ISO646_H", + "-D__ISO646_H" + }; + + options.insert(options.end(), + apple_arguments.begin(), + apple_arguments.end()); + + StreamString minimum_version_option; + unsigned int major = 0, minor = 0, micro = 0; + GetOSVersion(major, minor, micro); + if (micro == UINT32_MAX) + micro = 0; // FIXME who actually likes this behavior? + + switch (sdk_type) + { + case SDKType::iPhoneOS: + minimum_version_option.PutCString("-mios-version-min="); + minimum_version_option.PutCString(clang::VersionTuple(major, minor, micro).getAsString().c_str()); + break; + case SDKType::iPhoneSimulator: + minimum_version_option.PutCString("-mios-simulator-version-min="); + minimum_version_option.PutCString(clang::VersionTuple(major, minor, micro).getAsString().c_str()); + break; + case SDKType::MacOSX: + minimum_version_option.PutCString("-mmacosx-version-min="); + minimum_version_option.PutCString(clang::VersionTuple(major, minor, micro).getAsString().c_str()); + } + + options.push_back(minimum_version_option.GetString()); + + FileSpec sysroot_spec = GetSDKDirectoryForModules(sdk_type); + + if (sysroot_spec.IsDirectory()) + { + options.push_back("-isysroot"); + options.push_back(sysroot_spec.GetPath()); + } +} |