[llvm] r349119 - [macho] save the SDK version stored in module metadata into the version min and

Alex Lorenz via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 13 17:14:11 PST 2018


Author: arphaman
Date: Thu Dec 13 17:14:10 2018
New Revision: 349119

URL: http://llvm.org/viewvc/llvm-project?rev=349119&view=rev
Log:
[macho] save the SDK version stored in module metadata into the version min and
build version load commands in the object file

This commit introduces a new metadata node called "SDK Version". It will be set
by the frontend to mark the platform SDK (macOS/iOS/etc) version which was used
during that particular compilation.
This node is used when machine code is emitted, by either saving the SDK version
into the appropriate macho load command (version min/build version), or by
emitting the assembly for these load commands with the SDK version specified as
well.
The assembly for both load commands is extended by allowing it to contain the
sdk_version X, Y [, Z] trailing directive to represent the SDK version
respectively.

rdar://45774000

Differential Revision: https://reviews.llvm.org/D55612

Added:
    llvm/trunk/test/MC/MachO/ARM/build-version-sdk-version-errors.c
    llvm/trunk/test/MC/MachO/ARM/build-version-sdk-version.s
    llvm/trunk/test/MC/MachO/build-version-with-sdk-version.s
    llvm/trunk/test/MC/MachO/darwin-sdk-version.ll
    llvm/trunk/test/MC/MachO/osx-version-min-load-command-with-sdk-errors.s
    llvm/trunk/test/MC/MachO/osx-version-min-load-command-with-sdk.s
Modified:
    llvm/trunk/include/llvm/IR/Module.h
    llvm/trunk/include/llvm/MC/MCAssembler.h
    llvm/trunk/include/llvm/MC/MCObjectFileInfo.h
    llvm/trunk/include/llvm/MC/MCStreamer.h
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/trunk/lib/IR/Module.cpp
    llvm/trunk/lib/MC/MCAsmStreamer.cpp
    llvm/trunk/lib/MC/MCAssembler.cpp
    llvm/trunk/lib/MC/MCMachOStreamer.cpp
    llvm/trunk/lib/MC/MCParser/DarwinAsmParser.cpp
    llvm/trunk/lib/MC/MCStreamer.cpp
    llvm/trunk/lib/MC/MachObjectWriter.cpp
    llvm/trunk/lib/Object/ModuleSymbolTable.cpp

Modified: llvm/trunk/include/llvm/IR/Module.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Module.h?rev=349119&r1=349118&r2=349119&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Module.h (original)
+++ llvm/trunk/include/llvm/IR/Module.h Thu Dec 13 17:14:10 2018
@@ -49,6 +49,7 @@ class MemoryBuffer;
 class RandomNumberGenerator;
 template <class PtrType> class SmallPtrSetImpl;
 class StructType;
+class VersionTuple;
 
 /// A Module instance is used to store all the information related to an
 /// LLVM module. Modules are the top level container of all other LLVM
@@ -868,6 +869,17 @@ public:
   /// Set that PLT should be avoid for RTLib calls.
   void setRtLibUseGOT();
 
+  /// @name Utility functions for querying and setting the build SDK version
+  /// @{
+
+  /// Attach a build SDK version metadata to this module.
+  void setSDKVersion(const VersionTuple &V);
+
+  /// Get the build SDK version metadata.
+  ///
+  /// An empty version is returned if no such metadata is attached.
+  VersionTuple getSDKVersion() const;
+  /// @}
 
   /// Take ownership of the given memory buffer.
   void setOwnedMemoryBuffer(std::unique_ptr<MemoryBuffer> MB);

Modified: llvm/trunk/include/llvm/MC/MCAssembler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=349119&r1=349118&r2=349119&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAssembler.h (original)
+++ llvm/trunk/include/llvm/MC/MCAssembler.h Thu Dec 13 17:14:10 2018
@@ -23,6 +23,7 @@
 #include "llvm/MC/MCFragment.h"
 #include "llvm/MC/MCLinkerOptimizationHint.h"
 #include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/VersionTuple.h"
 #include <cassert>
 #include <cstddef>
 #include <cstdint>
@@ -94,6 +95,8 @@ public:
     unsigned Major;
     unsigned Minor;
     unsigned Update;
+    /// An optional version of the SDK that was used to build the source.
+    VersionTuple SDKVersion;
   };
 
 private:
@@ -255,20 +258,24 @@ public:
   /// MachO deployment target version information.
   const VersionInfoType &getVersionInfo() const { return VersionInfo; }
   void setVersionMin(MCVersionMinType Type, unsigned Major, unsigned Minor,
-                     unsigned Update) {
+                     unsigned Update,
+                     VersionTuple SDKVersion = VersionTuple()) {
     VersionInfo.EmitBuildVersion = false;
     VersionInfo.TypeOrPlatform.Type = Type;
     VersionInfo.Major = Major;
     VersionInfo.Minor = Minor;
     VersionInfo.Update = Update;
+    VersionInfo.SDKVersion = SDKVersion;
   }
   void setBuildVersion(MachO::PlatformType Platform, unsigned Major,
-                       unsigned Minor, unsigned Update) {
+                       unsigned Minor, unsigned Update,
+                       VersionTuple SDKVersion = VersionTuple()) {
     VersionInfo.EmitBuildVersion = true;
     VersionInfo.TypeOrPlatform.Platform = Platform;
     VersionInfo.Major = Major;
     VersionInfo.Minor = Minor;
     VersionInfo.Update = Update;
+    VersionInfo.SDKVersion = SDKVersion;
   }
 
   /// Reuse an assembler instance

Modified: llvm/trunk/include/llvm/MC/MCObjectFileInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectFileInfo.h?rev=349119&r1=349118&r2=349119&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCObjectFileInfo.h (original)
+++ llvm/trunk/include/llvm/MC/MCObjectFileInfo.h Thu Dec 13 17:14:10 2018
@@ -18,6 +18,7 @@
 #include "llvm/ADT/Triple.h"
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/Support/CodeGen.h"
+#include "llvm/Support/VersionTuple.h"
 
 namespace llvm {
 class MCContext;
@@ -390,6 +391,7 @@ private:
   bool PositionIndependent;
   MCContext *Ctx;
   Triple TT;
+  VersionTuple SDKVersion;
 
   void initMachOMCObjectFileInfo(const Triple &T);
   void initELFMCObjectFileInfo(const Triple &T, bool Large);
@@ -399,6 +401,12 @@ private:
 
 public:
   const Triple &getTargetTriple() const { return TT; }
+
+  void setSDKVersion(const VersionTuple &TheSDKVersion) {
+    SDKVersion = TheSDKVersion;
+  }
+
+  const VersionTuple &getSDKVersion() const { return SDKVersion; }
 };
 
 } // end namespace llvm

Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=349119&r1=349118&r2=349119&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCStreamer.h Thu Dec 13 17:14:10 2018
@@ -28,6 +28,7 @@
 #include "llvm/Support/MD5.h"
 #include "llvm/Support/SMLoc.h"
 #include "llvm/Support/TargetParser.h"
+#include "llvm/Support/VersionTuple.h"
 #include <cassert>
 #include <cstdint>
 #include <memory>
@@ -452,14 +453,17 @@ public:
 
   /// Specify the Mach-O minimum deployment target version.
   virtual void EmitVersionMin(MCVersionMinType Type, unsigned Major,
-                              unsigned Minor, unsigned Update) {}
+                              unsigned Minor, unsigned Update,
+                              VersionTuple SDKVersion) {}
 
   /// Emit/Specify Mach-O build version command.
   /// \p Platform should be one of MachO::PlatformType.
   virtual void EmitBuildVersion(unsigned Platform, unsigned Major,
-                                unsigned Minor, unsigned Update) {}
+                                unsigned Minor, unsigned Update,
+                                VersionTuple SDKVersion) {}
 
-  void EmitVersionForTarget(const Triple &Target);
+  void EmitVersionForTarget(const Triple &Target,
+                            const VersionTuple &SDKVersion);
 
   /// Note in the output that the specified \p Func is a Thumb mode
   /// function (ARM target only).

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=349119&r1=349118&r2=349119&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Thu Dec 13 17:14:10 2018
@@ -263,7 +263,7 @@ bool AsmPrinter::doInitialization(Module
   // use the directive, where it would need the same conditionalization
   // anyway.
   const Triple &Target = TM.getTargetTriple();
-  OutStreamer->EmitVersionForTarget(Target);
+  OutStreamer->EmitVersionForTarget(Target, M.getSDKVersion());
 
   // Allow the target to emit any magic that it wants at the start of the file.
   EmitStartOfAsmFile(M);

Modified: llvm/trunk/lib/IR/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Module.cpp?rev=349119&r1=349118&r2=349119&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Module.cpp (original)
+++ llvm/trunk/lib/IR/Module.cpp Thu Dec 13 17:14:10 2018
@@ -46,6 +46,7 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/RandomNumberGenerator.h"
+#include "llvm/Support/VersionTuple.h"
 #include <algorithm>
 #include <cassert>
 #include <cstdint>
@@ -547,6 +548,45 @@ void Module::setRtLibUseGOT() {
   addModuleFlag(ModFlagBehavior::Max, "RtLibUseGOT", 1);
 }
 
+void Module::setSDKVersion(const VersionTuple &V) {
+  SmallVector<unsigned, 3> Entries;
+  Entries.push_back(V.getMajor());
+  if (auto Minor = V.getMinor()) {
+    Entries.push_back(*Minor);
+    if (auto Subminor = V.getSubminor())
+      Entries.push_back(*Subminor);
+    // Ignore the 'build' component as it can't be represented in the object
+    // file.
+  }
+  addModuleFlag(ModFlagBehavior::Warning, "SDK Version",
+                ConstantDataArray::get(Context, Entries));
+}
+
+VersionTuple Module::getSDKVersion() const {
+  auto *CM = dyn_cast_or_null<ConstantAsMetadata>(getModuleFlag("SDK Version"));
+  if (!CM)
+    return {};
+  auto *Arr = dyn_cast_or_null<ConstantDataArray>(CM->getValue());
+  if (!Arr)
+    return {};
+  auto getVersionComponent = [&](unsigned Index) -> Optional<unsigned> {
+    if (Index >= Arr->getNumElements())
+      return None;
+    return (unsigned)Arr->getElementAsInteger(Index);
+  };
+  auto Major = getVersionComponent(0);
+  if (!Major)
+    return {};
+  VersionTuple Result = VersionTuple(*Major);
+  if (auto Minor = getVersionComponent(1)) {
+    Result = VersionTuple(*Major, *Minor);
+    if (auto Subminor = getVersionComponent(2)) {
+      Result = VersionTuple(*Major, *Minor, *Subminor);
+    }
+  }
+  return Result;
+}
+
 GlobalVariable *llvm::collectUsedGlobalVariables(
     const Module &M, SmallPtrSetImpl<GlobalValue *> &Set, bool CompilerUsed) {
   const char *Name = CompilerUsed ? "llvm.compiler.used" : "llvm.used";

Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=349119&r1=349118&r2=349119&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Thu Dec 13 17:14:10 2018
@@ -147,9 +147,9 @@ public:
   void EmitLinkerOptions(ArrayRef<std::string> Options) override;
   void EmitDataRegion(MCDataRegionType Kind) override;
   void EmitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor,
-                      unsigned Update) override;
+                      unsigned Update, VersionTuple SDKVersion) override;
   void EmitBuildVersion(unsigned Platform, unsigned Major, unsigned Minor,
-                        unsigned Update) override;
+                        unsigned Update, VersionTuple SDKVersion) override;
   void EmitThumbFunc(MCSymbol *Func) override;
 
   void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
@@ -514,11 +514,26 @@ static const char *getVersionMinDirectiv
   llvm_unreachable("Invalid MC version min type");
 }
 
+static void EmitSDKVersionSuffix(raw_ostream &OS,
+                                 const VersionTuple &SDKVersion) {
+  if (SDKVersion.empty())
+    return;
+  OS << '\t' << "sdk_version " << SDKVersion.getMajor();
+  if (auto Minor = SDKVersion.getMinor()) {
+    OS << ", " << *Minor;
+    if (auto Subminor = SDKVersion.getSubminor()) {
+      OS << ", " << *Subminor;
+    }
+  }
+}
+
 void MCAsmStreamer::EmitVersionMin(MCVersionMinType Type, unsigned Major,
-                                   unsigned Minor, unsigned Update) {
+                                   unsigned Minor, unsigned Update,
+                                   VersionTuple SDKVersion) {
   OS << '\t' << getVersionMinDirective(Type) << ' ' << Major << ", " << Minor;
   if (Update)
     OS << ", " << Update;
+  EmitSDKVersionSuffix(OS, SDKVersion);
   EmitEOL();
 }
 
@@ -534,11 +549,13 @@ static const char *getPlatformName(MachO
 }
 
 void MCAsmStreamer::EmitBuildVersion(unsigned Platform, unsigned Major,
-                                     unsigned Minor, unsigned Update) {
+                                     unsigned Minor, unsigned Update,
+                                     VersionTuple SDKVersion) {
   const char *PlatformName = getPlatformName((MachO::PlatformType)Platform);
   OS << "\t.build_version " << PlatformName << ", " << Major << ", " << Minor;
   if (Update)
     OS << ", " << Update;
+  EmitSDKVersionSuffix(OS, SDKVersion);
   EmitEOL();
 }
 

Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=349119&r1=349118&r2=349119&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Thu Dec 13 17:14:10 2018
@@ -111,6 +111,7 @@ void MCAssembler::reset() {
   ELFHeaderEFlags = 0;
   LOHContainer.reset();
   VersionInfo.Major = 0;
+  VersionInfo.SDKVersion = VersionTuple();
 
   // reset objects owned by us
   if (getBackendPtr())

Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=349119&r1=349118&r2=349119&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Thu Dec 13 17:14:10 2018
@@ -89,10 +89,10 @@ public:
   void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
   void EmitLinkerOptions(ArrayRef<std::string> Options) override;
   void EmitDataRegion(MCDataRegionType Kind) override;
-  void EmitVersionMin(MCVersionMinType Kind, unsigned Major,
-                      unsigned Minor, unsigned Update) override;
-  void EmitBuildVersion(unsigned Platform, unsigned Major,
-                        unsigned Minor, unsigned Update) override;
+  void EmitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor,
+                      unsigned Update, VersionTuple SDKVersion) override;
+  void EmitBuildVersion(unsigned Platform, unsigned Major, unsigned Minor,
+                        unsigned Update, VersionTuple SDKVersion) override;
   void EmitThumbFunc(MCSymbol *Func) override;
   bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
   void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
@@ -270,14 +270,16 @@ void MCMachOStreamer::EmitDataRegion(MCD
 }
 
 void MCMachOStreamer::EmitVersionMin(MCVersionMinType Kind, unsigned Major,
-                                     unsigned Minor, unsigned Update) {
-  getAssembler().setVersionMin(Kind, Major, Minor, Update);
+                                     unsigned Minor, unsigned Update,
+                                     VersionTuple SDKVersion) {
+  getAssembler().setVersionMin(Kind, Major, Minor, Update, SDKVersion);
 }
 
 void MCMachOStreamer::EmitBuildVersion(unsigned Platform, unsigned Major,
-                                       unsigned Minor, unsigned Update) {
+                                       unsigned Minor, unsigned Update,
+                                       VersionTuple SDKVersion) {
   getAssembler().setBuildVersion((MachO::PlatformType)Platform, Major, Minor,
-                                 Update);
+                                 Update, SDKVersion);
 }
 
 void MCMachOStreamer::EmitThumbFunc(MCSymbol *Symbol) {
@@ -507,7 +509,7 @@ MCStreamer *llvm::createMachOStreamer(MC
       new MCMachOStreamer(Context, std::move(MAB), std::move(OW), std::move(CE),
                           DWARFMustBeAtTheEnd, LabelSections);
   const Triple &Target = Context.getObjectFileInfo()->getTargetTriple();
-  S->EmitVersionForTarget(Target);
+  S->EmitVersionForTarget(Target, Context.getObjectFileInfo()->getSDKVersion());
   if (RelaxAll)
     S->getAssembler().setRelaxAll(true);
   return S;

Modified: llvm/trunk/lib/MC/MCParser/DarwinAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/DarwinAsmParser.cpp?rev=349119&r1=349118&r2=349119&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/DarwinAsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/DarwinAsmParser.cpp Thu Dec 13 17:14:10 2018
@@ -459,7 +459,12 @@ public:
 
   bool parseBuildVersion(StringRef Directive, SMLoc Loc);
   bool parseVersionMin(StringRef Directive, SMLoc Loc, MCVersionMinType Type);
+  bool parseMajorMinorVersionComponent(unsigned *Major, unsigned *Minor,
+                                       const char *VersionName);
+  bool parseOptionalTrailingVersionComponent(unsigned *Component,
+                                             const char *ComponentName);
   bool parseVersion(unsigned *Major, unsigned *Minor, unsigned *Update);
+  bool parseSDKVersion(VersionTuple &SDKVersion);
   void checkVersion(StringRef Directive, StringRef Arg, SMLoc Loc,
                     Triple::OSType ExpectedOS);
 };
@@ -1000,43 +1005,89 @@ bool DarwinAsmParser::parseDirectiveData
   return false;
 }
 
-/// parseVersion ::= major, minor [, update]
-bool DarwinAsmParser::parseVersion(unsigned *Major, unsigned *Minor,
-                                   unsigned *Update) {
+static bool isSDKVersionToken(const AsmToken &Tok) {
+  return Tok.is(AsmToken::Identifier) && Tok.getIdentifier() == "sdk_version";
+}
+
+/// parseMajorMinorVersionComponent ::= major, minor
+bool DarwinAsmParser::parseMajorMinorVersionComponent(unsigned *Major,
+                                                      unsigned *Minor,
+                                                      const char *VersionName) {
   // Get the major version number.
   if (getLexer().isNot(AsmToken::Integer))
-    return TokError("invalid OS major version number, integer expected");
+    return TokError(Twine("invalid ") + VersionName +
+                    " major version number, integer expected");
   int64_t MajorVal = getLexer().getTok().getIntVal();
   if (MajorVal > 65535 || MajorVal <= 0)
-    return TokError("invalid OS major version number");
+    return TokError(Twine("invalid ") + VersionName + " major version number");
   *Major = (unsigned)MajorVal;
   Lex();
   if (getLexer().isNot(AsmToken::Comma))
-    return TokError("OS minor version number required, comma expected");
+    return TokError(Twine(VersionName) +
+                    " minor version number required, comma expected");
   Lex();
   // Get the minor version number.
   if (getLexer().isNot(AsmToken::Integer))
-    return TokError("invalid OS minor version number, integer expected");
+    return TokError(Twine("invalid ") + VersionName +
+                    " minor version number, integer expected");
   int64_t MinorVal = getLexer().getTok().getIntVal();
   if (MinorVal > 255 || MinorVal < 0)
-    return TokError("invalid OS minor version number");
+    return TokError(Twine("invalid ") + VersionName + " minor version number");
   *Minor = MinorVal;
   Lex();
+  return false;
+}
+
+/// parseOptionalTrailingVersionComponent ::= , version_number
+bool DarwinAsmParser::parseOptionalTrailingVersionComponent(
+    unsigned *Component, const char *ComponentName) {
+  assert(getLexer().is(AsmToken::Comma) && "comma expected");
+  Lex();
+  if (getLexer().isNot(AsmToken::Integer))
+    return TokError(Twine("invalid ") + ComponentName +
+                    " version number, integer expected");
+  int64_t Val = getLexer().getTok().getIntVal();
+  if (Val > 255 || Val < 0)
+    return TokError(Twine("invalid ") + ComponentName + " version number");
+  *Component = Val;
+  Lex();
+  return false;
+}
+
+/// parseVersion ::= parseMajorMinorVersionComponent
+///                      parseOptionalTrailingVersionComponent
+bool DarwinAsmParser::parseVersion(unsigned *Major, unsigned *Minor,
+                                   unsigned *Update) {
+  if (parseMajorMinorVersionComponent(Major, Minor, "OS"))
+    return true;
 
   // Get the update level, if specified
   *Update = 0;
-  if (getLexer().is(AsmToken::EndOfStatement))
+  if (getLexer().is(AsmToken::EndOfStatement) ||
+      isSDKVersionToken(getLexer().getTok()))
     return false;
   if (getLexer().isNot(AsmToken::Comma))
     return TokError("invalid OS update specifier, comma expected");
+  if (parseOptionalTrailingVersionComponent(Update, "OS update"))
+    return true;
+  return false;
+}
+
+bool DarwinAsmParser::parseSDKVersion(VersionTuple &SDKVersion) {
+  assert(isSDKVersionToken(getLexer().getTok()) && "expected sdk_version");
   Lex();
-  if (getLexer().isNot(AsmToken::Integer))
-    return TokError("invalid OS update version number, integer expected");
-  int64_t UpdateVal = getLexer().getTok().getIntVal();
-  if (UpdateVal > 255 || UpdateVal < 0)
-    return TokError("invalid OS update version number");
-  *Update = UpdateVal;
-  Lex();
+  unsigned Major, Minor;
+  if (parseMajorMinorVersionComponent(&Major, &Minor, "SDK"))
+    return true;
+  SDKVersion = VersionTuple(Major, Minor);
+
+  // Get the subminor version, if specified.
+  if (getLexer().is(AsmToken::Comma)) {
+    unsigned Subminor;
+    if (parseOptionalTrailingVersionComponent(&Subminor, "SDK subminor"))
+      return true;
+    SDKVersion = VersionTuple(Major, Minor, Subminor);
+  }
   return false;
 }
 
@@ -1066,10 +1117,10 @@ static Triple::OSType getOSTypeFromMCVM(
 }
 
 /// parseVersionMin
-///   ::= .ios_version_min parseVersion
-///   |   .macosx_version_min parseVersion
-///   |   .tvos_version_min parseVersion
-///   |   .watchos_version_min parseVersion
+///   ::= .ios_version_min parseVersion parseSDKVersion
+///   |   .macosx_version_min parseVersion parseSDKVersion
+///   |   .tvos_version_min parseVersion parseSDKVersion
+///   |   .watchos_version_min parseVersion parseSDKVersion
 bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc Loc,
                                       MCVersionMinType Type) {
   unsigned Major;
@@ -1078,13 +1129,16 @@ bool DarwinAsmParser::parseVersionMin(St
   if (parseVersion(&Major, &Minor, &Update))
     return true;
 
+  VersionTuple SDKVersion;
+  if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion))
+    return true;
+
   if (parseToken(AsmToken::EndOfStatement))
     return addErrorSuffix(Twine(" in '") + Directive + "' directive");
 
   Triple::OSType ExpectedOS = getOSTypeFromMCVM(Type);
   checkVersion(Directive, StringRef(), Loc, ExpectedOS);
-
-  getStreamer().EmitVersionMin(Type, Major, Minor, Update);
+  getStreamer().EmitVersionMin(Type, Major, Minor, Update, SDKVersion);
   return false;
 }
 
@@ -1100,7 +1154,7 @@ static Triple::OSType getOSTypeFromPlatf
 }
 
 /// parseBuildVersion
-///   ::= .build_version (macos|ios|tvos|watchos), parseVersion
+///   ::= .build_version (macos|ios|tvos|watchos), parseVersion parseSDKVersion
 bool DarwinAsmParser::parseBuildVersion(StringRef Directive, SMLoc Loc) {
   StringRef PlatformName;
   SMLoc PlatformLoc = getTok().getLoc();
@@ -1126,14 +1180,17 @@ bool DarwinAsmParser::parseBuildVersion(
   if (parseVersion(&Major, &Minor, &Update))
     return true;
 
+  VersionTuple SDKVersion;
+  if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion))
+    return true;
+
   if (parseToken(AsmToken::EndOfStatement))
     return addErrorSuffix(" in '.build_version' directive");
 
   Triple::OSType ExpectedOS
     = getOSTypeFromPlatform((MachO::PlatformType)Platform);
   checkVersion(Directive, PlatformName, Loc, ExpectedOS);
-
-  getStreamer().EmitBuildVersion(Platform, Major, Minor, Update);
+  getStreamer().EmitBuildVersion(Platform, Major, Minor, Update, SDKVersion);
   return false;
 }
 

Modified: llvm/trunk/lib/MC/MCStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=349119&r1=349118&r2=349119&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCStreamer.cpp Thu Dec 13 17:14:10 2018
@@ -1045,7 +1045,8 @@ MCSymbol *MCStreamer::endSection(MCSecti
   return Sym;
 }
 
-void MCStreamer::EmitVersionForTarget(const Triple &Target) {
+void MCStreamer::EmitVersionForTarget(const Triple &Target,
+                                      const VersionTuple &SDKVersion) {
   if (!Target.isOSBinFormatMachO() || !Target.isOSDarwin())
     return;
   // Do we even know the version?
@@ -1071,5 +1072,5 @@ void MCStreamer::EmitVersionForTarget(co
     Target.getiOSVersion(Major, Minor, Update);
   }
   if (Major != 0)
-    EmitVersionMin(VersionType, Major, Minor, Update);
+    EmitVersionMin(VersionType, Major, Minor, Update, SDKVersion);
 }

Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=349119&r1=349118&r2=349119&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MachObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/MachObjectWriter.cpp Thu Dec 13 17:14:10 2018
@@ -846,18 +846,27 @@ uint64_t MachObjectWriter::writeObject(M
 
   // Write out the deployment target information, if it's available.
   if (VersionInfo.Major != 0) {
-    assert(VersionInfo.Update < 256 && "unencodable update target version");
-    assert(VersionInfo.Minor < 256 && "unencodable minor target version");
-    assert(VersionInfo.Major < 65536 && "unencodable major target version");
-    uint32_t EncodedVersion = VersionInfo.Update | (VersionInfo.Minor << 8) |
-      (VersionInfo.Major << 16);
+    auto EncodeVersion = [](VersionTuple V) -> uint32_t {
+      assert(!V.empty() && "empty version");
+      unsigned Update = V.getSubminor() ? *V.getSubminor() : 0;
+      unsigned Minor = V.getMinor() ? *V.getMinor() : 0;
+      assert(Update < 256 && "unencodable update target version");
+      assert(Minor < 256 && "unencodable minor target version");
+      assert(V.getMajor() < 65536 && "unencodable major target version");
+      return Update | (Minor << 8) | (V.getMajor() << 16);
+    };
+    uint32_t EncodedVersion = EncodeVersion(
+        VersionTuple(VersionInfo.Major, VersionInfo.Minor, VersionInfo.Update));
+    uint32_t SDKVersion = !VersionInfo.SDKVersion.empty()
+                              ? EncodeVersion(VersionInfo.SDKVersion)
+                              : 0;
     if (VersionInfo.EmitBuildVersion) {
       // FIXME: Currently empty tools. Add clang version in the future.
       W.write<uint32_t>(MachO::LC_BUILD_VERSION);
       W.write<uint32_t>(sizeof(MachO::build_version_command));
       W.write<uint32_t>(VersionInfo.TypeOrPlatform.Platform);
       W.write<uint32_t>(EncodedVersion);
-      W.write<uint32_t>(0);         // SDK version.
+      W.write<uint32_t>(SDKVersion);
       W.write<uint32_t>(0);         // Empty tools list.
     } else {
       MachO::LoadCommandType LCType
@@ -865,7 +874,7 @@ uint64_t MachObjectWriter::writeObject(M
       W.write<uint32_t>(LCType);
       W.write<uint32_t>(sizeof(MachO::version_min_command));
       W.write<uint32_t>(EncodedVersion);
-      W.write<uint32_t>(0);         // reserved.
+      W.write<uint32_t>(SDKVersion);
     }
   }
 

Modified: llvm/trunk/lib/Object/ModuleSymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/ModuleSymbolTable.cpp?rev=349119&r1=349118&r2=349119&view=diff
==============================================================================
--- llvm/trunk/lib/Object/ModuleSymbolTable.cpp (original)
+++ llvm/trunk/lib/Object/ModuleSymbolTable.cpp Thu Dec 13 17:14:10 2018
@@ -100,6 +100,7 @@ initializeRecordStreamer(const Module &M
   MCObjectFileInfo MOFI;
   MCContext MCCtx(MAI.get(), MRI.get(), &MOFI);
   MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, MCCtx);
+  MOFI.setSDKVersion(M.getSDKVersion());
   RecordStreamer Streamer(MCCtx, M);
   T->createNullTargetStreamer(Streamer);
 

Added: llvm/trunk/test/MC/MachO/ARM/build-version-sdk-version-errors.c
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/ARM/build-version-sdk-version-errors.c?rev=349119&view=auto
==============================================================================
--- llvm/trunk/test/MC/MachO/ARM/build-version-sdk-version-errors.c (added)
+++ llvm/trunk/test/MC/MachO/ARM/build-version-sdk-version-errors.c Thu Dec 13 17:14:10 2018
@@ -0,0 +1,19 @@
+// RUN: not llvm-mc -triple x86_64-apple-macos %s 2>&1 | FileCheck %s
+
+.build_version macos,3,4,5 sdk_version
+// CHECK: invalid SDK major version number, integer expected
+
+.build_version macos,3,4,5 sdk_version 10
+// CHECK: SDK minor version number required, comma expected
+
+.build_version macos,3,4,5 sdk_version 10,
+// CHECK: invalid SDK minor version number, integer expected
+
+.build_version macos,3,4,5 sdk_version 10,1,
+// CHECK: invalid SDK subminor version number, integer expected
+
+.build_version macos,3,4,5 sdk_version 10,10000
+// CHECK: invalid SDK minor version number
+
+.build_version macos,3,4,5 sdk_version 10,255,10000
+// CHECK: invalid SDK subminor version number

Added: llvm/trunk/test/MC/MachO/ARM/build-version-sdk-version.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/ARM/build-version-sdk-version.s?rev=349119&view=auto
==============================================================================
--- llvm/trunk/test/MC/MachO/ARM/build-version-sdk-version.s (added)
+++ llvm/trunk/test/MC/MachO/ARM/build-version-sdk-version.s Thu Dec 13 17:14:10 2018
@@ -0,0 +1,13 @@
+// RUN: llvm-mc -triple x86_64-apple-macos %s | FileCheck %s
+
+.build_version macos,3,4,5 sdk_version 10,14
+// CHECK: .build_version macos, 3, 4, 5 sdk_version 10, 14
+
+.build_version ios,6,7 sdk_version 6,1,0
+// CHECK: .build_version ios, 6, 7 sdk_version 6, 1, 0
+
+.build_version tvos,8,9 sdk_version 9,0,10
+// CHECK: .build_version tvos, 8, 9 sdk_version 9, 0, 10
+
+.build_version watchos,10,11 sdk_version 10,11
+// CHECK: .build_version watchos, 10, 11 sdk_version 10, 11

Added: llvm/trunk/test/MC/MachO/build-version-with-sdk-version.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/build-version-with-sdk-version.s?rev=349119&view=auto
==============================================================================
--- llvm/trunk/test/MC/MachO/build-version-with-sdk-version.s (added)
+++ llvm/trunk/test/MC/MachO/build-version-with-sdk-version.s Thu Dec 13 17:14:10 2018
@@ -0,0 +1,13 @@
+// RUN: llvm-mc -triple x86_64-apple-macos %s -filetype=obj -o - | llvm-readobj --macho-version-min | FileCheck %s
+
+// Test the formation of the sdk_version component of the version load
+// command in the MachO.
+.build_version macos, 10,13,2 sdk_version 10,14,1
+
+// CHECK: MinVersion {
+// CHECK:   Cmd: LC_BUILD_VERSION
+// CHECK:   Size: 24
+// CHECK:   Platform: macos
+// CHECK:   Version: 10.13.2
+// CHECK:   SDK: 10.14.1
+// CHECK: }

Added: llvm/trunk/test/MC/MachO/darwin-sdk-version.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/darwin-sdk-version.ll?rev=349119&view=auto
==============================================================================
--- llvm/trunk/test/MC/MachO/darwin-sdk-version.ll (added)
+++ llvm/trunk/test/MC/MachO/darwin-sdk-version.ll Thu Dec 13 17:14:10 2018
@@ -0,0 +1,18 @@
+; RUN: llc %s -filetype=obj -o - | llvm-objdump -macho -private-headers - | FileCheck %s
+; RUN: llc %s -filetype=asm -o - | FileCheck --check-prefix=ASM %s
+
+target triple = "x86_64-apple-macos10.14";
+!llvm.module.flags = !{!0};
+!0 = !{i32 2, !"SDK Version", [3 x i32] [ i32 10, i32 14, i32 2 ] };
+
+define void @foo() {
+entry:
+  ret void
+}
+
+; CHECK:           cmd LC_VERSION_MIN_MACOSX
+; CHECK-NEXT:  cmdsize 16
+; CHECK-NEXT:  version 10.14
+; CHECK-NEXT:      sdk 10.14.2
+
+; ASM: .macosx_version_min 10, 14 sdk_version 10, 14, 2

Added: llvm/trunk/test/MC/MachO/osx-version-min-load-command-with-sdk-errors.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/osx-version-min-load-command-with-sdk-errors.s?rev=349119&view=auto
==============================================================================
--- llvm/trunk/test/MC/MachO/osx-version-min-load-command-with-sdk-errors.s (added)
+++ llvm/trunk/test/MC/MachO/osx-version-min-load-command-with-sdk-errors.s Thu Dec 13 17:14:10 2018
@@ -0,0 +1,10 @@
+// RUN: not llvm-mc -triple x86_64-apple-macos %s -o - 2>&1 | FileCheck %s
+
+.macosx_version_min 10,13,2 sdk_version 10
+// CHECK: SDK minor version number required, comma expected
+
+.macosx_version_min 10,13,2 sdk_version 10,
+// CHECK: invalid SDK minor version number, integer expected
+
+.macosx_version_min 10,13,2 sdk_version 10
+// CHECK: SDK minor version number required, comma expected

Added: llvm/trunk/test/MC/MachO/osx-version-min-load-command-with-sdk.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/osx-version-min-load-command-with-sdk.s?rev=349119&view=auto
==============================================================================
--- llvm/trunk/test/MC/MachO/osx-version-min-load-command-with-sdk.s (added)
+++ llvm/trunk/test/MC/MachO/osx-version-min-load-command-with-sdk.s Thu Dec 13 17:14:10 2018
@@ -0,0 +1,12 @@
+// RUN: llvm-mc -triple x86_64-apple-macos %s -filetype=obj -o - | llvm-readobj --macho-version-min | FileCheck %s
+
+// Test the formation of the sdk_version component of the version load
+// command in the MachO.
+.macosx_version_min 10,13,2 sdk_version 10,14
+
+// CHECK: MinVersion {
+// CHECK:   Cmd: LC_VERSION_MIN_MACOSX
+// CHECK:   Size: 16
+// CHECK:   Version: 10.13.2
+// CHECK:   SDK: 10.14
+// CHECK: }




More information about the llvm-commits mailing list