From 856a0380260e2735f51b059822674bd47961c050 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Wed, 28 Oct 2015 22:36:05 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@251569 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/Triple.h | 25 +++++++-- include/llvm/MC/MCDirectives.h | 4 +- include/llvm/MC/MCParser/MCAsmParserExtension.h | 3 + include/llvm/Support/ARMTargetParser.def | 1 + include/llvm/Support/MachO.h | 4 +- lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 16 ++++-- lib/MC/MCAsmStreamer.cpp | 2 + lib/MC/MCMachOStreamer.cpp | 18 ++++-- lib/MC/MCParser/DarwinAsmParser.cpp | 29 +++++++++- lib/MC/MachObjectWriter.cpp | 18 +++++- lib/Support/TargetParser.cpp | 1 + lib/Support/Triple.cpp | 10 ++++ lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp | 10 +++- test/MC/MachO/ARM/tvos-version-min-load-command.s | 13 +++++ test/MC/MachO/ARM/version-min-diagnostics.s | 40 +++++++++++++ test/MC/MachO/ARM/version-min-diagnostics2.s | 34 ++++++++++++ test/MC/MachO/ARM/version-min.s | 16 ++++++ test/MC/MachO/darwin-version-min-load-command.s | 22 ++++++-- tools/llvm-readobj/MachODumper.cpp | 68 +++++++++++++---------- 19 files changed, 280 insertions(+), 54 deletions(-) create mode 100644 test/MC/MachO/ARM/tvos-version-min-load-command.s create mode 100644 test/MC/MachO/ARM/version-min-diagnostics2.s diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 5f3742c8998..4ed694cfa99 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -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 { diff --git a/include/llvm/MC/MCDirectives.h b/include/llvm/MC/MCDirectives.h index f9d66e0b15d..326b2a1ac06 100644 --- a/include/llvm/MC/MCDirectives.h +++ b/include/llvm/MC/MCDirectives.h @@ -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 diff --git a/include/llvm/MC/MCParser/MCAsmParserExtension.h b/include/llvm/MC/MCParser/MCAsmParserExtension.h index 077fd21e073..30b25dcfdae 100644 --- a/include/llvm/MC/MCParser/MCAsmParserExtension.h +++ b/include/llvm/MC/MCParser/MCAsmParserExtension.h @@ -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); } diff --git a/include/llvm/Support/ARMTargetParser.def b/include/llvm/Support/ARMTargetParser.def index 39979d01fd6..523a5edfcae 100644 --- a/include/llvm/Support/ARMTargetParser.def +++ b/include/llvm/Support/ARMTargetParser.def @@ -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 diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h index 0428198cce6..54b8745de1c 100644 --- a/include/llvm/Support/MachO.h +++ b/include/llvm/Support/MachO.h @@ -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 { diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index f073118fd00..00762ca0ca8 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -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. diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index a6c4e282a2d..2f06415c21c 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -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; } diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 03868b00fb8..52ecf9fcfbf 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -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); diff --git a/lib/MC/MCParser/DarwinAsmParser.cpp b/lib/MC/MCParser/DarwinAsmParser.cpp index 5e99ad092f7..582d43623e8 100644 --- a/lib/MC/MCParser/DarwinAsmParser.cpp +++ b/lib/MC/MCParser/DarwinAsmParser.cpp @@ -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(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); diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp index 17023d82d62..324385fa132 100644 --- a/lib/MC/MachObjectWriter.cpp +++ b/lib/MC/MachObjectWriter.cpp @@ -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. diff --git a/lib/Support/TargetParser.cpp b/lib/Support/TargetParser.cpp index 7a870775ee4..b6cb19890c2 100644 --- a/lib/Support/TargetParser.cpp +++ b/lib/Support/TargetParser.cpp @@ -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: diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp index 142a9b9e200..8964fc09985 100644 --- a/lib/Support/Triple.cpp +++ b/lib/Support/Triple.cpp @@ -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) diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp index 79d9cef06ac..097b683493c 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -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 diff --git a/test/MC/MachO/ARM/tvos-version-min-load-command.s b/test/MC/MachO/ARM/tvos-version-min-load-command.s new file mode 100644 index 00000000000..3c9b237d695 --- /dev/null +++ b/test/MC/MachO/ARM/tvos-version-min-load-command.s @@ -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: } diff --git a/test/MC/MachO/ARM/version-min-diagnostics.s b/test/MC/MachO/ARM/version-min-diagnostics.s index 15d44d31661..76c3268dafb 100644 --- a/test/MC/MachO/ARM/version-min-diagnostics.s +++ b/test/MC/MachO/ARM/version-min-diagnostics.s @@ -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: ^ diff --git a/test/MC/MachO/ARM/version-min-diagnostics2.s b/test/MC/MachO/ARM/version-min-diagnostics2.s new file mode 100644 index 00000000000..0689cd41f70 --- /dev/null +++ b/test/MC/MachO/ARM/version-min-diagnostics2.s @@ -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 diff --git a/test/MC/MachO/ARM/version-min.s b/test/MC/MachO/ARM/version-min.s index 0a40338ed5e..d4840db7b6b 100644 --- a/test/MC/MachO/ARM/version-min.s +++ b/test/MC/MachO/ARM/version-min.s @@ -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 diff --git a/test/MC/MachO/darwin-version-min-load-command.s b/test/MC/MachO/darwin-version-min-load-command.s index c8364846aeb..3c4df0f57d1 100644 --- a/test/MC/MachO/darwin-version-min-load-command.s +++ b/test/MC/MachO/darwin-version-min-load-command.s @@ -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 diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index ab77fdcf136..58d2c9fca47 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -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); + 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) - 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); + SDK += "." + utostr(MachOObjectFile::getVersionMinUpdate(VMC, true)); } + W.printString("SDK", SDK); } } -- 2.11.0