summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp2
-rw-r--r--llvm/lib/IR/Module.cpp40
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp25
-rw-r--r--llvm/lib/MC/MCAssembler.cpp1
-rw-r--r--llvm/lib/MC/MCMachOStreamer.cpp20
-rw-r--r--llvm/lib/MC/MCParser/DarwinAsmParser.cpp107
-rw-r--r--llvm/lib/MC/MCStreamer.cpp5
-rw-r--r--llvm/lib/MC/MachObjectWriter.cpp23
-rw-r--r--llvm/lib/Object/ModuleSymbolTable.cpp1
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);
OpenPOWER on IntegriCloud