diff options
author | Alex Lorenz <arphaman@gmail.com> | 2020-06-29 21:04:25 -0700 |
---|---|---|
committer | Alex Lorenz <arphaman@gmail.com> | 2020-06-30 11:48:17 -0700 |
commit | 24a1447b02854f3145bf5337a82c5fd245f61ca5 (patch) | |
tree | 429535104faa1d7d64bb1355cf50172bdb24e84f /llvm/lib/MC/MCStreamer.cpp | |
parent | 7099d8e4f7d06928a3f9b5424805593fb55c20c1 (diff) | |
download | llvm-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.cpp | 129 |
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); } |