ARM: support .watchos_version_min and .tvos_version_min.

These MachO file directives are used by linkers and other tools to provide
compatibility information, much like the existing .ios_version_min and
.macosx_version_min.

llvm-svn: 251569
This commit is contained in:
Tim Northover 2015-10-28 22:36:05 +00:00
parent 748b3ffe3b
commit 2d4d161519
19 changed files with 281 additions and 55 deletions

View File

@ -99,6 +99,7 @@ public:
ARMSubArch_v7em,
ARMSubArch_v7m,
ARMSubArch_v7s,
ARMSubArch_v7k,
ARMSubArch_v6,
ARMSubArch_v6m,
ARMSubArch_v6k,
@ -156,7 +157,9 @@ public:
AMDHSA, // AMD HSA Runtime
PS4,
ELFIAMCU,
LastOSType = ELFIAMCU
TvOS, // Apple tvOS
WatchOS, // Apple watchOS
LastOSType = WatchOS
};
enum EnvironmentType {
UnknownEnvironment,
@ -401,13 +404,27 @@ public:
}
/// Is this an iOS triple.
/// Note: This identifies tvOS as a variant of iOS. If that ever
/// changes, i.e., if the two operating systems diverge or their version
/// numbers get out of sync, that will need to be changed.
/// watchOS has completely different version numbers so it is not included.
bool isiOS() const {
return getOS() == Triple::IOS;
return getOS() == Triple::IOS || isTvOS();
}
/// isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
/// Is this an Apple tvOS triple.
bool isTvOS() const {
return getOS() == Triple::TvOS;
}
/// Is this an Apple watchOS triple.
bool isWatchOS() const {
return getOS() == Triple::WatchOS;
}
/// isOSDarwin - Is this a "Darwin" OS (OS X, iOS, or watchOS).
bool isOSDarwin() const {
return isMacOSX() || isiOS();
return isMacOSX() || isiOS() || isWatchOS();
}
bool isOSNetBSD() const {

View File

@ -62,7 +62,9 @@ enum MCDataRegionType {
enum MCVersionMinType {
MCVM_IOSVersionMin, ///< .ios_version_min
MCVM_OSXVersionMin ///< .macosx_version_min
MCVM_OSXVersionMin, ///< .macosx_version_min
MCVM_TvOSVersionMin, ///< .tvos_version_min
MCVM_WatchOSVersionMin, ///< .watchos_version_min
};
} // end namespace llvm

View File

@ -71,6 +71,9 @@ public:
bool Error(SMLoc L, const Twine &Msg) {
return getParser().Error(L, Msg);
}
void Note(SMLoc L, const Twine &Msg) {
getParser().Note(L, Msg);
}
bool TokError(const Twine &Msg) {
return getParser().TokError(Msg);
}

View File

@ -241,6 +241,7 @@ ARM_CPU_NAME("cortex-a8", AK_ARMV7HL, FK_NEON, true, AEK_SEC)
ARM_CPU_NAME("cortex-m4", AK_ARMV7EM, FK_NONE, true, AEK_NONE)
ARM_CPU_NAME("swift", AK_ARMV7S, FK_NEON_VFPV4, true,
(AEK_HWDIVARM | AEK_HWDIV))
ARM_CPU_NAME("cortex-a7", AK_ARMV7K, FK_NONE, true, AEK_HWDIVARM | AEK_HWDIV)
// Invalid CPU
ARM_CPU_NAME("invalid", AK_INVALID, FK_INVALID, true, AEK_INVALID)
#undef ARM_CPU_NAME

View File

@ -132,7 +132,9 @@ namespace llvm {
LC_DYLIB_CODE_SIGN_DRS = 0x0000002Bu,
LC_ENCRYPTION_INFO_64 = 0x0000002Cu,
LC_LINKER_OPTION = 0x0000002Du,
LC_LINKER_OPTIMIZATION_HINT = 0x0000002Eu
LC_LINKER_OPTIMIZATION_HINT = 0x0000002Eu,
LC_VERSION_MIN_TVOS = 0x0000002Fu,
LC_VERSION_MIN_WATCHOS = 0x00000030u,
};
enum : uint32_t {

View File

@ -196,10 +196,18 @@ bool AsmPrinter::doInitialization(Module &M) {
unsigned Major, Minor, Update;
TT.getOSVersion(Major, Minor, Update);
// If there is a version specified, Major will be non-zero.
if (Major)
OutStreamer->EmitVersionMin((TT.isMacOSX() ?
MCVM_OSXVersionMin : MCVM_IOSVersionMin),
Major, Minor, Update);
if (Major) {
MCVersionMinType VersionType;
if (TT.isWatchOS())
VersionType = MCVM_WatchOSVersionMin;
else if (TT.isTvOS())
VersionType = MCVM_TvOSVersionMin;
else if (TT.isMacOSX())
VersionType = MCVM_OSXVersionMin;
else
VersionType = MCVM_IOSVersionMin;
OutStreamer->EmitVersionMin(VersionType, Major, Minor, Update);
}
}
// Allow the target to emit any magic that it wants at the start of the file.

View File

@ -369,6 +369,8 @@ void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
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;
}

View File

@ -490,10 +490,20 @@ MCStreamer *llvm::createMachOStreamer(MCContext &Context, MCAsmBackend &MAB,
unsigned Major, Minor, Update;
TT.getOSVersion(Major, Minor, Update);
// If there is a version specified, Major will be non-zero.
if (Major)
S->EmitVersionMin((TT.isMacOSX() ?
MCVM_OSXVersionMin : MCVM_IOSVersionMin),
Major, Minor, Update);
if (Major) {
MCVersionMinType VersionType;
if (TT.isWatchOS())
VersionType = MCVM_WatchOSVersionMin;
else if (TT.isTvOS())
VersionType = MCVM_TvOSVersionMin;
else if (TT.isMacOSX())
VersionType = MCVM_OSXVersionMin;
else {
assert(TT.isiOS() && "Must only be iOS platform left");
VersionType = MCVM_IOSVersionMin;
}
S->EmitVersionMin(VersionType, Major, Minor, Update);
}
}
if (RelaxAll)
S->getAssembler().setRelaxAll(true);

View File

@ -40,6 +40,8 @@ class DarwinAsmParser : public MCAsmParserExtension {
unsigned TAA = 0, unsigned ImplicitAlign = 0,
unsigned StubSize = 0);
SMLoc LastVersionMinDirective;
public:
DarwinAsmParser() {}
@ -166,9 +168,14 @@ public:
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv");
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident");
addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(
".watchos_version_min");
addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(".tvos_version_min");
addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(".ios_version_min");
addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(
".macosx_version_min");
LastVersionMinDirective = SMLoc();
}
bool parseDirectiveDesc(StringRef, SMLoc);
@ -892,9 +899,11 @@ bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) {
/// parseVersionMin
/// ::= .ios_version_min major,minor[,update]
/// ::= .macosx_version_min major,minor[,update]
bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc) {
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);
// Get the major version number.
@ -927,6 +936,24 @@ bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc) {
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);

View File

@ -815,8 +815,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);
write32(VersionInfo.Kind == MCVM_OSXVersionMin ? MachO::LC_VERSION_MIN_MACOSX :
MachO::LC_VERSION_MIN_IPHONEOS);
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;
}
write32(LCType);
write32(sizeof(MachO::version_min_command));
write32(EncodedVersion);
write32(0); // reserved.

View File

@ -520,6 +520,7 @@ unsigned llvm::ARM::parseArchProfile(StringRef Arch) {
return ARM::PK_R;
case ARM::AK_ARMV7:
case ARM::AK_ARMV7A:
case ARM::AK_ARMV7K:
case ARM::AK_ARMV7L:
case ARM::AK_ARMV8A:
case ARM::AK_ARMV8_1A:

View File

@ -182,6 +182,8 @@ const char *Triple::getOSTypeName(OSType Kind) {
case AMDHSA: return "amdhsa";
case PS4: return "ps4";
case ELFIAMCU: return "elfiamcu";
case TvOS: return "tvos";
case WatchOS: return "watchos";
}
llvm_unreachable("Invalid OSType");
@ -437,6 +439,8 @@ static Triple::OSType parseOS(StringRef OSName) {
.StartsWith("amdhsa", Triple::AMDHSA)
.StartsWith("ps4", Triple::PS4)
.StartsWith("elfiamcu", Triple::ELFIAMCU)
.StartsWith("tvos", Triple::TvOS)
.StartsWith("watchos", Triple::WatchOS)
.Default(Triple::UnknownOS);
}
@ -512,6 +516,8 @@ static Triple::SubArchType parseSubArch(StringRef SubArchName) {
case ARM::AK_ARMV7L:
case ARM::AK_ARMV7HL:
return Triple::ARMSubArch_v7;
case ARM::AK_ARMV7K:
return Triple::ARMSubArch_v7k;
case ARM::AK_ARMV7M:
return Triple::ARMSubArch_v7m;
case ARM::AK_ARMV7S:
@ -932,6 +938,8 @@ bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
return false;
break;
case IOS:
case TvOS:
case WatchOS:
// Ignore the version from the triple. This is only handled because the
// the clang driver combines OS X and IOS support into a common Darwin
// toolchain that wants to know the OS X version number even when targeting
@ -950,6 +958,7 @@ void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
default: llvm_unreachable("unexpected OS for Darwin triple");
case Darwin:
case MacOSX:
case WatchOS:
// Ignore the version from the triple. This is only handled because the
// the clang driver combines OS X and IOS support into a common Darwin
// toolchain that wants to know the iOS version number even when targeting
@ -959,6 +968,7 @@ void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
Micro = 0;
break;
case IOS:
case TvOS:
getOSVersion(Major, Minor, Micro);
// Default to 5.0 (or 7.0 for arm64).
if (Major == 0)

View File

@ -188,7 +188,15 @@ std::string ARM_MC::ParseARMTriple(const Triple &TT, StringRef CPU) {
// Use CPU to figure out the exact features.
ARMArchFeature = "+v7";
break;
case Triple::ARMSubArch_v7:
case Triple::ARMSubArch_v7k:
if (NoCPU)
// v7k: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureHasRAS
// A7
ARMArchFeature = "+v7,+a7,+neon,+db,+t2dsp,+ras";
else
// Use CPU to figure out the exact features.
ARMArchFeature = "+v7";
break; case Triple::ARMSubArch_v7:
// v7 CPUs have lots of different feature sets. If no CPU is specified,
// then assume v7a (e.g. cortex-a8) feature set. Otherwise, return
// the "minimum" feature set and use CPU string to figure out the exact

View File

@ -0,0 +1,13 @@
// RUN: llvm-mc -triple armv7-apple-tvos %s -filetype=obj -o - | llvm-readobj --macho-version-min | FileCheck %s
// Test the formation of the version-min load command in the MachO.
// use a nonsense but well formed version.
.tvos_version_min 99,8,7
// CHECK: MinVersion {
// CHECK-NEXT: Cmd: LC_VERSION_MIN_TVOS
// CHECK-NEXT: Size: 16
// CHECK-NEXT: Version: 99.8.7
// CHECK-NEXT: SDK: n/a
// CHECK-NEXT: }

View File

@ -15,6 +15,16 @@
.macosx_version_min 10,-1,1
.macosx_version_min 0,1,1
.macosx_version_min 70000,1
.tvos_version_min 99,2,257
.tvos_version_min 50,256,1
.tvos_version_min 10,-1,1
.tvos_version_min 0,1,1
.tvos_version_min 70000,1
.watchos_version_min 99,2,257
.watchos_version_min 50,256,1
.watchos_version_min 10,-1,1
.watchos_version_min 0,1,1
.watchos_version_min 70000,1
// CHECK: error: invalid OS update number
@ -47,3 +57,33 @@
// CHECK: error: invalid OS major version number
// CHECK: .macosx_version_min 70000,1
// CHECK: ^
// CHECK: error: invalid OS update number
// CHECK: .tvos_version_min 99,2,257
// CHECK: ^
// CHECK: error: invalid OS minor version number
// CHECK: .tvos_version_min 50,256,1
// CHECK: ^
// CHECK: error: invalid OS minor version number
// CHECK: .tvos_version_min 10,-1,1
// CHECK: ^
// CHECK: error: invalid OS major version number
// CHECK: .tvos_version_min 0,1,1
// CHECK: ^
// CHECK: error: invalid OS major version number
// CHECK: .tvos_version_min 70000,1
// CHECK: ^
// CHECK: error: invalid OS update number
// CHECK: .watchos_version_min 99,2,257
// CHECK: ^
// CHECK: error: invalid OS minor version number
// CHECK: .watchos_version_min 50,256,1
// CHECK: ^
// CHECK: error: invalid OS minor version number
// CHECK: .watchos_version_min 10,-1,1
// CHECK: ^
// CHECK: error: invalid OS major version number
// CHECK: .watchos_version_min 0,1,1
// CHECK: ^
// CHECK: error: invalid OS major version number
// CHECK: .watchos_version_min 70000,1
// CHECK: ^

View File

@ -0,0 +1,34 @@
// RUN: llvm-mc -triple i386-apple-ios %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=IOS
// RUN: llvm-mc -triple i386-apple-watchos %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=WATCHOS
// RUN: llvm-mc -triple i386-apple-tvos %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=TVOS
// 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
.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
// 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
// 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
// CHECK: version-min-diagnostics2.s:[[@LINE-14]]:1: note: previous definition is here

View File

@ -19,3 +19,19 @@
// CHECK: .macosx_version_min 10, 2
// CHECK: .macosx_version_min 10, 8, 1
// CHECK: .macosx_version_min 2, 0
.tvos_version_min 5,2,0
.tvos_version_min 3,2,1
.tvos_version_min 5,0
// CHECK: .tvos_version_min 5, 2
// CHECK: .tvos_version_min 3, 2, 1
// CHECK: .tvos_version_min 5, 0
.watchos_version_min 5,2,0
.watchos_version_min 3,2,1
.watchos_version_min 5,0
// CHECK: .watchos_version_min 5, 2
// CHECK: .watchos_version_min 3, 2, 1
// CHECK: .watchos_version_min 5, 0

View File

@ -3,12 +3,22 @@
// RUN: llvm-mc -triple x86_64-apple-darwin %s -filetype=obj -o - | llvm-objdump -macho -private-headers - | FileCheck %s --check-prefix=CHECK-DARWIN
// Test version-min load command should be inferred from triple and should always be generated on Darwin
// CHECK: cmd LC_VERSION_MIN_MACOSX
// CHECK-NEXT: cmdsize 16
// CHECK-NEXT: version 10.10
// CHECK: Load command
// CHECK: cmd LC_VERSION_MIN_MACOSX
// CHECK: cmdsize 16
// CHECK: version 10.10
// CHECK-IOS: cmd LC_VERSION_MIN_IPHONEOS
// CHECK-IOS-NEXT: cmdsize 16
// CHECK-IOS-NEXT: version 8.0
// CHECK-IOS: Load command
// CHECK-IOS: cmd LC_VERSION_MIN_IPHONEOS
// CHECK-IOS: cmdsize 16
// CHECK-IOS: version 8.0
// CHECK-DARWIN-NOT: LC_VERSION_MIN
// FIXME: llvm-objdump doesn't know about WATCHOS LC yet
// FIXME: llvm-mc -triple x86_64-apple-watchos1.0.0 %s -filetype=obj -o - | llvm-objdump -macho -private-headers - | FileCheck %s --check-prefix=CHECK-WATCHOS
// CHECK-WATCHOS: Load command
// CHECK-WATCHOS: cmd LC_VERSION_MIN_WATCHOS
// CHECK-WATCHOS: cmdsize 16
// CHECK-WATCHOS: version 1.0

View File

@ -694,38 +694,46 @@ void MachODumper::printMachODataInCode() {
void MachODumper::printMachOVersionMin() {
for (const auto &Load : Obj->load_commands()) {
if (Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX ||
Load.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) {
MachO::version_min_command VMC = Obj->getVersionMinLoadCommand(Load);
DictScope Group(W, "MinVersion");
StringRef Cmd;
if (Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX)
Cmd = "LC_VERSION_MIN_MACOSX";
else
Cmd = "LC_VERSION_MIN_IPHONEOS";
W.printString("Cmd", Cmd);
W.printNumber("Size", VMC.cmdsize);
SmallString<32> Version;
Version = utostr(MachOObjectFile::getVersionMinMajor(VMC, false)) + "." +
utostr(MachOObjectFile::getVersionMinMinor(VMC, false));
uint32_t Update = MachOObjectFile::getVersionMinUpdate(VMC, false);
if (Update != 0)
Version += "." + utostr(MachOObjectFile::getVersionMinUpdate(VMC,
false));
W.printString("Version", Version);
SmallString<32> SDK;
if (VMC.sdk == 0)
SDK = "n/a";
else {
SDK = utostr(MachOObjectFile::getVersionMinMajor(VMC, true)) + "." +
utostr(MachOObjectFile::getVersionMinMinor(VMC, true));
uint32_t Update = MachOObjectFile::getVersionMinUpdate(VMC, true);
if (Update != 0)
SDK += "." + utostr(MachOObjectFile::getVersionMinUpdate(VMC,
true));
}
W.printString("SDK", SDK);
StringRef Cmd;
switch (Load.C.cmd) {
case MachO::LC_VERSION_MIN_MACOSX:
Cmd = "LC_VERSION_MIN_MACOSX";
break;
case MachO::LC_VERSION_MIN_IPHONEOS:
Cmd = "LC_VERSION_MIN_IPHONEOS";
break;
case MachO::LC_VERSION_MIN_TVOS:
Cmd = "LC_VERSION_MIN_TVOS";
break;
case MachO::LC_VERSION_MIN_WATCHOS:
Cmd = "LC_VERSION_MIN_WATCHOS";
break;
default:
continue;
}
MachO::version_min_command VMC = Obj->getVersionMinLoadCommand(Load);
DictScope Group(W, "MinVersion");
W.printString("Cmd", Cmd);
W.printNumber("Size", VMC.cmdsize);
SmallString<32> Version;
Version = utostr(MachOObjectFile::getVersionMinMajor(VMC, false)) + "." +
utostr(MachOObjectFile::getVersionMinMinor(VMC, false));
uint32_t Update = MachOObjectFile::getVersionMinUpdate(VMC, false);
if (Update != 0)
Version += "." + utostr(MachOObjectFile::getVersionMinUpdate(VMC, false));
W.printString("Version", Version);
SmallString<32> SDK;
if (VMC.sdk == 0)
SDK = "n/a";
else {
SDK = utostr(MachOObjectFile::getVersionMinMajor(VMC, true)) + "." +
utostr(MachOObjectFile::getVersionMinMinor(VMC, true));
uint32_t Update = MachOObjectFile::getVersionMinUpdate(VMC, true);
if (Update != 0)
SDK += "." + utostr(MachOObjectFile::getVersionMinUpdate(VMC, true));
}
W.printString("SDK", SDK);
}
}