MC: Add support for mach-o build_version

LC_BUILD_VERSION is a new load command superseding the previously used
LC_XXX_MIN_VERSION commands. This adds an assembler directive along with
encoding/streaming support.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@320661 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Matthias Braun 2017-12-14 00:12:46 +00:00
parent 5d4223acf1
commit 177a4fc2d2
13 changed files with 368 additions and 126 deletions

View File

@ -481,7 +481,7 @@ enum RelocationInfoType {
enum { VM_PROT_READ = 0x1, VM_PROT_WRITE = 0x2, VM_PROT_EXECUTE = 0x4 };
// Values for platform field in build_version_command.
enum {
enum PlatformType {
PLATFORM_MACOS = 1,
PLATFORM_IOS = 2,
PLATFORM_TVOS = 3,

View File

@ -16,6 +16,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCFixup.h"
@ -84,8 +85,12 @@ public:
/// MachO specific deployment target version info.
// A Major version of 0 indicates that no version information was supplied
// and so the corresponding load command should not be emitted.
using VersionMinInfoType = struct {
MCVersionMinType Kind;
using VersionInfoType = struct {
bool EmitBuildVersion;
union {
MCVersionMinType Type; ///< Used when EmitBuildVersion==false.
MachO::PlatformType Platform; ///< Used when EmitBuildVersion==true.
} TypeOrPlatform;
unsigned Major;
unsigned Minor;
unsigned Update;
@ -145,7 +150,7 @@ private:
/// the Streamer and the .o writer
MCLOHContainer LOHContainer;
VersionMinInfoType VersionMinInfo;
VersionInfoType VersionInfo;
/// Evaluate a fixup to a relocatable expression and the value which should be
/// placed into the fixup.
@ -243,13 +248,22 @@ public:
void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags; }
/// MachO deployment target version information.
const VersionMinInfoType &getVersionMinInfo() const { return VersionMinInfo; }
void setVersionMinInfo(MCVersionMinType Kind, unsigned Major, unsigned Minor,
unsigned Update) {
VersionMinInfo.Kind = Kind;
VersionMinInfo.Major = Major;
VersionMinInfo.Minor = Minor;
VersionMinInfo.Update = Update;
const VersionInfoType &getVersionInfo() const { return VersionInfo; }
void setVersionMin(MCVersionMinType Type, unsigned Major, unsigned Minor,
unsigned Update) {
VersionInfo.EmitBuildVersion = false;
VersionInfo.TypeOrPlatform.Type = Type;
VersionInfo.Major = Major;
VersionInfo.Minor = Minor;
VersionInfo.Update = Update;
}
void setBuildVersion(MachO::PlatformType Platform, unsigned Major,
unsigned Minor, unsigned Update) {
VersionInfo.EmitBuildVersion = true;
VersionInfo.TypeOrPlatform.Platform = Platform;
VersionInfo.Major = Major;
VersionInfo.Minor = Minor;
VersionInfo.Update = Update;
}
/// Reuse an assembler instance

View File

@ -421,9 +421,14 @@ public:
/// \brief Note in the output the specified region \p Kind.
virtual void EmitDataRegion(MCDataRegionType Kind) {}
/// \brief Specify the MachO minimum deployment target version.
virtual void EmitVersionMin(MCVersionMinType, unsigned Major, unsigned Minor,
unsigned Update) {}
/// \brief Specify the Mach-O minimum deployment target version.
virtual void EmitVersionMin(MCVersionMinType Type, unsigned Major,
unsigned Minor, unsigned Update) {}
/// 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) {}
/// \brief Note in the output that the specified \p Func is a Thumb mode
/// function (ARM target only).

View File

@ -137,6 +137,8 @@ public:
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 EmitThumbFunc(MCSymbol *Func) override;
void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
@ -471,15 +473,39 @@ void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
EmitEOL();
}
void MCAsmStreamer::EmitVersionMin(MCVersionMinType Kind, unsigned Major,
unsigned Minor, unsigned Update) {
switch (Kind) {
case MCVM_WatchOSVersionMin: OS << "\t.watchos_version_min"; break;
case MCVM_TvOSVersionMin: OS << "\t.tvos_version_min"; break;
case MCVM_IOSVersionMin: OS << "\t.ios_version_min"; break;
case MCVM_OSXVersionMin: OS << "\t.macosx_version_min"; break;
static const char *getVersionMinDirective(MCVersionMinType Type) {
switch (Type) {
case MCVM_WatchOSVersionMin: return ".watchos_version_min";
case MCVM_TvOSVersionMin: return ".tvos_version_min";
case MCVM_IOSVersionMin: return ".ios_version_min";
case MCVM_OSXVersionMin: return ".macosx_version_min";
}
OS << " " << Major << ", " << Minor;
llvm_unreachable("Invalid MC version min type");
}
void MCAsmStreamer::EmitVersionMin(MCVersionMinType Type, unsigned Major,
unsigned Minor, unsigned Update) {
OS << '\t' << getVersionMinDirective(Type) << ' ' << Major << ", " << Minor;
if (Update)
OS << ", " << Update;
EmitEOL();
}
static const char *getPlatformName(MachO::PlatformType Type) {
switch (Type) {
case MachO::PLATFORM_MACOS: return "macos";
case MachO::PLATFORM_IOS: return "ios";
case MachO::PLATFORM_TVOS: return "tvos";
case MachO::PLATFORM_WATCHOS: return "watchos";
case MachO::PLATFORM_BRIDGEOS: return "bridgeos";
}
llvm_unreachable("Invalid Mach-O platform type");
}
void MCAsmStreamer::EmitBuildVersion(unsigned Platform, unsigned Major,
unsigned Minor, unsigned Update) {
const char *PlatformName = getPlatformName((MachO::PlatformType)Platform);
OS << "\t.build_version " << PlatformName << ", " << Major << ", " << Minor;
if (Update)
OS << ", " << Update;
EmitEOL();

View File

@ -88,7 +88,7 @@ MCAssembler::MCAssembler(MCContext &Context, MCAsmBackend &Backend,
: Context(Context), Backend(Backend), Emitter(Emitter), Writer(Writer),
BundleAlignSize(0), RelaxAll(false), SubsectionsViaSymbols(false),
IncrementalLinkerCompatible(false), ELFHeaderEFlags(0) {
VersionMinInfo.Major = 0; // Major version == 0 for "none specified"
VersionInfo.Major = 0; // Major version == 0 for "none specified"
}
MCAssembler::~MCAssembler() = default;
@ -107,7 +107,7 @@ void MCAssembler::reset() {
IncrementalLinkerCompatible = false;
ELFHeaderEFlags = 0;
LOHContainer.reset();
VersionMinInfo.Major = 0;
VersionInfo.Major = 0;
// reset objects owned by us
getBackend().reset();

View File

@ -88,6 +88,8 @@ public:
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 EmitThumbFunc(MCSymbol *Func) override;
bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
@ -265,7 +267,13 @@ void MCMachOStreamer::EmitDataRegion(MCDataRegionType Kind) {
void MCMachOStreamer::EmitVersionMin(MCVersionMinType Kind, unsigned Major,
unsigned Minor, unsigned Update) {
getAssembler().setVersionMinInfo(Kind, Major, Minor, Update);
getAssembler().setVersionMin(Kind, Major, Minor, Update);
}
void MCMachOStreamer::EmitBuildVersion(unsigned Platform, unsigned Major,
unsigned Minor, unsigned Update) {
getAssembler().setBuildVersion((MachO::PlatformType)Platform, Major, Minor,
Update);
}
void MCMachOStreamer::EmitThumbFunc(MCSymbol *Symbol) {

View File

@ -54,7 +54,7 @@ class DarwinAsmParser : public MCAsmParserExtension {
unsigned TAA = 0, unsigned ImplicitAlign = 0,
unsigned StubSize = 0);
SMLoc LastVersionMinDirective;
SMLoc LastVersionDirective;
public:
DarwinAsmParser() = default;
@ -186,14 +186,17 @@ public:
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv");
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident");
addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(
addDirectiveHandler<&DarwinAsmParser::parseWatchOSVersionMin>(
".watchos_version_min");
addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(".tvos_version_min");
addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(".ios_version_min");
addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(
addDirectiveHandler<&DarwinAsmParser::parseTvOSVersionMin>(
".tvos_version_min");
addDirectiveHandler<&DarwinAsmParser::parseIOSVersionMin>(
".ios_version_min");
addDirectiveHandler<&DarwinAsmParser::parseMacOSXVersionMin>(
".macosx_version_min");
addDirectiveHandler<&DarwinAsmParser::parseBuildVersion>(".build_version");
LastVersionMinDirective = SMLoc();
LastVersionDirective = SMLoc();
}
bool parseDirectiveAltEntry(StringRef, SMLoc);
@ -441,7 +444,24 @@ public:
MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
}
bool parseVersionMin(StringRef, SMLoc);
bool parseWatchOSVersionMin(StringRef Directive, SMLoc Loc) {
return parseVersionMin(Directive, Loc, MCVM_WatchOSVersionMin);
}
bool parseTvOSVersionMin(StringRef Directive, SMLoc Loc) {
return parseVersionMin(Directive, Loc, MCVM_TvOSVersionMin);
}
bool parseIOSVersionMin(StringRef Directive, SMLoc Loc) {
return parseVersionMin(Directive, Loc, MCVM_IOSVersionMin);
}
bool parseMacOSXVersionMin(StringRef Directive, SMLoc Loc) {
return parseVersionMin(Directive, Loc, MCVM_OSXVersionMin);
}
bool parseBuildVersion(StringRef Directive, SMLoc Loc);
bool parseVersionMin(StringRef Directive, SMLoc Loc, MCVersionMinType Type);
bool parseVersion(unsigned *Major, unsigned *Minor, unsigned *Update);
void checkVersion(StringRef Directive, StringRef Arg, SMLoc Loc,
Triple::OSType ExpectedOS);
};
} // end anonymous namespace
@ -978,70 +998,144 @@ bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) {
return false;
}
/// parseVersionMin
/// ::= .ios_version_min major,minor[,update]
/// ::= .macosx_version_min major,minor[,update]
bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc Loc) {
int64_t Major = 0, Minor = 0, Update = 0;
int Kind = StringSwitch<int>(Directive)
.Case(".watchos_version_min", MCVM_WatchOSVersionMin)
.Case(".tvos_version_min", MCVM_TvOSVersionMin)
.Case(".ios_version_min", MCVM_IOSVersionMin)
.Case(".macosx_version_min", MCVM_OSXVersionMin);
/// parseVersion ::= major, minor [, update]
bool DarwinAsmParser::parseVersion(unsigned *Major, unsigned *Minor,
unsigned *Update) {
// Get the major version number.
if (getLexer().isNot(AsmToken::Integer))
return TokError("invalid OS major version number, integer expected");
int64_t MajorVal = getLexer().getTok().getIntVal();
if (MajorVal > 65535 || MajorVal <= 0)
return TokError("invalid OS major version number");
Major = getLexer().getTok().getIntVal();
if (Major > 65535 || Major <= 0)
return TokError("invalid OS major version number");
*Major = (unsigned)MajorVal;
Lex();
if (getLexer().isNot(AsmToken::Comma))
return TokError("minor OS version number required, comma expected");
return TokError("OS 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");
int64_t MinorVal = getLexer().getTok().getIntVal();
if (MinorVal > 255 || MinorVal < 0)
return TokError("invalid OS minor version number");
Minor = getLexer().getTok().getIntVal();
if (Minor > 255 || Minor < 0)
return TokError("invalid OS minor version number");
*Minor = MinorVal;
Lex();
// Get the update level, if specified
if (getLexer().isNot(AsmToken::EndOfStatement)) {
if (getLexer().isNot(AsmToken::Comma))
return TokError("invalid update specifier, comma expected");
Lex();
if (getLexer().isNot(AsmToken::Integer))
return TokError("invalid OS update number");
Update = getLexer().getTok().getIntVal();
if (Update > 255 || Update < 0)
return TokError("invalid OS update number");
Lex();
}
const Triple &T = getContext().getObjectFileInfo()->getTargetTriple();
Triple::OSType ExpectedOS = Triple::UnknownOS;
switch ((MCVersionMinType)Kind) {
case MCVM_WatchOSVersionMin: ExpectedOS = Triple::WatchOS; break;
case MCVM_TvOSVersionMin: ExpectedOS = Triple::TvOS; break;
case MCVM_IOSVersionMin: ExpectedOS = Triple::IOS; break;
case MCVM_OSXVersionMin: ExpectedOS = Triple::MacOSX; break;
}
if (T.getOS() != ExpectedOS)
Warning(Loc, Directive + " should only be used for " +
Triple::getOSTypeName(ExpectedOS) + " targets");
if (LastVersionMinDirective.isValid()) {
Warning(Loc, "overriding previous version_min directive");
Note(LastVersionMinDirective, "previous definition is here");
}
LastVersionMinDirective = Loc;
// We've parsed a correct version specifier, so send it to the streamer.
getStreamer().EmitVersionMin((MCVersionMinType)Kind, Major, Minor, Update);
*Update = 0;
if (getLexer().is(AsmToken::EndOfStatement))
return false;
if (getLexer().isNot(AsmToken::Comma))
return TokError("invalid OS update specifier, comma expected");
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();
return false;
}
void DarwinAsmParser::checkVersion(StringRef Directive, StringRef Arg,
SMLoc Loc, Triple::OSType ExpectedOS) {
const Triple &Target = getContext().getObjectFileInfo()->getTargetTriple();
if (Target.getOS() != ExpectedOS)
Warning(Loc, Twine(Directive) +
(Arg.empty() ? Twine() : Twine(' ') + Arg) +
" used while targeting " + Target.getOSName());
if (LastVersionDirective.isValid()) {
Warning(Loc, "overriding previous version directive");
Note(LastVersionDirective, "previous definition is here");
}
LastVersionDirective = Loc;
}
static Triple::OSType getOSTypeFromMCVM(MCVersionMinType Type) {
switch (Type) {
case MCVM_WatchOSVersionMin: return Triple::WatchOS;
case MCVM_TvOSVersionMin: return Triple::TvOS;
case MCVM_IOSVersionMin: return Triple::IOS;
case MCVM_OSXVersionMin: return Triple::MacOSX;
}
llvm_unreachable("Invalid mc version min type");
}
/// parseVersionMin
/// ::= .ios_version_min parseVersion
/// | .macosx_version_min parseVersion
/// | .tvos_version_min parseVersion
/// | .watchos_version_min parseVersion
bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc Loc,
MCVersionMinType Type) {
unsigned Major;
unsigned Minor;
unsigned Update;
if (parseVersion(&Major, &Minor, &Update))
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);
return false;
}
Triple::OSType getOSTypeFromPlatform(MachO::PlatformType Type) {
switch (Type) {
case MachO::PLATFORM_MACOS: return Triple::MacOSX;
case MachO::PLATFORM_IOS: return Triple::IOS;
case MachO::PLATFORM_TVOS: return Triple::TvOS;
case MachO::PLATFORM_WATCHOS: return Triple::WatchOS;
case MachO::PLATFORM_BRIDGEOS: /* silence warning */break;
}
llvm_unreachable("Invalid mach-o platform type");
}
/// parseBuildVersion
/// ::= .build_version (macos|ios|tvos|watchos), parseVersion
bool DarwinAsmParser::parseBuildVersion(StringRef Directive, SMLoc Loc) {
StringRef PlatformName;
SMLoc PlatformLoc = getTok().getLoc();
if (getParser().parseIdentifier(PlatformName))
return TokError("platform name expected");
unsigned Platform = StringSwitch<unsigned>(PlatformName)
.Case("macos", MachO::PLATFORM_MACOS)
.Case("ios", MachO::PLATFORM_IOS)
.Case("tvos", MachO::PLATFORM_TVOS)
.Case("watchos", MachO::PLATFORM_WATCHOS)
.Default(0);
if (Platform == 0)
return Error(PlatformLoc, "unknown platform name");
if (getLexer().isNot(AsmToken::Comma))
return TokError("version number required, comma expected");
Lex();
unsigned Major;
unsigned Minor;
unsigned Update;
if (parseVersion(&Major, &Minor, &Update))
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);
return false;
}
namespace llvm {
MCAsmParserExtension *createDarwinAsmParser() {

View File

@ -721,6 +721,16 @@ bool MachObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
return false;
}
static MachO::LoadCommandType getLCFromMCVM(MCVersionMinType Type) {
switch (Type) {
case MCVM_OSXVersionMin: return MachO::LC_VERSION_MIN_MACOSX;
case MCVM_IOSVersionMin: return MachO::LC_VERSION_MIN_IPHONEOS;
case MCVM_TvOSVersionMin: return MachO::LC_VERSION_MIN_TVOS;
case MCVM_WatchOSVersionMin: return MachO::LC_VERSION_MIN_WATCHOS;
}
llvm_unreachable("Invalid mc version min type");
}
void MachObjectWriter::writeObject(MCAssembler &Asm,
const MCAsmLayout &Layout) {
// Compute symbol table information and bind symbol indices.
@ -728,8 +738,8 @@ void MachObjectWriter::writeObject(MCAssembler &Asm,
UndefinedSymbolData);
unsigned NumSections = Asm.size();
const MCAssembler::VersionMinInfoType &VersionInfo =
Layout.getAssembler().getVersionMinInfo();
const MCAssembler::VersionInfoType &VersionInfo =
Layout.getAssembler().getVersionInfo();
// The section data starts after the header, the segment load command (and
// section headers) and the symbol table.
@ -741,7 +751,10 @@ void MachObjectWriter::writeObject(MCAssembler &Asm,
// Add the deployment target version info load command size, if used.
if (VersionInfo.Major != 0) {
++NumLoadCommands;
LoadCommandsSize += sizeof(MachO::version_min_command);
if (VersionInfo.EmitBuildVersion)
LoadCommandsSize += sizeof(MachO::build_version_command);
else
LoadCommandsSize += sizeof(MachO::version_min_command);
}
// Add the data-in-code load command size, if used.
@ -832,25 +845,22 @@ void MachObjectWriter::writeObject(MCAssembler &Asm,
assert(VersionInfo.Major < 65536 && "unencodable major target version");
uint32_t EncodedVersion = VersionInfo.Update | (VersionInfo.Minor << 8) |
(VersionInfo.Major << 16);
MachO::LoadCommandType LCType;
switch (VersionInfo.Kind) {
case MCVM_OSXVersionMin:
LCType = MachO::LC_VERSION_MIN_MACOSX;
break;
case MCVM_IOSVersionMin:
LCType = MachO::LC_VERSION_MIN_IPHONEOS;
break;
case MCVM_TvOSVersionMin:
LCType = MachO::LC_VERSION_MIN_TVOS;
break;
case MCVM_WatchOSVersionMin:
LCType = MachO::LC_VERSION_MIN_WATCHOS;
break;
if (VersionInfo.EmitBuildVersion) {
// FIXME: Currently empty tools. Add clang version in the future.
write32(MachO::LC_BUILD_VERSION);
write32(sizeof(MachO::build_version_command));
write32(VersionInfo.TypeOrPlatform.Platform);
write32(EncodedVersion);
write32(0); // SDK version.
write32(0); // Empty tools list.
} else {
MachO::LoadCommandType LCType
= getLCFromMCVM(VersionInfo.TypeOrPlatform.Type);
write32(LCType);
write32(sizeof(MachO::version_min_command));
write32(EncodedVersion);
write32(0); // reserved.
}
write32(LCType);
write32(sizeof(MachO::version_min_command));
write32(EncodedVersion);
write32(0); // reserved.
}
// Write the data-in-code load command, if used.

View File

@ -0,0 +1,56 @@
// RUN: not llvm-mc -triple x86_64-apple-tvos %s 2>&1 | FileCheck %s
.build_version tvos,65535,0,255
// CHECK-NOT: build-version-diagnostics.s:[[@LINE-1]]
.build_version macos,1,2,3
// CHECK: build-version-diagnostics.s:[[@LINE-1]]:1: warning: .build_version macos used while targeting tvos
// CHECK: build-version-diagnostics.s:[[@LINE-2]]:1: warning: overriding previous version directive
.build_version 1,2,3
// CHECK: build-version-diagnostics.s:[[@LINE-1]]:16: error: platform name expected
.build_version macos 1,2
// CHECK: build-version-diagnostics.s:[[@LINE-1]]:22: error: version number required, comma expected
.build_version noos,1,2
// CHECK: build-version-diagnostics.s:[[@LINE-1]]:16: error: unknown platform name
.build_version macos,a
// CHECK: build-version-diagnostics.s:[[@LINE-1]]:22: error: invalid OS major version number, integer expected
.build_version macos,0,1
// CHECK: build-version-diagnostics.s:[[@LINE-1]]:22: error: invalid OS major version number
.build_version macos,-1,1
// CHECK: build-version-diagnostics.s:[[@LINE-1]]:22: error: invalid OS major version number
.build_version macos,65536,1
// CHECK: build-version-diagnostics.s:[[@LINE-1]]:22: error: invalid OS major version number
.build_version ios,10 0
// CHECK: build-version-diagnostics.s:[[@LINE-1]]:23: error: OS minor version number required, comma expected
.build_version ios,10,
// CHECK: build-version-diagnostics.s:[[@LINE-1]]:23: error: invalid OS minor version number, integer expected
.build_version ios,10,-1
// CHECK: build-version-diagnostics.s:[[@LINE-1]]:23: error: invalid OS minor version number
.build_version ios,10,256
// CHECK: build-version-diagnostics.s:[[@LINE-1]]:23: error: invalid OS minor version number
.build_version watchos,10,0 a
// CHECK: build-version-diagnostics.s:[[@LINE-1]]:29: error: invalid OS update specifier, comma expected
.build_version watchos,10,0 ,
// CHECK: build-version-diagnostics.s:[[@LINE-1]]:30: error: invalid OS update version number, integer expected
.build_version ios,10,0,-1
// CHECK: build-version-diagnostics.s:[[@LINE-1]]:25: error: invalid OS update version number
.build_version ios,10,0,256
// CHECK: build-version-diagnostics.s:[[@LINE-1]]:25: error: invalid OS update version number
.build_version ios,10,0,0,
// CHECK: build-version-diagnostics.s:[[@LINE-1]]:26: error: unexpected token in '.build_version' directive

View File

@ -0,0 +1,10 @@
// RUN: llvm-mc %s -triple x86_64-apple-tvos -filetype=obj | llvm-readobj -macho-version-min | FileCheck %s
.build_version tvos,1,2,3
// CHECK: MinVersion {
// CHECK: Cmd: LC_BUILD_VERSION
// CHECK: Size: 24
// CHECK: Platform: tvos
// CHECK: Version: 1.2.3
// CHECK: SDK: n/a
// CHECK: }

View File

@ -0,0 +1,19 @@
// RUN: llvm-mc -triple x86_64-apple-macos %s | FileCheck %s
.build_version macos,1,2
// CHECK: .build_version macos, 1, 2
.build_version macos,1,2,0
// CHECK: .build_version macos, 1, 2
.build_version macos,3,4,5
// CHECK: .build_version macos, 3, 4, 5
.build_version ios,6,7
// CHECK: .build_version ios, 6, 7
.build_version tvos,8,9
// CHECK: .build_version tvos, 8, 9
.build_version watchos,10,11
// CHECK: .build_version watchos, 10, 11

View File

@ -27,7 +27,7 @@
.watchos_version_min 70000,1
// CHECK: error: invalid OS update number
// CHECK: error: invalid OS update version number
// CHECK: .ios_version_min 5,2,257
// CHECK: ^
// CHECK: error: invalid OS minor version number
@ -42,7 +42,7 @@
// CHECK: error: invalid OS major version number
// CHECK: .ios_version_min 70000,1
// CHECK: ^
// CHECK: error: invalid OS update number
// CHECK: error: invalid OS update version number
// CHECK: .macosx_version_min 99,2,257
// CHECK: ^
// CHECK: error: invalid OS minor version number
@ -57,7 +57,7 @@
// CHECK: error: invalid OS major version number
// CHECK: .macosx_version_min 70000,1
// CHECK: ^
// CHECK: error: invalid OS update number
// CHECK: error: invalid OS update version number
// CHECK: .tvos_version_min 99,2,257
// CHECK: ^
// CHECK: error: invalid OS minor version number
@ -72,7 +72,7 @@
// CHECK: error: invalid OS major version number
// CHECK: .tvos_version_min 70000,1
// CHECK: ^
// CHECK: error: invalid OS update number
// CHECK: error: invalid OS update version number
// CHECK: .watchos_version_min 99,2,257
// CHECK: ^
// CHECK: error: invalid OS minor version number

View File

@ -4,31 +4,31 @@
// RUN: llvm-mc -triple i386-apple-macosx %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=MACOSX
.ios_version_min 1,2,3
// WATCHOS: version-min-diagnostics2.s:[[@LINE-1]]:1: warning: .ios_version_min should only be used for ios targets
// TVOS: version-min-diagnostics2.s:[[@LINE-2]]:1: warning: .ios_version_min should only be used for ios targets
// MACOSX: version-min-diagnostics2.s:[[@LINE-3]]:1: warning: .ios_version_min should only be used for ios targets
// IOS-NOT: warning: .ios_version_min should only be used for ios targets
// WATCHOS: version-min-diagnostics2.s:[[@LINE-1]]:1: warning: .ios_version_min used while targeting watchos
// TVOS: version-min-diagnostics2.s:[[@LINE-2]]:1: warning: .ios_version_min used while targeting tvos
// MACOSX: version-min-diagnostics2.s:[[@LINE-3]]:1: warning: .ios_version_min used while targeting macos
// IOS-NOT: warning: .ios_version_min used while targeting
.macosx_version_min 4,5,6
// WATCHOS: version-min-diagnostics2.s:[[@LINE-1]]:1: warning: .macosx_version_min should only be used for macosx targets
// TVOS: version-min-diagnostics2.s:[[@LINE-2]]:1: warning: .macosx_version_min should only be used for macosx targets
// IOS: version-min-diagnostics2.s:[[@LINE-3]]:1: warning: .macosx_version_min should only be used for macosx targets
// MACOSX-NOT: warning: .macosx_version_min should only be used for macosx targets
// CHECK: version-min-diagnostics2.s:[[@LINE-5]]:1: warning: overriding previous version_min directive
// WATCHOS: version-min-diagnostics2.s:[[@LINE-1]]:1: warning: .macosx_version_min used while targeting watchos
// TVOS: version-min-diagnostics2.s:[[@LINE-2]]:1: warning: .macosx_version_min used while targeting tvos
// IOS: version-min-diagnostics2.s:[[@LINE-3]]:1: warning: .macosx_version_min used while targeting ios
// MACOSX-NOT: warning: .macosx_version_min used while targeting
// CHECK: version-min-diagnostics2.s:[[@LINE-5]]:1: warning: overriding previous version directive
// CHECK: version-min-diagnostics2.s:[[@LINE-12]]:1: note: previous definition is here
.tvos_version_min 7,8,9
// WATCHOS: version-min-diagnostics2.s:[[@LINE-1]]:1: warning: .tvos_version_min should only be used for tvos targets
// MACOSX: version-min-diagnostics2.s:[[@LINE-2]]:1: warning: .tvos_version_min should only be used for tvos targets
// IOS: version-min-diagnostics2.s:[[@LINE-3]]:1: warning: .tvos_version_min should only be used for tvos targets
// TVOS-NOT: warning: .tvos_version_min should only be used for tvos targets
// CHECK: version-min-diagnostics2.s:[[@LINE-5]]:1: warning: overriding previous version_min directive
// WATCHOS: version-min-diagnostics2.s:[[@LINE-1]]:1: warning: .tvos_version_min used while targeting watchos
// MACOSX: version-min-diagnostics2.s:[[@LINE-2]]:1: warning: .tvos_version_min used while targeting macos
// IOS: version-min-diagnostics2.s:[[@LINE-3]]:1: warning: .tvos_version_min used while targeting ios
// TVOS-NOT: warning: .tvos_version_min used while targeting
// CHECK: version-min-diagnostics2.s:[[@LINE-5]]:1: warning: overriding previous version directive
// CHECK: version-min-diagnostics2.s:[[@LINE-14]]:1: note: previous definition is here
.watchos_version_min 10,11,12
// MACOSX: version-min-diagnostics2.s:[[@LINE-1]]:1: warning: .watchos_version_min should only be used for watchos targets
// IOS: version-min-diagnostics2.s:[[@LINE-2]]:1: warning: .watchos_version_min should only be used for watchos targets
// TVOS-NOT: warning: .tvos_version_min should only be used for tvos targets
// WATCHOS-NOT: warning: .watchos_version_min should only be used for watchos targets
// CHECK: version-min-diagnostics2.s:[[@LINE-5]]:1: warning: overriding previous version_min directive
// MACOSX: version-min-diagnostics2.s:[[@LINE-1]]:1: warning: .watchos_version_min used while targeting macos
// IOS: version-min-diagnostics2.s:[[@LINE-2]]:1: warning: .watchos_version_min used while targeting ios
// TVOS: version-min-diagnostics2.s:[[@LINE-3]]:1: warning: .watchos_version_min used while targeting tvos
// WATCHOS-NOT: warning: .watchos_version_min used while targeting watchos
// CHECK: version-min-diagnostics2.s:[[@LINE-5]]:1: warning: overriding previous version directive
// CHECK: version-min-diagnostics2.s:[[@LINE-14]]:1: note: previous definition is here