mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-30 15:10:30 +00:00
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@349119 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ee2b007283
commit
6592c09789
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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).
|
||||
|
@ -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);
|
||||
|
@ -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";
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -111,6 +111,7 @@ void MCAssembler::reset() {
|
||||
ELFHeaderEFlags = 0;
|
||||
LOHContainer.reset();
|
||||
VersionInfo.Major = 0;
|
||||
VersionInfo.SDKVersion = VersionTuple();
|
||||
|
||||
// reset objects owned by us
|
||||
if (getBackendPtr())
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
19
test/MC/MachO/ARM/build-version-sdk-version-errors.c
Normal file
19
test/MC/MachO/ARM/build-version-sdk-version-errors.c
Normal file
@ -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
|
13
test/MC/MachO/ARM/build-version-sdk-version.s
Normal file
13
test/MC/MachO/ARM/build-version-sdk-version.s
Normal file
@ -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
|
13
test/MC/MachO/build-version-with-sdk-version.s
Normal file
13
test/MC/MachO/build-version-with-sdk-version.s
Normal file
@ -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: }
|
18
test/MC/MachO/darwin-sdk-version.ll
Normal file
18
test/MC/MachO/darwin-sdk-version.ll
Normal file
@ -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
|
10
test/MC/MachO/osx-version-min-load-command-with-sdk-errors.s
Normal file
10
test/MC/MachO/osx-version-min-load-command-with-sdk-errors.s
Normal file
@ -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
|
12
test/MC/MachO/osx-version-min-load-command-with-sdk.s
Normal file
12
test/MC/MachO/osx-version-min-load-command-with-sdk.s
Normal file
@ -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: }
|
Loading…
Reference in New Issue
Block a user