diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/IR/Module.cpp | 40 | ||||
-rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 25 | ||||
-rw-r--r-- | llvm/lib/MC/MCAssembler.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/MC/MCMachOStreamer.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/DarwinAsmParser.cpp | 107 | ||||
-rw-r--r-- | llvm/lib/MC/MCStreamer.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/MC/MachObjectWriter.cpp | 23 | ||||
-rw-r--r-- | llvm/lib/Object/ModuleSymbolTable.cpp | 1 |
9 files changed, 176 insertions, 48 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index a1622da33a6..c38457ff59e 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -263,7 +263,7 @@ bool AsmPrinter::doInitialization(Module &M) { // 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); diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp index 7d02a3956ff..70a16cbbf24 100644 --- a/llvm/lib/IR/Module.cpp +++ b/llvm/lib/IR/Module.cpp @@ -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"; diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 463e9066616..0daec983dfd 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -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 *getVersionMinDirective(MCVersionMinType Type) { 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::PlatformType Type) { } 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(); } diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index 1e23b6d816e..cde6a93a164 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -111,6 +111,7 @@ void MCAssembler::reset() { ELFHeaderEFlags = 0; LOHContainer.reset(); VersionInfo.Major = 0; + VersionInfo.SDKVersion = VersionTuple(); // reset objects owned by us if (getBackendPtr()) diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp index 43e69605787..b30317e7467 100644 --- a/llvm/lib/MC/MCMachOStreamer.cpp +++ b/llvm/lib/MC/MCMachOStreamer.cpp @@ -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(MCDataRegionType Kind) { } 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(MCContext &Context, 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; diff --git a/llvm/lib/MC/MCParser/DarwinAsmParser.cpp b/llvm/lib/MC/MCParser/DarwinAsmParser.cpp index e6fc1fac81b..07926d6c1c9 100644 --- a/llvm/lib/MC/MCParser/DarwinAsmParser.cpp +++ b/llvm/lib/MC/MCParser/DarwinAsmParser.cpp @@ -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::parseDirectiveDataRegionEnd(StringRef, SMLoc) { 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(MCVersionMinType Type) { } /// 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(StringRef Directive, SMLoc Loc, 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 getOSTypeFromPlatform(MachO::PlatformType Type) { } /// 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(StringRef Directive, SMLoc Loc) { 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; } diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index 3722c0ad3c8..733dd4019dc 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -1045,7 +1045,8 @@ MCSymbol *MCStreamer::endSection(MCSection *Section) { 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(const Triple &Target) { Target.getiOSVersion(Major, Minor, Update); } if (Major != 0) - EmitVersionMin(VersionType, Major, Minor, Update); + EmitVersionMin(VersionType, Major, Minor, Update, SDKVersion); } diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp index c2e8dc1ef65..2fa65658ccf 100644 --- a/llvm/lib/MC/MachObjectWriter.cpp +++ b/llvm/lib/MC/MachObjectWriter.cpp @@ -846,18 +846,27 @@ uint64_t MachObjectWriter::writeObject(MCAssembler &Asm, // 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(MCAssembler &Asm, 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); } } diff --git a/llvm/lib/Object/ModuleSymbolTable.cpp b/llvm/lib/Object/ModuleSymbolTable.cpp index b353ef3c835..33ce7d8109f 100644 --- a/llvm/lib/Object/ModuleSymbolTable.cpp +++ b/llvm/lib/Object/ModuleSymbolTable.cpp @@ -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); |