diff options
Diffstat (limited to 'lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp')
| -rw-r--r-- | lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp | 185 |
1 files changed, 166 insertions, 19 deletions
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index 57226bc4d85..c5ba5b94f21 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -4880,21 +4880,78 @@ bool ObjectFileMachO::GetUUID(const llvm::MachO::mach_header &header, return false; } -static const char *GetOSName(uint32_t cmd) { +static llvm::StringRef GetOSName(uint32_t cmd) { switch (cmd) { case llvm::MachO::LC_VERSION_MIN_IPHONEOS: - return "ios"; + return llvm::Triple::getOSTypeName(llvm::Triple::IOS); case llvm::MachO::LC_VERSION_MIN_MACOSX: - return "macosx"; + return llvm::Triple::getOSTypeName(llvm::Triple::MacOSX); case llvm::MachO::LC_VERSION_MIN_TVOS: - return "tvos"; + return llvm::Triple::getOSTypeName(llvm::Triple::TvOS); case llvm::MachO::LC_VERSION_MIN_WATCHOS: - return "watchos"; + return llvm::Triple::getOSTypeName(llvm::Triple::WatchOS); default: llvm_unreachable("unexpected LC_VERSION load command"); } } +namespace { + struct OSEnv { + llvm::StringRef os_type; + llvm::StringRef environment; + OSEnv(uint32_t cmd) { + switch (cmd) { + case PLATFORM_MACOS: + os_type = llvm::Triple::getOSTypeName(llvm::Triple::MacOSX); + return; + case PLATFORM_IOS: + os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS); + return; + case PLATFORM_TVOS: + os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS); + return; + case PLATFORM_WATCHOS: + os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS); + return; +// NEED_BRIDGEOS_TRIPLE case PLATFORM_BRIDGEOS: +// NEED_BRIDGEOS_TRIPLE os_type = llvm::Triple::getOSTypeName(llvm::Triple::BridgeOS); +// NEED_BRIDGEOS_TRIPLE return; +#if defined (PLATFORM_IOSSIMULATOR) && defined (PLATFORM_TVOSSIMULATOR) && defined (PLATFORM_WATCHOSSIMULATOR) + case PLATFORM_IOSSIMULATOR: + os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS); + environment = + llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator); + return; + case PLATFORM_TVOSSIMULATOR: + os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS); + environment = + llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator); + return; + case PLATFORM_WATCHOSSIMULATOR: + os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS); + environment = + llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator); + return; +#endif + default: { + Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS | + LIBLLDB_LOG_PROCESS)); + if (log) + log->Printf("unsupported platform in LC_BUILD_VERSION"); + } + } + } + }; + + struct MinOS { + uint32_t major, minor, patch; + MinOS(uint32_t version) + : major(version >> 16), + minor((version >> 8) & 0xffu), + patch(version & 0xffu) {} + }; +} // namespace + bool ObjectFileMachO::GetArchitecture(const llvm::MachO::mach_header &header, const lldb_private::DataExtractor &data, lldb::offset_t lc_offset, @@ -4926,36 +4983,34 @@ bool ObjectFileMachO::GetArchitecture(const llvm::MachO::mach_header &header, return true; } else { struct load_command load_cmd; + llvm::SmallString<16> os_name; + llvm::raw_svector_ostream os(os_name); + // See if there is an LC_VERSION_MIN_* load command that can give + // us the OS type. lldb::offset_t offset = lc_offset; for (uint32_t i = 0; i < header.ncmds; ++i) { const lldb::offset_t cmd_offset = offset; if (data.GetU32(&offset, &load_cmd, 2) == NULL) break; - uint32_t major, minor, patch; struct version_min_command version_min; - - llvm::SmallString<16> os_name; - llvm::raw_svector_ostream os(os_name); - switch (load_cmd.cmd) { case llvm::MachO::LC_VERSION_MIN_IPHONEOS: case llvm::MachO::LC_VERSION_MIN_MACOSX: case llvm::MachO::LC_VERSION_MIN_TVOS: - case llvm::MachO::LC_VERSION_MIN_WATCHOS: + case llvm::MachO::LC_VERSION_MIN_WATCHOS: { if (load_cmd.cmdsize != sizeof(version_min)) break; - data.ExtractBytes(cmd_offset, - sizeof(version_min), data.GetByteOrder(), - &version_min); - major = version_min.version >> 16; - minor = (version_min.version >> 8) & 0xffu; - patch = version_min.version & 0xffu; - os << GetOSName(load_cmd.cmd) << major << '.' << minor << '.' - << patch; + if (data.ExtractBytes(cmd_offset, sizeof(version_min), + data.GetByteOrder(), &version_min) == 0) + break; + MinOS min_os(version_min.version); + os << GetOSName(load_cmd.cmd) << min_os.major << '.' << min_os.minor + << '.' << min_os.patch; triple.setOSName(os.str()); return true; + } default: break; } @@ -4963,6 +5018,35 @@ bool ObjectFileMachO::GetArchitecture(const llvm::MachO::mach_header &header, offset = cmd_offset + load_cmd.cmdsize; } + // See if there is an LC_BUILD_VERSION load command that can give + // us the OS type. + + offset = lc_offset; + for (uint32_t i = 0; i < header.ncmds; ++i) { + const lldb::offset_t cmd_offset = offset; + if (data.GetU32(&offset, &load_cmd, 2) == NULL) + break; + + if (load_cmd.cmd == llvm::MachO::LC_BUILD_VERSION) { + struct build_version_command build_version; + if (load_cmd.cmdsize != sizeof(build_version)) + if (data.ExtractBytes(cmd_offset, sizeof(build_version), + data.GetByteOrder(), &build_version) == 0) + continue; + MinOS min_os(build_version.minos); + OSEnv os_env(build_version.platform); + if (os_env.os_type.empty()) + continue; + os << os_env.os_type << min_os.major << '.' << min_os.minor << '.' + << min_os.patch; + triple.setOSName(os.str()); + if (!os_env.environment.empty()) + triple.setEnvironmentName(os_env.environment); + return true; + } + offset = cmd_offset + load_cmd.cmdsize; + } + if (header.filetype != MH_KEXT_BUNDLE) { // We didn't find a LC_VERSION_MIN load command and this isn't a KEXT // so lets not say our Vendor is Apple, leave it as an unspecified @@ -5727,8 +5811,30 @@ llvm::VersionTuple ObjectFileMachO::GetMinimumOSVersion() { m_min_os_version = llvm::VersionTuple(xxxx, yy, zz); break; } + } + } else if (lc.cmd == llvm::MachO::LC_BUILD_VERSION) { + // struct build_version_command { + // uint32_t cmd; /* LC_BUILD_VERSION */ + // uint32_t cmdsize; /* sizeof(struct build_version_command) plus */ + // /* ntools * sizeof(struct build_tool_version) */ + // uint32_t platform; /* platform */ + // uint32_t minos; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ + // uint32_t sdk; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ + // uint32_t ntools; /* number of tool entries following this */ + // }; + + offset += 4; // skip platform + uint32_t minos = m_data.GetU32(&offset); + + const uint32_t xxxx = minos >> 16; + const uint32_t yy = (minos >> 8) & 0xffu; + const uint32_t zz = minos & 0xffu; + if (xxxx) { + m_min_os_version = llvm::VersionTuple(xxxx, yy, zz); + break; } } + offset = load_cmd_offset + lc.cmdsize; } @@ -5775,6 +5881,46 @@ uint32_t ObjectFileMachO::GetSDKVersion(uint32_t *versions, offset = load_cmd_offset + lc.cmdsize; } + if (success == false) + { + offset = MachHeaderSizeFromMagic(m_header.magic); + 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 == llvm::MachO::LC_BUILD_VERSION) + { + // struct build_version_command { + // uint32_t cmd; /* LC_BUILD_VERSION */ + // uint32_t cmdsize; /* sizeof(struct build_version_command) plus */ + // /* ntools * sizeof(struct build_tool_version) */ + // uint32_t platform; /* platform */ + // uint32_t minos; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ + // uint32_t sdk; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ + // uint32_t ntools; /* number of tool entries following this */ + // }; + + offset += 4; // skip platform + uint32_t minos = m_data.GetU32(&offset); + + const uint32_t xxxx = minos >> 16; + const uint32_t yy = (minos >> 8) & 0xffu; + const uint32_t zz = minos & 0xffu; + if (xxxx) + { + m_sdk_versions.push_back (xxxx); + m_sdk_versions.push_back (yy); + 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 try to find // the version # again on the next call to this @@ -5944,6 +6090,7 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp, target_triple.getOS() == llvm::Triple::IOS || target_triple.getOS() == llvm::Triple::WatchOS || target_triple.getOS() == llvm::Triple::TvOS)) { + // NEED_BRIDGEOS_TRIPLE target_triple.getOS() == llvm::Triple::BridgeOS)) { bool make_core = false; switch (target_arch.GetMachine()) { case llvm::Triple::aarch64: |

