[llvm] [llvm][macho] Support the LC_TARGET_TRIPLE load command (PR #210276)
Ian Anderson via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 17 02:52:20 PDT 2026
https://github.com/ian-twilightcoder updated https://github.com/llvm/llvm-project/pull/210276
>From ef80a9bc8e6f0c4229ea11be9c55d40047153efc Mon Sep 17 00:00:00 2001
From: Ian Anderson <iana at apple.com>
Date: Fri, 6 Feb 2026 00:52:18 -0800
Subject: [PATCH] [llvm][macho] Support the LC_TARGET_TRIPLE load command
Add support for the new LC_TARGET_TRIPLE load command.
rdar://140301164
---
llvm/include/llvm/BinaryFormat/MachO.def | 2 +
llvm/include/llvm/BinaryFormat/MachO.h | 12 ++++
.../llvm/ExecutionEngine/Orc/MachOBuilder.h | 19 ++++++
.../llvm/ExecutionEngine/Orc/MachOPlatform.h | 2 +
llvm/include/llvm/MC/MCMachObjectWriter.h | 4 ++
llvm/include/llvm/MC/MCStreamer.h | 2 +
llvm/include/llvm/Object/MachO.h | 2 +
.../lib/ExecutionEngine/Orc/MachOPlatform.cpp | 3 +
llvm/lib/MC/MCAsmStreamer.cpp | 6 ++
llvm/lib/MC/MCMachOStreamer.cpp | 5 ++
llvm/lib/MC/MCParser/DarwinAsmParser.cpp | 22 +++++++
llvm/lib/MC/MachObjectWriter.cpp | 30 ++++++++++
llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp | 1 +
llvm/lib/Object/MachOObjectFile.cpp | 50 ++++++++++++++++
llvm/lib/ObjectYAML/MachOEmitter.cpp | 6 ++
llvm/lib/ObjectYAML/MachOYAML.cpp | 11 ++++
.../Inputs/MachO_Universal_libFoo_dylib.yaml | 28 +++++----
llvm/test/MC/MachO/target-triple-padding.s | 27 +++++++++
llvm/test/MC/MachO/target-triple.s | 47 +++++++++++++++
...o-invalid-target-triple-name_offset-toobig | Bin 0 -> 40 bytes
...invalid-target-triple-name_offset-toosmall | Bin 0 -> 44 bytes
.../macho-invalid-target-triple-name_toobig | Bin 0 -> 44 bytes
.../Inputs/macho-invalid-target-triple-small | Bin 0 -> 44 bytes
llvm/test/Object/macho-invalid.test | 12 ++++
.../MachO/target_triple_command.yaml | 26 +++++++++
.../llvm-objdump/MachO/target-triple.yaml | 54 ++++++++++++++++++
llvm/tools/llvm-objdump/MachODump.cpp | 20 +++++++
llvm/tools/llvm-readobj/MachODumper.cpp | 17 ++++++
llvm/tools/llvm-readobj/ObjDumper.h | 1 +
llvm/tools/llvm-readobj/Opts.td | 1 +
llvm/tools/llvm-readobj/llvm-readobj.cpp | 4 ++
llvm/tools/obj2yaml/macho2yaml.cpp | 9 +++
32 files changed, 413 insertions(+), 10 deletions(-)
create mode 100644 llvm/test/MC/MachO/target-triple-padding.s
create mode 100644 llvm/test/MC/MachO/target-triple.s
create mode 100644 llvm/test/Object/Inputs/macho-invalid-target-triple-name_offset-toobig
create mode 100644 llvm/test/Object/Inputs/macho-invalid-target-triple-name_offset-toosmall
create mode 100644 llvm/test/Object/Inputs/macho-invalid-target-triple-name_toobig
create mode 100644 llvm/test/Object/Inputs/macho-invalid-target-triple-small
create mode 100644 llvm/test/ObjectYAML/MachO/target_triple_command.yaml
create mode 100644 llvm/test/tools/llvm-objdump/MachO/target-triple.yaml
diff --git a/llvm/include/llvm/BinaryFormat/MachO.def b/llvm/include/llvm/BinaryFormat/MachO.def
index 4124c723ec021..472f0c52b62e0 100644
--- a/llvm/include/llvm/BinaryFormat/MachO.def
+++ b/llvm/include/llvm/BinaryFormat/MachO.def
@@ -78,6 +78,7 @@ HANDLE_LOAD_COMMAND(LC_DYLD_EXPORTS_TRIE, 0x80000033u, linkedit_data_command)
HANDLE_LOAD_COMMAND(LC_DYLD_CHAINED_FIXUPS, 0x80000034u, linkedit_data_command)
HANDLE_LOAD_COMMAND(LC_FILESET_ENTRY, 0x80000035u, fileset_entry_command)
HANDLE_LOAD_COMMAND(LC_ATOM_INFO, 0x00000036u, linkedit_data_command)
+HANDLE_LOAD_COMMAND(LC_TARGET_TRIPLE, 0x00000039u, target_triple_command)
#endif
@@ -110,6 +111,7 @@ LOAD_COMMAND_STRUCT(sub_library_command)
LOAD_COMMAND_STRUCT(sub_umbrella_command)
LOAD_COMMAND_STRUCT(symseg_command)
LOAD_COMMAND_STRUCT(symtab_command)
+LOAD_COMMAND_STRUCT(target_triple_command)
LOAD_COMMAND_STRUCT(thread_command)
LOAD_COMMAND_STRUCT(twolevel_hints_command)
LOAD_COMMAND_STRUCT(uuid_command)
diff --git a/llvm/include/llvm/BinaryFormat/MachO.h b/llvm/include/llvm/BinaryFormat/MachO.h
index bea1bcaf2bf75..aedf7d15e9612 100644
--- a/llvm/include/llvm/BinaryFormat/MachO.h
+++ b/llvm/include/llvm/BinaryFormat/MachO.h
@@ -922,6 +922,12 @@ struct build_version_command {
uint32_t ntools; // number of tool entries following this
};
+struct target_triple_command {
+ uint32_t cmd; // LC_TARGET_TRIPLE
+ uint32_t cmdsize; // including string
+ uint32_t triple; // target triple string
+};
+
struct dyld_env_command {
uint32_t cmd;
uint32_t cmdsize;
@@ -1517,6 +1523,12 @@ inline void swapStruct(build_version_command &C) {
sys::swapByteOrder(C.ntools);
}
+inline void swapStruct(target_triple_command &C) {
+ sys::swapByteOrder(C.cmd);
+ sys::swapByteOrder(C.cmdsize);
+ sys::swapByteOrder(C.triple);
+}
+
inline void swapStruct(build_tool_version &C) {
sys::swapByteOrder(C.tool);
sys::swapByteOrder(C.version);
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/MachOBuilder.h b/llvm/include/llvm/ExecutionEngine/Orc/MachOBuilder.h
index 2af2dfed1c41a..e7f2ab42745e3 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/MachOBuilder.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/MachOBuilder.h
@@ -154,6 +154,25 @@ struct MachOBuilderLoadCommand<MachO::LC_RPATH>
std::string Path;
};
+template <>
+struct MachOBuilderLoadCommand<MachO::LC_TARGET_TRIPLE>
+ : public MachOBuilderLoadCommandImplBase<MachO::LC_TARGET_TRIPLE> {
+ MachOBuilderLoadCommand(std::string TargetTriple)
+ : MachOBuilderLoadCommandImplBase(12u),
+ TargetTriple(std::move(TargetTriple)) {
+ cmdsize += (this->TargetTriple.size() + 1 + 3) & ~0x3;
+ }
+
+ size_t write(MutableArrayRef<char> Buf, size_t Offset,
+ bool SwapStruct) override {
+ Offset = writeMachOStruct(Buf, Offset, rawStruct(), SwapStruct);
+ strcpy(Buf.data() + Offset, TargetTriple.data());
+ return Offset + ((TargetTriple.size() + 1 + 3) & ~0x3);
+ }
+
+ std::string TargetTriple;
+};
+
// Builds MachO objects.
template <typename MachOTraits> class MachOBuilder {
private:
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h b/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
index 944f099c38b61..e7fd4398b5abe 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
@@ -89,6 +89,8 @@ class LLVM_ABI MachOPlatform : public Platform {
std::vector<std::string> RPaths;
/// List of LC_BUILD_VERSIONs.
std::vector<BuildVersionOpts> BuildVersions;
+ /// Optional LC_TARGET_TRIPLE.
+ std::optional<std::string> TargetTriple;
/// Optional UUID. If set, this will be used to add an LC_UUID command.
std::optional<std::array<uint8_t, 16>> UUID;
diff --git a/llvm/include/llvm/MC/MCMachObjectWriter.h b/llvm/include/llvm/MC/MCMachObjectWriter.h
index 2163312b9e3c8..125c45d34758b 100644
--- a/llvm/include/llvm/MC/MCMachObjectWriter.h
+++ b/llvm/include/llvm/MC/MCMachObjectWriter.h
@@ -166,6 +166,8 @@ class LLVM_ABI MachObjectWriter final : public MCObjectWriter {
VersionInfoType VersionInfo{};
VersionInfoType TargetVariantVersionInfo{};
+ std::optional<std::string> TargetTriple;
+
// The list of linker options for LC_LINKER_OPTION.
std::vector<std::vector<std::string>> LinkerOptions;
@@ -247,6 +249,8 @@ class LLVM_ABI MachObjectWriter final : public MCObjectWriter {
TargetVariantVersionInfo.SDKVersion = SDKVersion;
}
+ void setTargetTriple(StringRef Triple) { TargetTriple = Triple; }
+
std::vector<std::vector<std::string>> &getLinkerOptions() {
return LinkerOptions;
}
diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h
index f1479f860e885..d33be39744a44 100644
--- a/llvm/include/llvm/MC/MCStreamer.h
+++ b/llvm/include/llvm/MC/MCStreamer.h
@@ -528,6 +528,8 @@ class LLVM_ABI MCStreamer {
unsigned Update,
VersionTuple SDKVersion) {}
+ virtual void emitTargetTriple(StringRef TargetTriple) {}
+
void emitVersionForTarget(const Triple &Target,
const VersionTuple &SDKVersion,
const Triple *DarwinTargetVariantTriple,
diff --git a/llvm/include/llvm/Object/MachO.h b/llvm/include/llvm/Object/MachO.h
index f4c1e30b097ee..cafd6ed3fa9f2 100644
--- a/llvm/include/llvm/Object/MachO.h
+++ b/llvm/include/llvm/Object/MachO.h
@@ -668,6 +668,8 @@ class LLVM_ABI MachOObjectFile : public ObjectFile {
getNoteLoadCommand(const LoadCommandInfo &L) const;
MachO::build_version_command
getBuildVersionLoadCommand(const LoadCommandInfo &L) const;
+ MachO::target_triple_command
+ getTargetTripleLoadCommand(const LoadCommandInfo &L) const;
MachO::build_tool_version
getBuildToolVersion(unsigned index) const;
MachO::dylib_command
diff --git a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
index d7c0eb6bba2fd..61b2dfd3e6ef9 100644
--- a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
@@ -1772,6 +1772,9 @@ jitlink::Block &createHeaderBlock(MachOPlatform &MOP,
B.template addLoadCommand<MachO::LC_BUILD_VERSION>(
BV.Platform, BV.MinOS, BV.SDK, static_cast<uint32_t>(0));
+ if (Opts.TargetTriple)
+ B.template addLoadCommand<MachO::LC_TARGET_TRIPLE>(*Opts.TargetTriple);
+
using LoadKind = MachOPlatform::HeaderOptions::LoadDylibCmd::LoadKind;
for (auto &LD : Opts.LoadDylibs) {
switch (LD.K) {
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 037b44762875e..0a2e91dde2324 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -299,6 +299,7 @@ class MCAsmStreamer final : public MCAsmBaseStreamer {
void emitDarwinTargetVariantBuildVersion(unsigned Platform, unsigned Major,
unsigned Minor, unsigned Update,
VersionTuple SDKVersion) override;
+ void emitTargetTriple(StringRef TargetTriple) override;
void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
void emitConditionalAssignment(MCSymbol *Symbol,
@@ -822,6 +823,11 @@ void MCAsmStreamer::emitDarwinTargetVariantBuildVersion(
emitBuildVersion(Platform, Major, Minor, Update, SDKVersion);
}
+void MCAsmStreamer::emitTargetTriple(StringRef TargetTriple) {
+ OS << "\t.target_triple \"" << TargetTriple << '"';
+ EmitEOL();
+}
+
void MCAsmStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
bool UseSet = MAI->usesSetToEquateSymbol();
if (UseSet)
diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp
index dbb5dd79d1eb5..5e6726f8979ee 100644
--- a/llvm/lib/MC/MCMachOStreamer.cpp
+++ b/llvm/lib/MC/MCMachOStreamer.cpp
@@ -95,6 +95,7 @@ class MCMachOStreamer : public MCObjectStreamer {
void emitDarwinTargetVariantBuildVersion(unsigned Platform, unsigned Major,
unsigned Minor, unsigned Update,
VersionTuple SDKVersion) override;
+ void emitTargetTriple(StringRef TargetTriple) override;
bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
@@ -254,6 +255,10 @@ void MCMachOStreamer::emitDarwinTargetVariantBuildVersion(
Minor, Update, SDKVersion);
}
+void MCMachOStreamer::emitTargetTriple(StringRef TargetTriple) {
+ getWriter().setTargetTriple(TargetTriple);
+}
+
bool MCMachOStreamer::emitSymbolAttribute(MCSymbol *Sym,
MCSymbolAttr Attribute) {
auto *Symbol = static_cast<MCSymbolMachO *>(Sym);
diff --git a/llvm/lib/MC/MCParser/DarwinAsmParser.cpp b/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
index c4c4c5eab2224..ba6813c142266 100644
--- a/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
@@ -192,6 +192,8 @@ class DarwinAsmParser : public MCAsmParserExtension {
addDirectiveHandler<&DarwinAsmParser::parseMacOSXVersionMin>(
".macosx_version_min");
addDirectiveHandler<&DarwinAsmParser::parseBuildVersion>(".build_version");
+ addDirectiveHandler<&DarwinAsmParser::parseTargetTripleDirective>(
+ ".target_triple");
addDirectiveHandler<&DarwinAsmParser::parseDirectiveCGProfile>(
".cg_profile");
@@ -457,6 +459,7 @@ class DarwinAsmParser : public MCAsmParserExtension {
}
bool parseBuildVersion(StringRef Directive, SMLoc Loc);
+ bool parseTargetTripleDirective(StringRef Directive, SMLoc Loc);
bool parseVersionMin(StringRef Directive, SMLoc Loc, MCVersionMinType Type);
bool parseMajorMinorVersionComponent(unsigned *Major, unsigned *Minor,
const char *VersionName);
@@ -1186,6 +1189,25 @@ bool DarwinAsmParser::parseBuildVersion(StringRef Directive, SMLoc Loc) {
return false;
}
+/// parseTargetTripleDirective
+/// ::= .target_triple parseTargetTriple
+bool DarwinAsmParser::parseTargetTripleDirective(StringRef Directive,
+ SMLoc Loc) {
+ StringRef TargetTriple;
+ SMLoc TargetTripleLoc = getTok().getLoc();
+ if (getParser().parseIdentifier(TargetTriple))
+ return TokError("target triple expected");
+ std::string NormalizedTriple = Triple::normalize(TargetTriple);
+ if (!Triple(NormalizedTriple).isOSDarwin())
+ return Error(TargetTripleLoc, "non-Darwin target triple");
+
+ if (parseEOL())
+ return addErrorSuffix(" in '.target_triple' directive");
+
+ getStreamer().emitTargetTriple(NormalizedTriple);
+ return false;
+}
+
/// parseDirectiveCGProfile
/// ::= .cg_profile from, to, count
bool DarwinAsmParser::parseDirectiveCGProfile(StringRef S, SMLoc Loc) {
diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp
index e274d886c22d8..790f7595807b9 100644
--- a/llvm/lib/MC/MachObjectWriter.cpp
+++ b/llvm/lib/MC/MachObjectWriter.cpp
@@ -844,6 +844,18 @@ uint64_t MachObjectWriter::writeObject() {
LoadCommandsSize += sizeof(MachO::build_version_command);
}
+ // Add the target triple load command size, if used.
+ uint32_t TargetTripleCommandSize = 0;
+ if (TargetTriple) {
+ ++NumLoadCommands;
+ // The full command is the command struct plus the NUL terminated triple
+ // string, all padded to align.
+ TargetTripleCommandSize =
+ alignTo(sizeof(MachO::target_triple_command) + TargetTriple->size() + 1,
+ is64Bit() ? 8 : 4);
+ LoadCommandsSize += TargetTripleCommandSize;
+ }
+
// Add the data-in-code load command size, if used.
unsigned NumDataRegions = DataRegions.size();
if (NumDataRegions) {
@@ -977,6 +989,24 @@ uint64_t MachObjectWriter::writeObject() {
if (TargetVariantVersionInfo.Major != 0)
EmitDeploymentTargetVersion(TargetVariantVersionInfo);
+ // Write the target triple load command, if used.
+ if (TargetTriple) {
+ assert((TargetTripleCommandSize > sizeof(MachO::target_triple_command)) &&
+ "target triple load command size is too small");
+
+ // Write the command struct
+ W.write<uint32_t>(MachO::LC_TARGET_TRIPLE);
+ W.write<uint32_t>(TargetTripleCommandSize);
+ W.write<uint32_t>(sizeof(
+ MachO::target_triple_command)); // Offset to the triple string - right
+ // after the command struct.
+
+ // Write the triple string, NUL byte, and command padding.
+ uint64_t RemainingSize =
+ TargetTripleCommandSize - sizeof(MachO::target_triple_command);
+ writeWithPadding(*TargetTriple, RemainingSize);
+ }
+
// Write the data-in-code load command, if used.
uint64_t DataInCodeTableEnd = RelocTableEnd + NumDataRegions * 8;
if (NumDataRegions) {
diff --git a/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp b/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
index a8c5d05e4605a..8cd418276f851 100644
--- a/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
+++ b/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
@@ -447,6 +447,7 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
case MachO::LC_VERSION_MIN_TVOS:
case MachO::LC_VERSION_MIN_WATCHOS:
case MachO::LC_BUILD_VERSION:
+ case MachO::LC_TARGET_TRIPLE:
case MachO::LC_ID_DYLIB:
case MachO::LC_LOAD_DYLIB:
case MachO::LC_LOAD_WEAK_DYLIB:
diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp
index 3342c99e245ca..3d48d18668f02 100644
--- a/llvm/lib/Object/MachOObjectFile.cpp
+++ b/llvm/lib/Object/MachOObjectFile.cpp
@@ -883,6 +883,48 @@ parseBuildVersionCommand(const MachOObjectFile &Obj,
return Error::success();
}
+static Error
+checkTargetTripleCommand(const MachOObjectFile &Obj,
+ const MachOObjectFile::LoadCommandInfo &Load,
+ uint32_t LoadCommandIndex) {
+ // Check the command size is big enough for the command struct.
+ if (Load.C.cmdsize < sizeof(MachO::target_triple_command))
+ return malformedError("load command " + Twine(LoadCommandIndex) +
+ " LC_TARGET_TRIPLE cmdsize too small");
+
+ auto TTOrErr = getStructOrErr<MachO::target_triple_command>(Obj, Load.Ptr);
+ if (!TTOrErr)
+ return TTOrErr.takeError();
+ MachO::target_triple_command TT = TTOrErr.get();
+
+ // Check the triple offset is after the command struct.
+ if (TT.triple < sizeof(MachO::target_triple_command))
+ return malformedError(
+ "load command " + Twine(LoadCommandIndex) +
+ " LC_TARGET_TRIPLE triple.offset field too small, not past the end of "
+ "the target_triple_command struct");
+
+ // Check the triple offset is before the end of the command.
+ if (TT.triple >= TT.cmdsize)
+ return malformedError("load command " + Twine(LoadCommandIndex) +
+ " LC_TARGET_TRIPLE triple.offset field extends past "
+ "the end of the load command");
+
+ // Check there is a NUL between the starting offset of the triple and the end
+ // of the command.
+ uint32_t i;
+ const char *P = (const char *)Load.Ptr;
+ for (i = TT.triple; i < TT.cmdsize; i++)
+ if (P[i] == '\0')
+ break;
+ if (i >= TT.cmdsize)
+ return malformedError("load command " + Twine(LoadCommandIndex) +
+ " LC_TARGET_TRIPLE triple name extends past the end "
+ "of the load command");
+
+ return Error::success();
+}
+
static Error checkRpathCommand(const MachOObjectFile &Obj,
const MachOObjectFile::LoadCommandInfo &Load,
uint32_t LoadCommandIndex) {
@@ -1475,6 +1517,9 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
} else if (Load.C.cmd == MachO::LC_BUILD_VERSION) {
if ((Err = parseBuildVersionCommand(*this, Load, BuildTools, I)))
return;
+ } else if (Load.C.cmd == MachO::LC_TARGET_TRIPLE) {
+ if ((Err = checkTargetTripleCommand(*this, Load, I)))
+ return;
} else if (Load.C.cmd == MachO::LC_RPATH) {
if ((Err = checkRpathCommand(*this, Load, I)))
return;
@@ -4750,6 +4795,11 @@ MachOObjectFile::getBuildVersionLoadCommand(const LoadCommandInfo &L) const {
return getStruct<MachO::build_version_command>(*this, L.Ptr);
}
+MachO::target_triple_command
+MachOObjectFile::getTargetTripleLoadCommand(const LoadCommandInfo &L) const {
+ return getStruct<MachO::target_triple_command>(*this, L.Ptr);
+}
+
MachO::build_tool_version
MachOObjectFile::getBuildToolVersion(unsigned index) const {
return getStruct<MachO::build_tool_version>(*this, BuildTools[index]);
diff --git a/llvm/lib/ObjectYAML/MachOEmitter.cpp b/llvm/lib/ObjectYAML/MachOEmitter.cpp
index cf7202c7da949..644041a72df50 100644
--- a/llvm/lib/ObjectYAML/MachOEmitter.cpp
+++ b/llvm/lib/ObjectYAML/MachOEmitter.cpp
@@ -238,6 +238,12 @@ size_t writeLoadCommandData<MachO::build_version_command>(
return BytesWritten;
}
+template <>
+size_t writeLoadCommandData<MachO::target_triple_command>(
+ MachOYAML::LoadCommand &LC, raw_ostream &OS, bool IsLittleEndian) {
+ return writePayloadString(LC, OS);
+}
+
void ZeroFillBytes(raw_ostream &OS, size_t Size) {
std::vector<uint8_t> FillData(Size, 0);
OS.write(reinterpret_cast<char *>(FillData.data()), Size);
diff --git a/llvm/lib/ObjectYAML/MachOYAML.cpp b/llvm/lib/ObjectYAML/MachOYAML.cpp
index 32015ddeb3618..8cb9b6ebb9f21 100644
--- a/llvm/lib/ObjectYAML/MachOYAML.cpp
+++ b/llvm/lib/ObjectYAML/MachOYAML.cpp
@@ -276,6 +276,12 @@ void mapLoadCommandData<MachO::build_version_command>(
IO.mapOptional("Tools", LoadCommand.Tools);
}
+template <>
+void mapLoadCommandData<MachO::target_triple_command>(
+ IO &IO, MachOYAML::LoadCommand &LoadCommand) {
+ IO.mapOptional("Content", LoadCommand.Content);
+}
+
void MappingTraits<MachOYAML::LoadCommand>::mapping(
IO &IO, MachOYAML::LoadCommand &LoadCommand) {
MachO::LoadCommandType TempCmd = static_cast<MachO::LoadCommandType>(
@@ -624,6 +630,11 @@ void MappingTraits<MachO::build_version_command>::mapping(
IO.mapRequired("ntools", LoadCommand.ntools);
}
+void MappingTraits<MachO::target_triple_command>::mapping(
+ IO &IO, MachO::target_triple_command &LoadCommand) {
+ IO.mapRequired("triple", LoadCommand.triple);
+}
+
void MappingTraits<MachO::fileset_entry_command>::mapping(
IO &IO, MachO::fileset_entry_command &LoadCommand) {
IO.mapRequired("vmaddr", LoadCommand.vmaddr);
diff --git a/llvm/test/ExecutionEngine/JITLink/Generic/Inputs/MachO_Universal_libFoo_dylib.yaml b/llvm/test/ExecutionEngine/JITLink/Generic/Inputs/MachO_Universal_libFoo_dylib.yaml
index 56e976a3c3bbc..613bdbe5f1708 100644
--- a/llvm/test/ExecutionEngine/JITLink/Generic/Inputs/MachO_Universal_libFoo_dylib.yaml
+++ b/llvm/test/ExecutionEngine/JITLink/Generic/Inputs/MachO_Universal_libFoo_dylib.yaml
@@ -26,8 +26,8 @@ Slices:
cputype: 0x1000007
cpusubtype: 0x3
filetype: 0x6
- ncmds: 13
- sizeofcmds: 568
+ ncmds: 14
+ sizeofcmds: 608
flags: 0x100085
reserved: 0x0
LoadCommands:
@@ -45,9 +45,9 @@ Slices:
Sections:
- sectname: __text
segname: __TEXT
- addr: 0x2A0
+ addr: 0x2C8
size: 3
- offset: 0x2A0
+ offset: 0x2C8
align: 4
reloff: 0x0
nreloc: 0
@@ -122,6 +122,10 @@ Slices:
Tools:
- tool: 3
version: 76481792
+ - cmd: LC_TARGET_TRIPLE
+ cmdsize: 40
+ triple: 12
+ Content: 'x86_64-apple-macos27.0.0'
- cmd: LC_SOURCE_VERSION
cmdsize: 16
version: 0
@@ -181,8 +185,8 @@ Slices:
cputype: 0x100000C
cpusubtype: 0x80000002
filetype: 0x6
- ncmds: 14
- sizeofcmds: 664
+ ncmds: 15
+ sizeofcmds: 704
flags: 0x100085
reserved: 0x0
LoadCommands:
@@ -200,9 +204,9 @@ Slices:
Sections:
- sectname: __text
segname: __TEXT
- addr: 0x2D8
+ addr: 0x300
size: 8
- offset: 0x2D8
+ offset: 0x300
align: 2
reloff: 0x0
nreloc: 0
@@ -213,9 +217,9 @@ Slices:
content: 00008052C0035FD6
- sectname: __unwind_info
segname: __TEXT
- addr: 0x2E0
+ addr: 0x308
size: 88
- offset: 0x2E0
+ offset: 0x308
align: 2
reloff: 0x0
nreloc: 0
@@ -290,6 +294,10 @@ Slices:
Tools:
- tool: 3
version: 76481792
+ - cmd: LC_TARGET_TRIPLE
+ cmdsize: 40
+ triple: 12
+ Content: 'arm64e-apple-macos27.0.0'
- cmd: LC_SOURCE_VERSION
cmdsize: 16
version: 0
diff --git a/llvm/test/MC/MachO/target-triple-padding.s b/llvm/test/MC/MachO/target-triple-padding.s
new file mode 100644
index 0000000000000..d8828754f8d95
--- /dev/null
+++ b/llvm/test/MC/MachO/target-triple-padding.s
@@ -0,0 +1,27 @@
+// RUN: split-file %s %t
+
+// RUN: llvm-mc -triple arm64-ios-macabi %t/target-triple-always-has-nul.s -filetype=obj -o - \
+// RUN: | llvm-objdump --macho --private-headers - | FileCheck %t/target-triple-always-has-nul.s
+
+// RUN: llvm-mc -triple arm64-apple-driverkit %t/target-triple-no-extra-padding.s -filetype=obj -o - \
+// RUN: | llvm-objdump --macho --private-headers - | FileCheck %t/target-triple-no-extra-padding.s
+
+//--- target-triple-always-has-nul.s
+// Make sure a target triple that reaches an 8 byte boundary doesn't drop its NUL.
+// LC_TARGET_TRIPLE is 3 32-bit integers (12 bytes) plus the target triple string.
+// A target triple length of 28 hits the 8 byte boundary (12 + 28 = 40). However the
+// NUL byte on the end of the string is required, so it should pad out to 48 bytes.
+.target_triple "arm64-apple-ios27.0.0-macabi"
+
+// CHECK: cmd LC_TARGET_TRIPLE
+// CHECK-NEXT: cmdsize 48
+// CHECK-NEXT: triple arm64-apple-ios27.0.0-macabi
+
+//--- target-triple-no-extra-padding.s
+// A target triple length of 27 perfectly fits in an 8 byte boundary when including
+// the string's NUL byte. That should come out to 40 bytes with no extra padding.
+.target_triple "arm64-apple-driverkit27.0.0"
+
+// CHECK: cmd LC_TARGET_TRIPLE
+// CHECK-NEXT: cmdsize 40
+// CHECK-NEXT: triple arm64-apple-driverkit27.0.0
diff --git a/llvm/test/MC/MachO/target-triple.s b/llvm/test/MC/MachO/target-triple.s
new file mode 100644
index 0000000000000..e0db90f4bfcf0
--- /dev/null
+++ b/llvm/test/MC/MachO/target-triple.s
@@ -0,0 +1,47 @@
+// RUN: split-file %s %t
+
+// RUN: llvm-mc -triple arm64-apple-macos %t/target-triple.s | FileCheck %t/target-triple.s
+// RUN: llvm-mc -triple arm64-apple-macos %t/target-triple.s -filetype=obj -o %t.o
+// RUN: llvm-objdump --macho --private-headers %t.o | FileCheck %t/target-triple.s --check-prefix=OBJDUMP
+// RUN: llvm-readobj --macho-target-triple %t.o | FileCheck %t/target-triple.s --check-prefix=READOBJ
+
+// RUN: not llvm-mc -triple arm64-apple-macos %t/non-darwin-target-triple.s 2>&1 | FileCheck %t/non-darwin-target-triple.s
+
+//--- target-triple.s
+.target_triple "arm64-apple-macos27.0.0"
+.build_version macos, 27,0 sdk_version 27,0
+
+// CHECK: .target_triple "arm64-apple-macos27.0.0"
+// Verify that .target_triple prints a newline so the next statement prints on
+// the next line and doesn't run into the .target_triple directive
+// CHECK-NEXT: .build_version macos, 27, 0 sdk_version 27, 0
+
+
+// Make sure the command is included in the Mach header
+// Mach header
+// ... filetype ncmds sizeofcmds
+// ... OBJECT 5 320
+// (filetype isn't really important for this test, we just didn't want to
+// accidentally match a random 5.)
+// OBJDUMP: Mach header
+// OBJDUMP-NEXT: ncmds
+// OBJDUMP-NEXT: OBJECT
+// OBJDUMP-SAME: 5
+// OBJDUMP-SAME: 320
+
+// OBJDUMP: cmd LC_TARGET_TRIPLE
+// OBJDUMP-NEXT: cmdsize 40
+// OBJDUMP-NEXT: triple arm64-apple-macos27.0.0
+
+
+// READOBJ: TargetTriple {
+// READOBJ-NEXT: Cmd: LC_TARGET_TRIPLE
+// READOBJ-NEXT: Size: 40
+// READOBJ-NEXT: Triple: arm64-apple-macos27.0.0
+// READOBJ-NEXT: }
+
+//--- non-darwin-target-triple.s
+.target_triple "x86_64-unknown-linux-gnu"
+
+// .target_triple is a Darwin specific directive
+// CHECK: error: non-Darwin target triple
diff --git a/llvm/test/Object/Inputs/macho-invalid-target-triple-name_offset-toobig b/llvm/test/Object/Inputs/macho-invalid-target-triple-name_offset-toobig
new file mode 100644
index 0000000000000000000000000000000000000000..73a23b3c6e38f99868a63eadb45d6861bf471938
GIT binary patch
literal 40
fcmX^2>+L^w1_lOZAZCPO9v}?@mOu<*D*!P7lwJfe
literal 0
HcmV?d00001
diff --git a/llvm/test/Object/Inputs/macho-invalid-target-triple-name_offset-toosmall b/llvm/test/Object/Inputs/macho-invalid-target-triple-name_offset-toosmall
new file mode 100644
index 0000000000000000000000000000000000000000..13116b56e4e422689ef836a8cd3e63cc819e52ea
GIT binary patch
literal 44
kcmX^2>+L^w1_lOZAZCPO9v}?@mOv~3#2i4Jn3S9X0H|gKrvLx|
literal 0
HcmV?d00001
diff --git a/llvm/test/Object/Inputs/macho-invalid-target-triple-name_toobig b/llvm/test/Object/Inputs/macho-invalid-target-triple-name_toobig
new file mode 100644
index 0000000000000000000000000000000000000000..a39209cb88a4484bd18bfaefb2a49017a0c9fd78
GIT binary patch
literal 44
jcmX^2>+L^w1_lOZAZCPO9v}?@mOv~3#2|iRQgR9asD=fr
literal 0
HcmV?d00001
diff --git a/llvm/test/Object/Inputs/macho-invalid-target-triple-small b/llvm/test/Object/Inputs/macho-invalid-target-triple-small
new file mode 100644
index 0000000000000000000000000000000000000000..b2c9fbf4cb14bc052625aee5a8f62a1bd2de537c
GIT binary patch
literal 44
hcmX^2>+L^w1_lOZAZCPO4j>HzmOu<*3xha7005*a1RMYW
literal 0
HcmV?d00001
diff --git a/llvm/test/Object/macho-invalid.test b/llvm/test/Object/macho-invalid.test
index f149ace70d42d..9e2defb97e390 100644
--- a/llvm/test/Object/macho-invalid.test
+++ b/llvm/test/Object/macho-invalid.test
@@ -326,6 +326,18 @@ INVALID-RPATH-NAME_OFFSET-TOOBIG: macho-invalid-rpath-name_offset-toobig': trunc
RUN: not llvm-objdump --macho --private-headers %p/Inputs/macho-invalid-rpath-name_toobig 2>&1 | FileCheck --check-prefix=INVALID-RPATH-NAME_TOOBIG %s
INVALID-RPATH-NAME_TOOBIG: macho-invalid-rpath-name_toobig': truncated or malformed object (load command 0 LC_RPATH library name extends past the end of the load command)
+RUN: not llvm-objdump --macho --private-headers %p/Inputs/macho-invalid-target-triple-small 2>&1 | FileCheck --check-prefix=INVALID-TARGET-TRIPLE-SMALL %s
+INVALID-TARGET-TRIPLE-SMALL: macho-invalid-target-triple-small': truncated or malformed object (load command 0 LC_TARGET_TRIPLE cmdsize too small)
+
+RUN: not llvm-objdump --macho --private-headers %p/Inputs/macho-invalid-target-triple-name_offset-toosmall 2>&1 | FileCheck --check-prefix=INVALID-TARGET-TRIPLE-NAME_OFFSET-TOOSMALL %s
+INVALID-TARGET-TRIPLE-NAME_OFFSET-TOOSMALL: macho-invalid-target-triple-name_offset-toosmall': truncated or malformed object (load command 0 LC_TARGET_TRIPLE triple.offset field too small, not past the end of the target_triple_command struct)
+
+RUN: not llvm-objdump --macho --private-headers %p/Inputs/macho-invalid-target-triple-name_offset-toobig 2>&1 | FileCheck --check-prefix=INVALID-TARGET-TRIPLE-NAME_OFFSET-TOOBIG %s
+INVALID-TARGET-TRIPLE-NAME_OFFSET-TOOBIG: macho-invalid-target-triple-name_offset-toobig': truncated or malformed object (load command 0 LC_TARGET_TRIPLE triple.offset field extends past the end of the load command)
+
+RUN: not llvm-objdump --macho --private-headers %p/Inputs/macho-invalid-target-triple-name_toobig 2>&1 | FileCheck --check-prefix=INVALID-TARGET-TRIPLE-NAME_TOOBIG %s
+INVALID-TARGET-TRIPLE-NAME_TOOBIG: macho-invalid-target-triple-name_toobig': truncated or malformed object (load command 0 LC_TARGET_TRIPLE triple name extends past the end of the load command)
+
RUN: not llvm-objdump --macho --private-headers %p/Inputs/macho-invalid-source-bad-size 2>&1 | FileCheck --check-prefix=INVALID-SOURCE-BAD-SIZE %s
INVALID-SOURCE-BAD-SIZE: macho-invalid-source-bad-size': truncated or malformed object (LC_SOURCE_VERSION command 0 has incorrect cmdsize)
diff --git a/llvm/test/ObjectYAML/MachO/target_triple_command.yaml b/llvm/test/ObjectYAML/MachO/target_triple_command.yaml
new file mode 100644
index 0000000000000..ad935f6a1471f
--- /dev/null
+++ b/llvm/test/ObjectYAML/MachO/target_triple_command.yaml
@@ -0,0 +1,26 @@
+# RUN: yaml2obj %s | obj2yaml | FileCheck %s
+
+--- !mach-o
+FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x01000007
+ cpusubtype: 0x80000003
+ filetype: 0x00000002
+ ncmds: 1
+ sizeofcmds: 40
+ flags: 0x00218085
+ reserved: 0x00000000
+LoadCommands:
+ - cmd: LC_TARGET_TRIPLE
+ cmdsize: 40
+ triple: 12
+ Content: 'arm64-apple-macos27.0.0'
+...
+
+
+CHECK: LoadCommands:
+CHECK: - cmd: LC_TARGET_TRIPLE
+CHECK-NEXT: cmdsize: 40
+CHECK-NEXT: triple: 12
+CHECK-NEXT: Content: arm64-apple-macos27.0.0
+CHECK-NEXT: ZeroPadBytes: 5
diff --git a/llvm/test/tools/llvm-objdump/MachO/target-triple.yaml b/llvm/test/tools/llvm-objdump/MachO/target-triple.yaml
new file mode 100644
index 0000000000000..81721c7bb8501
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/MachO/target-triple.yaml
@@ -0,0 +1,54 @@
+# RUN: yaml2obj %s | llvm-objdump --macho --private-headers - | FileCheck %s
+# RUN: yaml2obj %s | llvm-otool -lv - | FileCheck %s
+# RUN: yaml2obj %s | llvm-otool -l - | FileCheck --check-prefix=SHORT %s
+
+--- !mach-o
+FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x01000007
+ cpusubtype: 0x00000003
+ filetype: 0x00000004
+ ncmds: 2
+ sizeofcmds: 200
+ flags: 0x00000000
+ reserved: 0
+LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __TEXT
+ vmaddr: 4294967296
+ vmsize: 8192
+ fileoff: 0
+ filesize: 3099
+ maxprot: 7
+ initprot: 5
+ nsects: 1
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x0000000100001160
+ size: 3099
+ offset: 0x00001160
+ align: 4
+ reloff: 0x00000000
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x00000000
+ reserved2: 0x00000000
+ reserved3: 0x00000000
+ - cmd: LC_TARGET_TRIPLE
+ cmdsize: 40
+ triple: 12
+ Content: arm64-apple-macos27.0.0
+...
+
+CHECK: Load command 1
+CHECK-NEXT: cmd LC_TARGET_TRIPLE
+CHECK-NEXT: cmdsize 40
+CHECK-NEXT: triple arm64-apple-macos27.0.0
+
+SHORT: Load command 1
+SHORT-NEXT: cmd LC_TARGET_TRIPLE
+SHORT-NEXT: cmdsize 40
+SHORT-NEXT: triple arm64-apple-macos27.0.0
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp
index 8b5a56b0db095..ac87ad928d990 100644
--- a/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/llvm/tools/llvm-objdump/MachODump.cpp
@@ -9337,6 +9337,22 @@ static void PrintBuildVersionLoadCommand(const MachOObjectFile *obj,
}
}
+static void PrintTargetTripleCommand(MachO::target_triple_command tt,
+ const char *Ptr) {
+ outs() << " cmd LC_TARGET_TRIPLE\n";
+ outs() << " cmdsize " << tt.cmdsize;
+ if (tt.cmdsize < sizeof(struct MachO::target_triple_command))
+ outs() << " Incorrect size\n";
+ else
+ outs() << "\n";
+ if (tt.triple < tt.cmdsize) {
+ const char *P = Ptr + tt.triple;
+ outs() << " triple " << P << " (offset " << tt.triple << ")\n";
+ } else {
+ outs() << " triple ?(bad offset " << tt.triple << ")\n";
+ }
+}
+
static void PrintSourceVersionCommand(MachO::source_version_command sd) {
outs() << " cmd LC_SOURCE_VERSION\n";
outs() << " cmdsize " << sd.cmdsize;
@@ -10313,6 +10329,10 @@ static void PrintLoadCommands(const MachOObjectFile *Obj, uint32_t filetype,
MachO::build_version_command Bv =
Obj->getBuildVersionLoadCommand(Command);
PrintBuildVersionLoadCommand(Obj, Bv, verbose);
+ } else if (Command.C.cmd == MachO::LC_TARGET_TRIPLE) {
+ MachO::target_triple_command Tt =
+ Obj->getTargetTripleLoadCommand(Command);
+ PrintTargetTripleCommand(Tt, Command.Ptr);
} else if (Command.C.cmd == MachO::LC_SOURCE_VERSION) {
MachO::source_version_command Sd = Obj->getSourceVersionCommand(Command);
PrintSourceVersionCommand(Sd);
diff --git a/llvm/tools/llvm-readobj/MachODumper.cpp b/llvm/tools/llvm-readobj/MachODumper.cpp
index f5b3cf203204f..592a936e4a21b 100644
--- a/llvm/tools/llvm-readobj/MachODumper.cpp
+++ b/llvm/tools/llvm-readobj/MachODumper.cpp
@@ -47,6 +47,7 @@ class MachODumper : public ObjDumper {
// MachO-specific.
void printMachODataInCode() override;
void printMachOVersionMin() override;
+ void printMachOTargetTriple() override;
void printMachODysymtab() override;
void printMachOSegment() override;
void printMachOIndirectSymbols() override;
@@ -928,6 +929,22 @@ void MachODumper::printMachOVersionMin() {
}
}
+void MachODumper::printMachOTargetTriple() {
+ for (const auto &Load : Obj->load_commands()) {
+ if (Load.C.cmd == MachO::LC_TARGET_TRIPLE) {
+ DictScope Group(W, "TargetTriple");
+ MachO::target_triple_command TTC = Obj->getTargetTripleLoadCommand(Load);
+ W.printString("Cmd", "LC_TARGET_TRIPLE");
+ W.printNumber("Size", TTC.cmdsize);
+ if (TTC.triple < TTC.cmdsize) {
+ W.printString("Triple", Load.Ptr + TTC.triple);
+ } else {
+ W.printNumber("Triple ?(bad offset)", TTC.triple);
+ }
+ }
+ }
+}
+
void MachODumper::printMachODysymtab() {
for (const auto &Load : Obj->load_commands()) {
if (Load.C.cmd == MachO::LC_DYSYMTAB) {
diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h
index 3943f3efa3d0a..3942e5b5630b7 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/llvm/tools/llvm-readobj/ObjDumper.h
@@ -172,6 +172,7 @@ class ObjDumper {
// Only implemented for MachO.
virtual void printMachODataInCode() { }
virtual void printMachOVersionMin() { }
+ virtual void printMachOTargetTriple() {}
virtual void printMachODysymtab() { }
virtual void printMachOSegment() { }
virtual void printMachOIndirectSymbols() { }
diff --git a/llvm/tools/llvm-readobj/Opts.td b/llvm/tools/llvm-readobj/Opts.td
index 7aafdb03973e8..72ad85550412d 100644
--- a/llvm/tools/llvm-readobj/Opts.td
+++ b/llvm/tools/llvm-readobj/Opts.td
@@ -77,6 +77,7 @@ def macho_indirect_symbols : FF<"macho-indirect-symbols", "Display indirect symb
def macho_linker_options : FF<"macho-linker-options", "Display linker options">, Group<grp_mach_o>;
def macho_segment : FF<"macho-segment", "Display Segment command">, Group<grp_mach_o>;
def macho_version_min : FF<"macho-version-min", "Display version min command">, Group<grp_mach_o>;
+def macho_target_triple : FF<"macho-target-triple", "Display target triple command">, Group<grp_mach_o>;
// PE/COFF specific options.
def grp_coff : OptionGroup<"kind">, HelpText<"OPTIONS (PE/COFF specific)">;
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index 146855b78c4fc..d06221fbfd5b8 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -150,6 +150,7 @@ static bool MachOIndirectSymbols;
static bool MachOLinkerOptions;
static bool MachOSegment;
static bool MachOVersionMin;
+static bool MachOTargetTriple;
// PE/COFF specific options.
static bool CodeView;
@@ -305,6 +306,7 @@ static void parseOptions(const opt::InputArgList &Args) {
opts::MachOLinkerOptions = Args.hasArg(OPT_macho_linker_options);
opts::MachOSegment = Args.hasArg(OPT_macho_segment);
opts::MachOVersionMin = Args.hasArg(OPT_macho_version_min);
+ opts::MachOTargetTriple = Args.hasArg(OPT_macho_target_triple);
// PE/COFF specific options.
opts::CodeView = Args.hasArg(OPT_codeview);
@@ -537,6 +539,8 @@ static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer,
Dumper->printMachOSegment();
if (opts::MachOVersionMin)
Dumper->printMachOVersionMin();
+ if (opts::MachOTargetTriple)
+ Dumper->printMachOTargetTriple();
if (opts::MachODysymtab)
Dumper->printMachODysymtab();
if (opts::CGProfile)
diff --git a/llvm/tools/obj2yaml/macho2yaml.cpp b/llvm/tools/obj2yaml/macho2yaml.cpp
index f78ec8f3c265a..c3802aac43711 100644
--- a/llvm/tools/obj2yaml/macho2yaml.cpp
+++ b/llvm/tools/obj2yaml/macho2yaml.cpp
@@ -287,6 +287,15 @@ MachODumper::processLoadCommandData<MachO::build_version_command>(
return Start + NTools * sizeof(MachO::build_tool_version);
}
+template <>
+Expected<const char *>
+MachODumper::processLoadCommandData<MachO::target_triple_command>(
+ MachOYAML::LoadCommand &LC,
+ const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd,
+ MachOYAML::Object &Y) {
+ return readString<MachO::target_triple_command>(LC, LoadCmd);
+}
+
Expected<std::unique_ptr<MachOYAML::Object>> MachODumper::dump() {
auto Y = std::make_unique<MachOYAML::Object>();
Y->IsLittleEndian = Obj.isLittleEndian();
More information about the llvm-commits
mailing list