Upstreaming the BridgeOS device support and the
LC_BUILD_VERSION load command handling - this
commit is a combination of patches by Adrian
Prantl and myself. llvm::Triple::BridgeOS
isn't defined yet, so all references to that
are currently commented out.
Also update Xcode project file to build the
NativePDB etc plugins.
<rdar://problem/43353615>
llvm-svn: 344209
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 57226bc..c5ba5b9 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -4880,21 +4880,78 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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: