aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MachObjectWriter.cpp
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2021-12-07 17:51:44 -0800
committerAlex Lorenz <arphaman@gmail.com>2021-12-07 18:17:47 -0800
commit0756aa397856d88f458c6836b24d36ca60fd1044 (patch)
tree7ce36f0a717971b602e85b4b6492b6660bcfceef /llvm/lib/MC/MachObjectWriter.cpp
parent5ff52be5d98a621db6de079ad09d0f94854938e8 (diff)
downloadllvm-0756aa397856d88f458c6836b24d36ca60fd1044.zip
llvm-0756aa397856d88f458c6836b24d36ca60fd1044.tar.gz
llvm-0756aa397856d88f458c6836b24d36ca60fd1044.tar.bz2
[macho] add support for emitting macho files with two build version load commands
This patch extends LLVM IR to add metadata that can be used to emit macho files with two build version load commands. It utilizes "darwin.target_variant.triple" and "darwin.target_variant.SDK Version" metadata names for that, which will be set by a future patch in clang. MachO uses two build version load commands to represent an object file / binary that is targeting both the macOS target, and the Mac Catalyst target. At runtime, a dynamic library that supports both targets can be loaded from either a native macOS or a Mac Catalyst app on a macOS system. We want to add support to this to upstream to LLVM to be able to build compiler-rt for both targets, to finish the complete support for the Mac Catalyst platform, which is right now targetable by upstream clang, but the compiler-rt bits aren't supported because of the lack of this multiple build version support. Differential Revision: https://reviews.llvm.org/D112189
Diffstat (limited to 'llvm/lib/MC/MachObjectWriter.cpp')
-rw-r--r--llvm/lib/MC/MachObjectWriter.cpp80
1 files changed, 48 insertions, 32 deletions
diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp
index 277d88c..3961cf3 100644
--- a/llvm/lib/MC/MachObjectWriter.cpp
+++ b/llvm/lib/MC/MachObjectWriter.cpp
@@ -779,6 +779,17 @@ uint64_t MachObjectWriter::writeObject(MCAssembler &Asm,
LoadCommandsSize += sizeof(MachO::version_min_command);
}
+ const MCAssembler::VersionInfoType &TargetVariantVersionInfo =
+ Layout.getAssembler().getDarwinTargetVariantVersionInfo();
+
+ // Add the target variant version info load command size, if used.
+ if (TargetVariantVersionInfo.Major != 0) {
+ ++NumLoadCommands;
+ assert(TargetVariantVersionInfo.EmitBuildVersion &&
+ "target variant should use build version");
+ LoadCommandsSize += sizeof(MachO::build_version_command);
+ }
+
// Add the data-in-code load command size, if used.
unsigned NumDataRegions = Asm.getDataRegions().size();
if (NumDataRegions) {
@@ -862,38 +873,43 @@ uint64_t MachObjectWriter::writeObject(MCAssembler &Asm,
}
// Write out the deployment target information, if it's available.
- if (VersionInfo.Major != 0) {
- auto EncodeVersion = [](VersionTuple V) -> uint32_t {
- assert(!V.empty() && "empty version");
- unsigned Update = V.getSubminor() ? *V.getSubminor() : 0;
- unsigned Minor = V.getMinor() ? *V.getMinor() : 0;
- assert(Update < 256 && "unencodable update target version");
- assert(Minor < 256 && "unencodable minor target version");
- assert(V.getMajor() < 65536 && "unencodable major target version");
- return Update | (Minor << 8) | (V.getMajor() << 16);
- };
- uint32_t EncodedVersion = EncodeVersion(
- VersionTuple(VersionInfo.Major, VersionInfo.Minor, VersionInfo.Update));
- uint32_t SDKVersion = !VersionInfo.SDKVersion.empty()
- ? EncodeVersion(VersionInfo.SDKVersion)
- : 0;
- if (VersionInfo.EmitBuildVersion) {
- // FIXME: Currently empty tools. Add clang version in the future.
- W.write<uint32_t>(MachO::LC_BUILD_VERSION);
- W.write<uint32_t>(sizeof(MachO::build_version_command));
- W.write<uint32_t>(VersionInfo.TypeOrPlatform.Platform);
- W.write<uint32_t>(EncodedVersion);
- W.write<uint32_t>(SDKVersion);
- W.write<uint32_t>(0); // Empty tools list.
- } else {
- MachO::LoadCommandType LCType
- = getLCFromMCVM(VersionInfo.TypeOrPlatform.Type);
- W.write<uint32_t>(LCType);
- W.write<uint32_t>(sizeof(MachO::version_min_command));
- W.write<uint32_t>(EncodedVersion);
- W.write<uint32_t>(SDKVersion);
- }
- }
+ auto EmitDeploymentTargetVersion =
+ [&](const MCAssembler::VersionInfoType &VersionInfo) {
+ auto EncodeVersion = [](VersionTuple V) -> uint32_t {
+ assert(!V.empty() && "empty version");
+ unsigned Update = V.getSubminor() ? *V.getSubminor() : 0;
+ unsigned Minor = V.getMinor() ? *V.getMinor() : 0;
+ assert(Update < 256 && "unencodable update target version");
+ assert(Minor < 256 && "unencodable minor target version");
+ assert(V.getMajor() < 65536 && "unencodable major target version");
+ return Update | (Minor << 8) | (V.getMajor() << 16);
+ };
+ uint32_t EncodedVersion = EncodeVersion(VersionTuple(
+ VersionInfo.Major, VersionInfo.Minor, VersionInfo.Update));
+ uint32_t SDKVersion = !VersionInfo.SDKVersion.empty()
+ ? EncodeVersion(VersionInfo.SDKVersion)
+ : 0;
+ if (VersionInfo.EmitBuildVersion) {
+ // FIXME: Currently empty tools. Add clang version in the future.
+ W.write<uint32_t>(MachO::LC_BUILD_VERSION);
+ W.write<uint32_t>(sizeof(MachO::build_version_command));
+ W.write<uint32_t>(VersionInfo.TypeOrPlatform.Platform);
+ W.write<uint32_t>(EncodedVersion);
+ W.write<uint32_t>(SDKVersion);
+ W.write<uint32_t>(0); // Empty tools list.
+ } else {
+ MachO::LoadCommandType LCType =
+ getLCFromMCVM(VersionInfo.TypeOrPlatform.Type);
+ W.write<uint32_t>(LCType);
+ W.write<uint32_t>(sizeof(MachO::version_min_command));
+ W.write<uint32_t>(EncodedVersion);
+ W.write<uint32_t>(SDKVersion);
+ }
+ };
+ if (VersionInfo.Major != 0)
+ EmitDeploymentTargetVersion(VersionInfo);
+ if (TargetVariantVersionInfo.Major != 0)
+ EmitDeploymentTargetVersion(TargetVariantVersionInfo);
// Write the data-in-code load command, if used.
uint64_t DataInCodeTableEnd = RelocTableEnd + NumDataRegions * 8;