[lld] 5c835e1 - [lld][MachO] Add support for LC_VERSION_MIN_* load commands

Alexander Shaposhnikov via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 21 05:59:23 PDT 2021


Author: Alexander Shaposhnikov
Date: 2021-04-21T05:41:14-07:00
New Revision: 5c835e1ae5e177591ddb64be3f6a473ef6bfa4bb

URL: https://github.com/llvm/llvm-project/commit/5c835e1ae5e177591ddb64be3f6a473ef6bfa4bb
DIFF: https://github.com/llvm/llvm-project/commit/5c835e1ae5e177591ddb64be3f6a473ef6bfa4bb.diff

LOG: [lld][MachO] Add support for LC_VERSION_MIN_* load commands

This diff adds initial support for the legacy LC_VERSION_MIN_* load commands.

Test plan: make check-lld-macho

Differential revision: https://reviews.llvm.org/D100523

Added: 
    

Modified: 
    lld/MachO/Config.h
    lld/MachO/Driver.cpp
    lld/MachO/InputFiles.cpp
    lld/MachO/InputFiles.h
    lld/MachO/LTO.cpp
    lld/MachO/MapFile.cpp
    lld/MachO/OutputSegment.cpp
    lld/MachO/SyntheticSections.cpp
    lld/MachO/Writer.cpp
    lld/test/MachO/lc-build-version.s
    lld/test/MachO/load-command-sequence.s
    lld/test/MachO/local-got.s
    lld/test/MachO/x86-64-relocs.s

Removed: 
    


################################################################################
diff  --git a/lld/MachO/Config.h b/lld/MachO/Config.h
index d36a290fa66c..def14abc5b51 100644
--- a/lld/MachO/Config.h
+++ b/lld/MachO/Config.h
@@ -33,6 +33,7 @@ using SectionRenameMap = llvm::DenseMap<NamePair, NamePair>;
 using SegmentRenameMap = llvm::DenseMap<llvm::StringRef, llvm::StringRef>;
 
 struct PlatformInfo {
+  llvm::MachO::Target target;
   llvm::VersionTuple minimum;
   llvm::VersionTuple sdk;
 };
@@ -101,7 +102,6 @@ struct Configuration {
   llvm::StringRef ltoObjPath;
   llvm::StringRef thinLTOJobs;
   bool demangle = false;
-  llvm::MachO::Target target;
   PlatformInfo platformInfo;
   NamespaceKind namespaceKind = NamespaceKind::twolevel;
   UndefinedSymbolTreatment undefinedSymbolTreatment =

diff  --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 6591f73ffac0..32d70495cf87 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -616,9 +616,10 @@ static TargetInfo *createTargetInfo(InputArgList &args) {
     fatal("must specify -arch");
   PlatformKind platform = parsePlatformVersion(args);
 
-  config->target = MachO::Target(getArchitectureFromName(archName), platform);
+  config->platformInfo.target =
+      MachO::Target(getArchitectureFromName(archName), platform);
 
-  switch (getCPUTypeFromArchitecture(config->target.Arch).first) {
+  switch (getCPUTypeFromArchitecture(config->platformInfo.target.Arch).first) {
   case CPU_TYPE_X86_64:
     return createX86_64TargetInfo();
   case CPU_TYPE_ARM64:
@@ -699,17 +700,18 @@ static const char *getReproduceOption(InputArgList &args) {
 static bool isPie(InputArgList &args) {
   if (config->outputType != MH_EXECUTE || args.hasArg(OPT_no_pie))
     return false;
-  if (config->target.Arch == AK_arm64 || config->target.Arch == AK_arm64e ||
-      config->target.Arch == AK_arm64_32)
+  if (config->platformInfo.target.Arch == AK_arm64 ||
+      config->platformInfo.target.Arch == AK_arm64e ||
+      config->platformInfo.target.Arch == AK_arm64_32)
     return true;
 
   // TODO: add logic here as we support more archs. E.g. i386 should default
   // to PIE from 10.7
-  assert(config->target.Arch == AK_x86_64 ||
-         config->target.Arch == AK_x86_64h ||
-         config->target.Arch == AK_arm64_32);
+  assert(config->platformInfo.target.Arch == AK_x86_64 ||
+         config->platformInfo.target.Arch == AK_x86_64h ||
+         config->platformInfo.target.Arch == AK_arm64_32);
 
-  PlatformKind kind = config->target.Platform;
+  PlatformKind kind = config->platformInfo.target.Platform;
   if (kind == PlatformKind::macOS &&
       config->platformInfo.minimum >= VersionTuple(10, 6))
     return true;
@@ -1029,7 +1031,7 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
     StringRef segName = arg->getValue(0);
     uint32_t maxProt = parseProtection(arg->getValue(1));
     uint32_t initProt = parseProtection(arg->getValue(2));
-    if (maxProt != initProt && config->target.Arch != AK_i386)
+    if (maxProt != initProt && config->platformInfo.target.Arch != AK_i386)
       error("invalid argument '" + arg->getAsString(args) +
             "': max and init must be the same for non-i386 archs");
     if (segName == segment_names::linkEdit)
@@ -1051,8 +1053,9 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
 
   config->adhocCodesign = args.hasFlag(
       OPT_adhoc_codesign, OPT_no_adhoc_codesign,
-      (config->target.Arch == AK_arm64 || config->target.Arch == AK_arm64e) &&
-          config->target.Platform == PlatformKind::macOS);
+      (config->platformInfo.target.Arch == AK_arm64 ||
+       config->platformInfo.target.Arch == AK_arm64e) &&
+          config->platformInfo.target.Platform == PlatformKind::macOS);
 
   if (args.hasArg(OPT_v)) {
     message(getLLDVersion());

diff  --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp
index 139b4cdded46..6edeb2ccc284 100644
--- a/lld/MachO/InputFiles.cpp
+++ b/lld/MachO/InputFiles.cpp
@@ -95,6 +95,71 @@ SetVector<InputFile *> macho::inputFiles;
 std::unique_ptr<TarWriter> macho::tar;
 int InputFile::idCount = 0;
 
+static VersionTuple decodeVersion(uint32_t version) {
+  unsigned major = version >> 16;
+  unsigned minor = (version >> 8) & 0xffu;
+  unsigned subMinor = version & 0xffu;
+  return VersionTuple(major, minor, subMinor);
+}
+
+template <class LP>
+static Optional<PlatformInfo> getPlatformInfo(const InputFile *input) {
+  if (!isa<ObjFile>(input) && !isa<DylibFile>(input))
+    return None;
+
+  using Header = typename LP::mach_header;
+  auto *hdr = reinterpret_cast<const Header *>(input->mb.getBufferStart());
+  PlatformInfo platformInfo;
+  if (const auto *cmd =
+          findCommand<build_version_command>(hdr, LC_BUILD_VERSION)) {
+    platformInfo.target.Platform = static_cast<PlatformKind>(cmd->platform);
+    platformInfo.minimum = decodeVersion(cmd->minos);
+    return platformInfo;
+  } else if (const auto *cmd =
+                 findCommand<version_min_command>(hdr, LC_VERSION_MIN_MACOSX)) {
+    platformInfo.target.Platform = PlatformKind::macOS;
+    platformInfo.minimum = decodeVersion(cmd->version);
+    return platformInfo;
+  } else if (const auto *cmd = findCommand<version_min_command>(
+                 hdr, LC_VERSION_MIN_IPHONEOS)) {
+    platformInfo.target.Platform = PlatformKind::iOS;
+    platformInfo.minimum = decodeVersion(cmd->version);
+    return platformInfo;
+  } else if (const auto *cmd =
+                 findCommand<version_min_command>(hdr, LC_VERSION_MIN_TVOS)) {
+    platformInfo.target.Platform = PlatformKind::tvOS;
+    platformInfo.minimum = decodeVersion(cmd->version);
+  } else if (const auto *cmd = findCommand<version_min_command>(
+                 hdr, LC_VERSION_MIN_WATCHOS)) {
+    platformInfo.target.Platform = PlatformKind::watchOS;
+    platformInfo.minimum = decodeVersion(cmd->version);
+    return platformInfo;
+  }
+
+  return None;
+}
+
+template <class LP> static bool checkCompatibility(const InputFile *input) {
+  Optional<PlatformInfo> platformInfo = getPlatformInfo<LP>(input);
+  if (!platformInfo)
+    return true;
+  // TODO: Correctly detect simulator platforms or relax this check.
+  if (config->platformInfo.target.Platform != platformInfo->target.Platform) {
+    error(toString(input) + " has platform " +
+          getPlatformName(platformInfo->target.Platform) +
+          Twine(", which is 
diff erent from target platform ") +
+          getPlatformName(config->platformInfo.target.Platform));
+    return false;
+  }
+  if (platformInfo->minimum >= config->platformInfo.minimum)
+    return true;
+  error(toString(input) + " has version " +
+        platformInfo->minimum.getAsString() +
+        ", which is incompatible with target version of " +
+        config->platformInfo.minimum.getAsString());
+  return false;
+}
+
 // Open a given file path and return it as a memory-mapped file.
 Optional<MemoryBufferRef> macho::readFile(StringRef path) {
   // Open a file.
@@ -365,32 +430,6 @@ static macho::Symbol *createDefined(const NList &sym, StringRef name,
                        /*isExternal=*/false, /*isPrivateExtern=*/false);
 }
 
-// Checks if the version specified in `cmd` is compatible with target
-// version. IOW, check if cmd's version >= config's version.
-static bool hasCompatVersion(const InputFile *input,
-                             const build_version_command *cmd) {
-
-  if (config->target.Platform != static_cast<PlatformKind>(cmd->platform)) {
-    error(toString(input) + " has platform " +
-          getPlatformName(static_cast<PlatformKind>(cmd->platform)) +
-          Twine(", which is 
diff erent from target platform ") +
-          getPlatformName(config->target.Platform));
-    return false;
-  }
-
-  unsigned major = cmd->minos >> 16;
-  unsigned minor = (cmd->minos >> 8) & 0xffu;
-  unsigned subMinor = cmd->minos & 0xffu;
-  VersionTuple version(major, minor, subMinor);
-  if (version >= config->platformInfo.minimum)
-    return true;
-
-  error(toString(input) + " has version " + version.getAsString() +
-        ", which is incompatible with target version of " +
-        config->platformInfo.minimum.getAsString());
-  return false;
-}
-
 // Absolute symbols are defined symbols that do not have an associated
 // InputSection. They cannot be weak.
 template <class NList>
@@ -542,18 +581,15 @@ template <class LP> void ObjFile::parse() {
   auto *hdr = reinterpret_cast<const Header *>(mb.getBufferStart());
 
   Architecture arch = getArchitectureFromCpuType(hdr->cputype, hdr->cpusubtype);
-  if (arch != config->target.Arch) {
+  if (arch != config->platformInfo.target.Arch) {
     error(toString(this) + " has architecture " + getArchitectureName(arch) +
           " which is incompatible with target architecture " +
-          getArchitectureName(config->target.Arch));
+          getArchitectureName(config->platformInfo.target.Arch));
     return;
   }
 
-  if (const auto *cmd =
-          findCommand<build_version_command>(hdr, LC_BUILD_VERSION)) {
-    if (!hasCompatVersion(this, cmd))
-      return;
-  }
+  if (!checkCompatibility<LP>(this))
+    return;
 
   if (const load_command *cmd = findCommand(hdr, LC_LINKER_OPTION)) {
     auto *c = reinterpret_cast<const linker_option_command *>(cmd);
@@ -719,11 +755,8 @@ template <class LP> void DylibFile::parse(DylibFile *umbrella) {
     return;
   }
 
-  if (const build_version_command *cmd =
-          findCommand<build_version_command>(hdr, LC_BUILD_VERSION)) {
-    if (!hasCompatVersion(this, cmd))
-      return;
-  }
+  if (!checkCompatibility<LP>(this))
+    return;
 
   // Initialize symbols.
   DylibFile *exportingFile = isImplicitlyLinked(dylibName) ? this : umbrella;
@@ -791,9 +824,9 @@ DylibFile::DylibFile(const InterfaceFile &interface, DylibFile *umbrella,
       "/usr/lib/system/libsystem_pthread.dylib"};
 
   if (!is_contained(skipPlatformChecks, dylibName) &&
-      !is_contained(interface.targets(), config->target)) {
+      !is_contained(interface.targets(), config->platformInfo.target)) {
     error(toString(this) + " is incompatible with " +
-          std::string(config->target));
+          std::string(config->platformInfo.target));
     return;
   }
 
@@ -806,7 +839,7 @@ DylibFile::DylibFile(const InterfaceFile &interface, DylibFile *umbrella,
   // TODO(compnerd) filter out symbols based on the target platform
   // TODO: handle weak defs, thread locals
   for (const auto *symbol : interface.symbols()) {
-    if (!symbol->getArchitectures().has(config->target.Arch))
+    if (!symbol->getArchitectures().has(config->platformInfo.target.Arch))
       continue;
 
     switch (symbol->getKind()) {
@@ -834,7 +867,7 @@ DylibFile::DylibFile(const InterfaceFile &interface, DylibFile *umbrella,
   for (InterfaceFileRef intfRef : interface.reexportedLibraries()) {
     InterfaceFile::const_target_range targets = intfRef.targets();
     if (is_contained(skipPlatformChecks, intfRef.getInstallName()) ||
-        is_contained(targets, config->target))
+        is_contained(targets, config->platformInfo.target))
       loadReexport(intfRef.getInstallName(), exportingFile, topLevel);
   }
 }

diff  --git a/lld/MachO/InputFiles.h b/lld/MachO/InputFiles.h
index e3f04944df85..6ead6900e19c 100644
--- a/lld/MachO/InputFiles.h
+++ b/lld/MachO/InputFiles.h
@@ -37,6 +37,7 @@ class TarWriter;
 namespace lld {
 namespace macho {
 
+struct PlatformInfo;
 class InputSection;
 class Symbol;
 struct Reloc;

diff  --git a/lld/MachO/LTO.cpp b/lld/MachO/LTO.cpp
index f04b950553f8..a3d4b44749cb 100644
--- a/lld/MachO/LTO.cpp
+++ b/lld/MachO/LTO.cpp
@@ -117,9 +117,10 @@ std::vector<ObjFile *> BitcodeCompiler::compile() {
     uint32_t modTime = 0;
     if (!config->ltoObjPath.empty()) {
       filePath = config->ltoObjPath;
-      path::append(filePath, Twine(i) + "." +
-                                 getArchitectureName(config->target.Arch) +
-                                 ".lto.o");
+      path::append(filePath,
+                   Twine(i) + "." +
+                       getArchitectureName(config->platformInfo.target.Arch) +
+                       ".lto.o");
       saveBuffer(buf[i], filePath);
       modTime = getModTime(filePath);
     }

diff  --git a/lld/MachO/MapFile.cpp b/lld/MachO/MapFile.cpp
index acc89e405a54..42726809ff64 100644
--- a/lld/MachO/MapFile.cpp
+++ b/lld/MachO/MapFile.cpp
@@ -108,8 +108,9 @@ void macho::writeMapFile() {
   os << format("# Path: %s\n", config->outputFile.str().c_str());
 
   // Dump output architecture.
-  os << format("# Arch: %s\n",
-               getArchitectureName(config->target.Arch).str().c_str());
+  os << format(
+      "# Arch: %s\n",
+      getArchitectureName(config->platformInfo.target.Arch).str().c_str());
 
   // Dump table of object files.
   os << "# Object files:\n";

diff  --git a/lld/MachO/OutputSegment.cpp b/lld/MachO/OutputSegment.cpp
index 71da2ef8eb48..039001b8e13d 100644
--- a/lld/MachO/OutputSegment.cpp
+++ b/lld/MachO/OutputSegment.cpp
@@ -37,7 +37,7 @@ static uint32_t initProt(StringRef name) {
 }
 
 static uint32_t maxProt(StringRef name) {
-  assert(config->target.Arch != AK_i386 &&
+  assert(config->platformInfo.target.Arch != AK_i386 &&
          "TODO: i386 has 
diff erent maxProt requirements");
   return initProt(name);
 }

diff  --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index 72854bc0d68b..afa6777f8ecc 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -93,7 +93,7 @@ static uint32_t cpuSubtype() {
 
   if (config->outputType == MH_EXECUTE && !config->staticLink &&
       target->cpuSubtype == CPU_SUBTYPE_X86_64_ALL &&
-      config->target.Platform == PlatformKind::macOS &&
+      config->platformInfo.target.Platform == PlatformKind::macOS &&
       config->platformInfo.minimum >= VersionTuple(10, 5))
     subtype |= CPU_SUBTYPE_LIB64;
 

diff  --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index b2ce72e84fc3..7cd3de863913 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -359,10 +359,54 @@ class LCRPath : public LoadCommand {
   StringRef path;
 };
 
+static uint32_t encodeVersion(const VersionTuple &version) {
+  return ((version.getMajor() << 020) |
+          (version.getMinor().getValueOr(0) << 010) |
+          version.getSubminor().getValueOr(0));
+}
+
+class LCMinVersion : public LoadCommand {
+public:
+  explicit LCMinVersion(const PlatformInfo &platformInfo)
+      : platformInfo(platformInfo) {}
+
+  uint32_t getSize() const override { return sizeof(version_min_command); }
+
+  void writeTo(uint8_t *buf) const override {
+    auto *c = reinterpret_cast<version_min_command *>(buf);
+    switch (platformInfo.target.Platform) {
+    case PlatformKind::macOS:
+      c->cmd = LC_VERSION_MIN_MACOSX;
+      break;
+    case PlatformKind::iOS:
+    case PlatformKind::iOSSimulator:
+      c->cmd = LC_VERSION_MIN_IPHONEOS;
+      break;
+    case PlatformKind::tvOS:
+    case PlatformKind::tvOSSimulator:
+      c->cmd = LC_VERSION_MIN_TVOS;
+      break;
+    case PlatformKind::watchOS:
+    case PlatformKind::watchOSSimulator:
+      c->cmd = LC_VERSION_MIN_WATCHOS;
+      break;
+    default:
+      llvm_unreachable("invalid platform");
+      break;
+    }
+    c->cmdsize = getSize();
+    c->version = encodeVersion(platformInfo.minimum);
+    c->sdk = encodeVersion(platformInfo.sdk);
+  }
+
+private:
+  const PlatformInfo &platformInfo;
+};
+
 class LCBuildVersion : public LoadCommand {
 public:
-  LCBuildVersion(PlatformKind platform, const PlatformInfo &platformInfo)
-      : platform(platform), platformInfo(platformInfo) {}
+  explicit LCBuildVersion(const PlatformInfo &platformInfo)
+      : platformInfo(platformInfo) {}
 
   const int ntools = 1;
 
@@ -374,21 +418,17 @@ class LCBuildVersion : public LoadCommand {
     auto *c = reinterpret_cast<build_version_command *>(buf);
     c->cmd = LC_BUILD_VERSION;
     c->cmdsize = getSize();
-    c->platform = static_cast<uint32_t>(platform);
-    c->minos = ((platformInfo.minimum.getMajor() << 020) |
-                (platformInfo.minimum.getMinor().getValueOr(0) << 010) |
-                platformInfo.minimum.getSubminor().getValueOr(0));
-    c->sdk = ((platformInfo.sdk.getMajor() << 020) |
-              (platformInfo.sdk.getMinor().getValueOr(0) << 010) |
-              platformInfo.sdk.getSubminor().getValueOr(0));
+    c->platform = static_cast<uint32_t>(platformInfo.target.Platform);
+    c->minos = encodeVersion(platformInfo.minimum);
+    c->sdk = encodeVersion(platformInfo.sdk);
     c->ntools = ntools;
     auto *t = reinterpret_cast<build_tool_version *>(&c[1]);
     t->tool = TOOL_LD;
-    t->version = (LLVM_VERSION_MAJOR << 020) | (LLVM_VERSION_MINOR << 010) |
-                 LLVM_VERSION_PATCH;
+    t->version = encodeVersion(llvm::VersionTuple(
+        LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, LLVM_VERSION_PATCH));
   }
 
-  PlatformKind platform;
+private:
   const PlatformInfo &platformInfo;
 };
 
@@ -553,6 +593,20 @@ void Writer::scanSymbols() {
   }
 }
 
+// TODO: ld64 enforces the old load commands in a few other cases.
+static bool useLCBuildVersion(const PlatformInfo &platformInfo) {
+  static const std::map<PlatformKind, llvm::VersionTuple> minVersion = {
+      {PlatformKind::macOS, llvm::VersionTuple(10, 14)},
+      {PlatformKind::iOS, llvm::VersionTuple(12, 0)},
+      {PlatformKind::iOSSimulator, llvm::VersionTuple(13, 0)},
+      {PlatformKind::tvOS, llvm::VersionTuple(12, 0)},
+      {PlatformKind::tvOSSimulator, llvm::VersionTuple(13, 0)},
+      {PlatformKind::watchOS, llvm::VersionTuple(5, 0)},
+      {PlatformKind::watchOSSimulator, llvm::VersionTuple(6, 0)}};
+  auto it = minVersion.find(platformInfo.target.Platform);
+  return it == minVersion.end() ? true : platformInfo.minimum >= it->second;
+}
+
 template <class LP> void Writer::createLoadCommands() {
   uint8_t segIndex = 0;
   for (OutputSegment *seg : outputSegments) {
@@ -589,8 +643,10 @@ template <class LP> void Writer::createLoadCommands() {
   uuidCommand = make<LCUuid>();
   in.header->addLoadCommand(uuidCommand);
 
-  in.header->addLoadCommand(
-      make<LCBuildVersion>(config->target.Platform, config->platformInfo));
+  if (useLCBuildVersion(config->platformInfo))
+    in.header->addLoadCommand(make<LCBuildVersion>(config->platformInfo));
+  else
+    in.header->addLoadCommand(make<LCMinVersion>(config->platformInfo));
 
   int64_t dylibOrdinal = 1;
   for (InputFile *file : inputFiles) {

diff  --git a/lld/test/MachO/lc-build-version.s b/lld/test/MachO/lc-build-version.s
index eb4f422bef12..d7bd8be26f4b 100644
--- a/lld/test/MachO/lc-build-version.s
+++ b/lld/test/MachO/lc-build-version.s
@@ -1,16 +1,68 @@
 # REQUIRES: x86
+
 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
-# RUN: %lld -platform_version macos 10.14.1 10.15 -o %t %t.o
-# RUN: llvm-objdump --macho --all-headers %t | FileCheck %s
-
-# CHECK: cmd LC_BUILD_VERSION
-# CHECK-NEXT: cmdsize 32
-# CHECK-NEXT: platform macos
-# CHECK-NEXT: sdk 10.15
-# CHECK-NEXT: minos 10.14.1
-# CHECK-NEXT: ntools 1
-# CHECK-NEXT: tool ld
-# CHECK-NEXT: version {{[0-9\.]+}}
+
+# RUN: %lld -platform_version macos 10.14 10.15 -o %t.macos_10_14 %t.o
+# RUN: llvm-objdump --macho --all-headers %t.macos_10_14 | FileCheck %s --check-prefix=MACOS_10_14
+
+# MACOS_10_14: cmd LC_BUILD_VERSION
+# MACOS_10_14-NEXT: cmdsize 32
+# MACOS_10_14-NEXT: platform macos
+# MACOS_10_14-NEXT: sdk 10.15
+# MACOS_10_14-NEXT: minos 10.14
+# MACOS_10_14-NEXT: ntools 1
+# MACOS_10_14-NEXT: tool ld
+# MACOS_10_14-NEXT: version {{[0-9\.]+}}
+
+# RUN: %lld -platform_version macos 10.13 10.15 -o %t.macos_10_13 %t.o
+# RUN: llvm-objdump --macho --all-headers %t.macos_10_13 | FileCheck %s --check-prefix=MACOS_10_13
+
+# MACOS_10_13: cmd LC_VERSION_MIN_MACOSX
+# MACOS_10_13-NEXT: cmdsize 16
+# MACOS_10_13-NEXT: version 10.13
+# MACOS_10_13-NEXT: sdk 10.15
+
+# RUN: %lld -platform_version ios 12.0 10.15 -o %t.ios_12_0 %t.o
+# RUN: llvm-objdump --macho --all-headers %t.ios_12_0 | FileCheck %s --check-prefix=IOS_12_0
+# RUN: %lld -platform_version ios-simulator 13.0 10.15 -o %t.ios_sim_13_0 %t.o
+# RUN: llvm-objdump --macho --all-headers %t.ios_sim_13_0 | FileCheck %s --check-prefix=IOS_12_0
+
+# IOS_12_0: cmd LC_BUILD_VERSION
+
+# RUN: %lld -platform_version ios 11.0 10.15 -o %t.ios_11_0 %t.o
+# RUN: llvm-objdump --macho --all-headers %t.ios_11_0 | FileCheck %s --check-prefix=IOS_11_0
+# RUN: %lld -platform_version ios-simulator 12.0 10.15 -o %t.ios_sim_12_0 %t.o
+# RUN: llvm-objdump --macho --all-headers %t.ios_sim_12_0 | FileCheck %s --check-prefix=IOS_11_0
+
+# IOS_11_0: cmd LC_VERSION_MIN_IPHONEOS
+
+# RUN: %lld -platform_version tvos 12.0 10.15 -o %t.tvos_12_0 %t.o
+# RUN: llvm-objdump --macho --all-headers %t.tvos_12_0 | FileCheck %s --check-prefix=TVOS_12_0
+# RUN: %lld -platform_version tvos-simulator 13.0 10.15 -o %t.tvos_sim_13_0 %t.o
+# RUN: llvm-objdump --macho --all-headers %t.tvos_sim_13_0 | FileCheck %s --check-prefix=TVOS_12_0
+
+# TVOS_12_0: cmd LC_BUILD_VERSION
+
+# RUN: %lld -platform_version tvos 11.0 10.15 -o %t.tvos_11_0 %t.o
+# RUN: llvm-objdump --macho --all-headers %t.tvos_11_0 | FileCheck %s --check-prefix=TVOS_11_0
+# RUN: %lld -platform_version tvos-simulator 12.0 10.15 -o %t.tvos_sim_12_0 %t.o
+# RUN: llvm-objdump --macho --all-headers %t.tvos_sim_12_0 | FileCheck %s --check-prefix=TVOS_11_0
+
+# TVOS_11_0: cmd LC_VERSION_MIN_TVOS
+
+# RUN: %lld -platform_version watchos 5.0 10.15 -o %t.watchos_5_0 %t.o
+# RUN: llvm-objdump --macho --all-headers %t.watchos_5_0 | FileCheck %s --check-prefix=WATCHOS_5_0
+# RUN: %lld -platform_version watchos-simulator 6.0 10.15 -o %t.watchos_sim_6_0 %t.o
+# RUN: llvm-objdump --macho --all-headers %t.watchos_sim_6_0 | FileCheck %s --check-prefix=WATCHOS_5_0
+
+# WATCHOS_5_0: cmd LC_BUILD_VERSION
+
+# RUN: %lld -platform_version watchos 4.0 10.15 -o %t.watchos_4_0 %t.o
+# RUN: llvm-objdump --macho --all-headers %t.watchos_4_0 | FileCheck %s --check-prefix=WATCHOS_4_0
+# RUN: %lld -platform_version watchos-simulator 5.0 10.15 -o %t.watchos_sim_5_0 %t.o
+# RUN: llvm-objdump --macho --all-headers %t.watchos_sim_5_0 | FileCheck %s --check-prefix=WATCHOS_4_0
+
+# WATCHOS_4_0: cmd LC_VERSION_MIN_WATCHOS
 
 .text
 .global _main

diff  --git a/lld/test/MachO/load-command-sequence.s b/lld/test/MachO/load-command-sequence.s
index 734b7d1c6595..81051bf1431c 100644
--- a/lld/test/MachO/load-command-sequence.s
+++ b/lld/test/MachO/load-command-sequence.s
@@ -47,7 +47,7 @@
 # DYLIB: cmd LC_ID_DYLIB
 
 # COMMON: cmd LC_UUID
-# COMMON: cmd LC_BUILD_VERSION
+# COMMON: cmd LC_VERSION_MIN_MACOSX
 # COMMON: cmd LC_LOAD_DYLIB
 
 .section __TEXT,__cstring

diff  --git a/lld/test/MachO/local-got.s b/lld/test/MachO/local-got.s
index 9e48c7ec600b..e4a1c5e9b979 100644
--- a/lld/test/MachO/local-got.s
+++ b/lld/test/MachO/local-got.s
@@ -12,12 +12,12 @@
 ## address offset and the contents at that address very similarly, so am using
 ## --match-full-lines to make sure we match on the right thing.
 # CHECK:      Contents of section __TEXT,__cstring:
-# CHECK-NEXT: 100000434 {{.*}}
+# CHECK-NEXT: 100000424 {{.*}}
 
 ## 1st 8 bytes refer to the start of __cstring + 0xe, 2nd 8 bytes refer to the
 ## start of __cstring
 # CHECK:      Contents of section __DATA_CONST,__got:
-# CHECK-NEXT: [[#%X,ADDR:]]  42040000 01000000 34040000 01000000 {{.*}}
+# CHECK-NEXT: [[#%X,ADDR:]]  32040000 01000000 24040000 01000000 {{.*}}
 # CHECK-NEXT: [[#ADDR + 16]] 00000000 00000000 {{.*}}
 
 ## Check that the rebase table is empty.

diff  --git a/lld/test/MachO/x86-64-relocs.s b/lld/test/MachO/x86-64-relocs.s
index 8e9474454001..c5627c49583f 100644
--- a/lld/test/MachO/x86-64-relocs.s
+++ b/lld/test/MachO/x86-64-relocs.s
@@ -21,7 +21,7 @@
 
 # RUN: llvm-objdump --section=__const --full-contents %t | FileCheck %s --check-prefix=NONPCREL
 # NONPCREL:      Contents of section __DATA,__const:
-# NONPCREL-NEXT: 100001000 18040000 01000000 18040000 01000000
+# NONPCREL-NEXT: 100001000 08040000 01000000 08040000 01000000
 
 .section __TEXT,__text
 .globl _main, _f


        


More information about the llvm-commits mailing list