Generate version min load commands when the platform is unknown.

In the case where we are emitting to an object file, the platform is
possibly unknown, and the source object files contained load commands
for version min, we can take the maximum of those min versions and
emit in in the output object file.

This test also tests r259739.

llvm-svn: 259742
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
index d46cf2c..0eb2b11 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
@@ -317,6 +317,10 @@
                                + file.sections.size() * sectsSize
                                + sizeof(symtab_command);
     _countOfLoadCommands = 2;
+    if (file.hasMinVersionLoadCommand) {
+      _endOfLoadCommands += sizeof(version_min_command);
+      _countOfLoadCommands++;
+    }
     if (!_file.dataInCode.empty()) {
       _endOfLoadCommands += sizeof(linkedit_data_command);
       _countOfLoadCommands++;
@@ -738,6 +742,38 @@
   return std::error_code();
 }
 
+static void writeVersionMinLoadCommand(const NormalizedFile &_file,
+                                       bool _swap,
+                                       uint8_t *&lc) {
+  if (!_file.hasMinVersionLoadCommand)
+    return;
+  version_min_command *vm = reinterpret_cast<version_min_command*>(lc);
+  switch (_file.os) {
+    case MachOLinkingContext::OS::unknown:
+      vm->cmd     = _file.minOSVersionKind;
+      vm->cmdsize = sizeof(version_min_command);
+      vm->version = _file.minOSverson;
+      vm->sdk     = 0;
+      break;
+    case MachOLinkingContext::OS::macOSX:
+      vm->cmd     = LC_VERSION_MIN_MACOSX;
+      vm->cmdsize = sizeof(version_min_command);
+      vm->version = _file.minOSverson;
+      vm->sdk     = _file.sdkVersion;
+      break;
+    case MachOLinkingContext::OS::iOS:
+    case MachOLinkingContext::OS::iOS_simulator:
+      vm->cmd     = LC_VERSION_MIN_IPHONEOS;
+      vm->cmdsize = sizeof(version_min_command);
+      vm->version = _file.minOSverson;
+      vm->sdk     = _file.sdkVersion;
+      break;
+  }
+  if (_swap)
+    swapStruct(*vm);
+  lc += sizeof(version_min_command);
+}
+
 std::error_code MachOFileLayout::writeLoadCommands() {
   std::error_code ec;
   uint8_t *lc = &_buffer[_startOfLoadCommands];
@@ -759,6 +795,11 @@
     if (_swap)
       swapStruct(*st);
     lc += sizeof(symtab_command);
+
+    // Add LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS,
+    // LC_VERSION_MIN_WATCHOS, LC_VERSION_MIN_TVOS
+    writeVersionMinLoadCommand(_file, _swap, lc);
+
     // Add LC_DATA_IN_CODE if needed.
     if (_dataInCodeSize != 0) {
       linkedit_data_command* dl = reinterpret_cast<linkedit_data_command*>(lc);
@@ -872,32 +913,7 @@
 
     // Add LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_WATCHOS,
     // LC_VERSION_MIN_TVOS
-    if (_file.hasMinVersionLoadCommand) {
-      version_min_command *vm = reinterpret_cast<version_min_command*>(lc);
-      switch (_file.os) {
-        case MachOLinkingContext::OS::unknown:
-          // TODO: We need to emit the load command if we managed to derive
-          // a platform from one of the files we are linking.
-          llvm_unreachable("Version commands for unknown OS aren't supported");
-          break;
-        case MachOLinkingContext::OS::macOSX:
-          vm->cmd     = LC_VERSION_MIN_MACOSX;
-          vm->cmdsize = sizeof(version_min_command);
-          vm->version = _file.minOSverson;
-          vm->sdk     = _file.sdkVersion;
-          break;
-        case MachOLinkingContext::OS::iOS:
-        case MachOLinkingContext::OS::iOS_simulator:
-          vm->cmd     = LC_VERSION_MIN_MACOSX;
-          vm->cmdsize = sizeof(version_min_command);
-          vm->version = _file.minOSverson;
-          vm->sdk     = _file.sdkVersion;
-          break;
-      }
-      if (_swap)
-        swapStruct(*vm);
-      lc += sizeof(version_min_command);
-    }
+    writeVersionMinLoadCommand(_file, _swap, lc);
 
     // If main executable, add LC_MAIN.
     if (_file.fileType == llvm::MachO::MH_EXECUTE) {