aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MCStreamer.cpp
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2020-06-29 21:04:25 -0700
committerAlex Lorenz <arphaman@gmail.com>2020-06-30 11:48:17 -0700
commit24a1447b02854f3145bf5337a82c5fd245f61ca5 (patch)
tree429535104faa1d7d64bb1355cf50172bdb24e84f /llvm/lib/MC/MCStreamer.cpp
parent7099d8e4f7d06928a3f9b5424805593fb55c20c1 (diff)
downloadllvm-24a1447b02854f3145bf5337a82c5fd245f61ca5.zip
llvm-24a1447b02854f3145bf5337a82c5fd245f61ca5.tar.gz
llvm-24a1447b02854f3145bf5337a82c5fd245f61ca5.tar.bz2
[macho] emit LC_BUILD_VERSION load command for supported OSes and platforms
This change lets LLVM use the LC_BUILD_VERSION command when building for macOS 10.14, iOS 12, tvOS 12, and watchOS 5. Additionally, this change ensures that new platforms like Apple Silicon macOS / Mac Catalyst, and simulators running on Apple Silicon alway use LC_BUILD_VERSION with the OS version set to the minimum supported OS version if the deployment target version is older. Differential Revision: https://reviews.llvm.org/D82836
Diffstat (limited to 'llvm/lib/MC/MCStreamer.cpp')
-rw-r--r--llvm/lib/MC/MCStreamer.cpp129
1 files changed, 103 insertions, 26 deletions
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 0b650ef..0893835 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -1128,6 +1128,79 @@ MCSymbol *MCStreamer::endSection(MCSection *Section) {
return Sym;
}
+static VersionTuple
+targetVersionOrMinimumSupportedOSVersion(const Triple &Target,
+ VersionTuple TargetVersion) {
+ VersionTuple Min = Target.getMinimumSupportedOSVersion();
+ return !Min.empty() && Min > TargetVersion ? Min : TargetVersion;
+}
+
+static MCVersionMinType
+getMachoVersionMinLoadCommandType(const Triple &Target) {
+ assert(Target.isOSDarwin() && "expected a darwin OS");
+ switch (Target.getOS()) {
+ case Triple::MacOSX:
+ case Triple::Darwin:
+ return MCVM_OSXVersionMin;
+ case Triple::IOS:
+ assert(!Target.isMacCatalystEnvironment() &&
+ "mac Catalyst should use LC_BUILD_VERSION");
+ return MCVM_IOSVersionMin;
+ case Triple::TvOS:
+ return MCVM_TvOSVersionMin;
+ case Triple::WatchOS:
+ return MCVM_WatchOSVersionMin;
+ default:
+ break;
+ }
+ llvm_unreachable("unexpected OS type");
+}
+
+static VersionTuple getMachoBuildVersionSupportedOS(const Triple &Target) {
+ assert(Target.isOSDarwin() && "expected a darwin OS");
+ switch (Target.getOS()) {
+ case Triple::MacOSX:
+ case Triple::Darwin:
+ return VersionTuple(10, 14);
+ case Triple::IOS:
+ // Mac Catalyst always uses the build version load command.
+ if (Target.isMacCatalystEnvironment())
+ return VersionTuple();
+ LLVM_FALLTHROUGH;
+ case Triple::TvOS:
+ return VersionTuple(12);
+ case Triple::WatchOS:
+ return VersionTuple(5);
+ default:
+ break;
+ }
+ llvm_unreachable("unexpected OS type");
+}
+
+static MachO::PlatformType
+getMachoBuildVersionPlatformType(const Triple &Target) {
+ assert(Target.isOSDarwin() && "expected a darwin OS");
+ switch (Target.getOS()) {
+ case Triple::MacOSX:
+ case Triple::Darwin:
+ return MachO::PLATFORM_MACOS;
+ case Triple::IOS:
+ if (Target.isMacCatalystEnvironment())
+ return MachO::PLATFORM_MACCATALYST;
+ return Target.isSimulatorEnvironment() ? MachO::PLATFORM_IOSSIMULATOR
+ : MachO::PLATFORM_IOS;
+ case Triple::TvOS:
+ return Target.isSimulatorEnvironment() ? MachO::PLATFORM_TVOSSIMULATOR
+ : MachO::PLATFORM_TVOS;
+ case Triple::WatchOS:
+ return Target.isSimulatorEnvironment() ? MachO::PLATFORM_WATCHOSSIMULATOR
+ : MachO::PLATFORM_WATCHOS;
+ default:
+ break;
+ }
+ llvm_unreachable("unexpected OS type");
+}
+
void MCStreamer::emitVersionForTarget(const Triple &Target,
const VersionTuple &SDKVersion) {
if (!Target.isOSBinFormatMachO() || !Target.isOSDarwin())
@@ -1136,33 +1209,37 @@ void MCStreamer::emitVersionForTarget(const Triple &Target,
if (Target.getOSMajorVersion() == 0)
return;
- unsigned Major;
- unsigned Minor;
- unsigned Update;
- if (Target.isMacCatalystEnvironment()) {
- // Mac Catalyst always uses the build version load command.
+ unsigned Major = 0;
+ unsigned Minor = 0;
+ unsigned Update = 0;
+ switch (Target.getOS()) {
+ case Triple::MacOSX:
+ case Triple::Darwin:
+ Target.getMacOSXVersion(Major, Minor, Update);
+ break;
+ case Triple::IOS:
+ case Triple::TvOS:
Target.getiOSVersion(Major, Minor, Update);
- assert(Major && "A non-zero major version is expected");
- emitBuildVersion(MachO::PLATFORM_MACCATALYST, Major, Minor, Update,
- SDKVersion);
- return;
- }
-
- MCVersionMinType VersionType;
- if (Target.isWatchOS()) {
- VersionType = MCVM_WatchOSVersionMin;
+ break;
+ case Triple::WatchOS:
Target.getWatchOSVersion(Major, Minor, Update);
- } else if (Target.isTvOS()) {
- VersionType = MCVM_TvOSVersionMin;
- Target.getiOSVersion(Major, Minor, Update);
- } else if (Target.isMacOSX()) {
- VersionType = MCVM_OSXVersionMin;
- if (!Target.getMacOSXVersion(Major, Minor, Update))
- Major = 0;
- } else {
- VersionType = MCVM_IOSVersionMin;
- Target.getiOSVersion(Major, Minor, Update);
+ break;
+ default:
+ llvm_unreachable("unexpected OS type");
}
- if (Major != 0)
- emitVersionMin(VersionType, Major, Minor, Update, SDKVersion);
+ assert(Major != 0 && "A non-zero major version is expected");
+ auto LinkedTargetVersion = targetVersionOrMinimumSupportedOSVersion(
+ Target, VersionTuple(Major, Minor, Update));
+ auto BuildVersionOSVersion = getMachoBuildVersionSupportedOS(Target);
+ if (BuildVersionOSVersion.empty() ||
+ LinkedTargetVersion >= BuildVersionOSVersion)
+ return emitBuildVersion(getMachoBuildVersionPlatformType(Target),
+ LinkedTargetVersion.getMajor(),
+ *LinkedTargetVersion.getMinor(),
+ *LinkedTargetVersion.getSubminor(), SDKVersion);
+
+ emitVersionMin(getMachoVersionMinLoadCommandType(Target),
+ LinkedTargetVersion.getMajor(),
+ *LinkedTargetVersion.getMinor(),
+ *LinkedTargetVersion.getSubminor(), SDKVersion);
}