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: