[llvm-branch-commits] [lld] [lldb] [llvm] release/23.x: [ld64.lld, llvm-otool, lldb] Minimal arm64e.x1 support (PR #224185)
Keith Smiley via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Sep 22 10:53:48 PDT 2026
https://github.com/keith updated https://github.com/llvm/llvm-project/pull/224185
>From b538ac985c311bc1fb7a3f37f3b5c47a121582e1 Mon Sep 17 00:00:00 2001
From: Nico Weber <thakis at chromium.org>
Date: Thu, 10 Sep 2026 20:21:11 -0400
Subject: [PATCH 1/3] [ld64.lld, llvm-otool] Minimal arm64e.x1 support
(#222721)
Just enough for `llvm-otool -hv` to dump the cpusubtype, and for
ld64.lld to not reject .tbd files that have an arm64e.x1 slice.
This is needed to link mac binaries against the macOS 27 SDK.
(cherry picked from commit b8007a8e4020b8bca2b12e941660e10bf5bf6716)
---
lld/test/MachO/arm64-x1.s | 20 +++++++++++++++++++
llvm/include/llvm/BinaryFormat/MachO.h | 1 +
llvm/include/llvm/TargetParser/Triple.h | 6 ++++++
llvm/include/llvm/TextAPI/Architecture.def | 2 +-
llvm/lib/BinaryFormat/MachO.cpp | 2 ++
llvm/lib/Object/MachOObjectFile.cpp | 6 ++++++
llvm/lib/TargetParser/Triple.cpp | 5 +++++
.../MachO/file-headers-arm64.test | 5 +++++
.../tools/llvm-readobj/macho-arm64e_x1.test | 17 ++++++++++++++++
llvm/tools/llvm-objdump/MachODump.cpp | 7 +++++++
llvm/tools/llvm-readobj/MachODumper.cpp | 1 +
llvm/unittests/BinaryFormat/MachOTest.cpp | 2 ++
12 files changed, 73 insertions(+), 1 deletion(-)
create mode 100644 lld/test/MachO/arm64-x1.s
create mode 100644 llvm/test/tools/llvm-readobj/macho-arm64e_x1.test
diff --git a/lld/test/MachO/arm64-x1.s b/lld/test/MachO/arm64-x1.s
new file mode 100644
index 00000000000000..67b7debc471327
--- /dev/null
+++ b/lld/test/MachO/arm64-x1.s
@@ -0,0 +1,20 @@
+# REQUIRES: aarch64
+
+## Test that arm64.x1-macos is ignored instead of causing an error.
+## linked re-exported dylibs that only declare arm64e-macos targets, even if targeting arm64.
+# arm64 and arm64e are ABI compatible (same CPU type), and ld64 accepts this.
+
+# RUN: rm -rf %t; split-file --no-leading-lines %s %t
+
+# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o %t/test.o /dev/null
+
+# RUN: %no-arg-lld -syslibroot %t/sdk -lSystem -dylib -arch arm64 \
+# RUN: -platform_version macos 15 26 %t/test.o -o /dev/null
+
+#--- sdk/usr/lib/libSystem.tbd
+--- !tapi-tbd
+tbd-version: 4
+targets: [ arm64-macos, arm64e.x1-macos ]
+install-name: '/usr/lib/libSystem.dylib'
+current-version: 0001.001.1
+...
diff --git a/llvm/include/llvm/BinaryFormat/MachO.h b/llvm/include/llvm/BinaryFormat/MachO.h
index bea1bcaf2bf752..ab06b6c3563481 100644
--- a/llvm/include/llvm/BinaryFormat/MachO.h
+++ b/llvm/include/llvm/BinaryFormat/MachO.h
@@ -1703,6 +1703,7 @@ enum CPUSubTypeARM64 : uint32_t {
CPU_SUBTYPE_ARM64_ALL = 0,
CPU_SUBTYPE_ARM64_V8 = 1,
CPU_SUBTYPE_ARM64E = 2,
+ CPU_SUBTYPE_ARM64E_X1 = 12,
// arm64e uses the capability bits to encode ptrauth ABI information.
// Bit 63 marks the binary as Versioned.
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index d819c4975b13e5..ebc65d0b6eac5e 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -156,6 +156,7 @@ class Triple {
ARMSubArch_v4t,
AArch64SubArch_arm64e,
+ AArch64SubArch_arm64e_x1,
AArch64SubArch_arm64ec,
AArch64SubArch_lfi,
@@ -1218,6 +1219,11 @@ class Triple {
getSubArch() == Triple::AArch64SubArch_arm64e;
}
+ bool isArm64e_x1() const {
+ return getArch() == Triple::aarch64 &&
+ getSubArch() == Triple::AArch64SubArch_arm64e_x1;
+ }
+
// Tests whether the target is N32.
bool isABIN32() const {
EnvironmentType Env = getEnvironment();
diff --git a/llvm/include/llvm/TextAPI/Architecture.def b/llvm/include/llvm/TextAPI/Architecture.def
index 0caf58e1825d99..33d549035ee657 100644
--- a/llvm/include/llvm/TextAPI/Architecture.def
+++ b/llvm/include/llvm/TextAPI/Architecture.def
@@ -39,7 +39,7 @@ ARCHINFO(armv8_1m_main, armv8.1m.main, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_A
///
ARCHINFO(arm64, arm64, MachO::CPU_TYPE_ARM64, MachO::CPU_SUBTYPE_ARM64_ALL, 64)
ARCHINFO(arm64e, arm64e, MachO::CPU_TYPE_ARM64, MachO::CPU_SUBTYPE_ARM64E, 64)
-
+ARCHINFO(arm64e_x1, arm64e.x1, MachO::CPU_TYPE_ARM64, MachO::CPU_SUBTYPE_ARM64E_X1, 64)
///
/// ARM64_32 architectures sorted by cpu sub type id
diff --git a/llvm/lib/BinaryFormat/MachO.cpp b/llvm/lib/BinaryFormat/MachO.cpp
index 046a79bbd7c5f6..923ae478f31d1e 100644
--- a/llvm/lib/BinaryFormat/MachO.cpp
+++ b/llvm/lib/BinaryFormat/MachO.cpp
@@ -66,6 +66,8 @@ static MachO::CPUSubTypeARM64 getARM64SubType(const Triple &T) {
return (MachO::CPUSubTypeARM64)MachO::CPU_SUBTYPE_ARM64_32_V8;
if (T.isArm64e())
return MachO::CPU_SUBTYPE_ARM64E;
+ if (T.isArm64e_x1())
+ return MachO::CPU_SUBTYPE_ARM64E_X1;
return MachO::CPU_SUBTYPE_ARM64_ALL;
}
diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp
index 3342c99e245cad..c28bcf1e3fb4c9 100644
--- a/llvm/lib/Object/MachOObjectFile.cpp
+++ b/llvm/lib/Object/MachOObjectFile.cpp
@@ -2874,6 +2874,12 @@ Triple MachOObjectFile::getArchTriple(uint32_t CPUType, uint32_t CPUSubType,
if (ArchFlag)
*ArchFlag = "arm64e";
return Triple("arm64e-apple-darwin");
+ case MachO::CPU_SUBTYPE_ARM64E_X1:
+ if (McpuDefault)
+ *McpuDefault = "apple-a20";
+ if (ArchFlag)
+ *ArchFlag = "arm64e.x1";
+ return Triple("arm64e.x1-apple-darwin");
default:
return Triple();
}
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index 356782c1f6ad49..2e4fe7ce70887e 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -192,6 +192,8 @@ StringRef Triple::getArchName(ArchType Kind, SubArchType SubArch) {
return "arm64ec";
if (SubArch == AArch64SubArch_arm64e)
return "arm64e";
+ if (SubArch == AArch64SubArch_arm64e_x1)
+ return "arm64e.x1";
if (SubArch == AArch64SubArch_lfi)
return "aarch64_lfi";
break;
@@ -656,6 +658,7 @@ Triple::ArchType Triple::parseArch(StringRef ArchName) {
.Case("arm64", Triple::aarch64)
.Case("arm64_32", Triple::aarch64_32)
.Case("arm64e", Triple::aarch64)
+ .Case("arm64e.x1", Triple::aarch64)
.Case("arm64ec", Triple::aarch64)
.Case("arm", Triple::arm)
.Case("armeb", Triple::armeb)
@@ -783,6 +786,8 @@ Triple::SubArchType Triple::parseSubArch(StringRef SubArchName) {
if (SubArchName == "arm64e")
return Triple::AArch64SubArch_arm64e;
+ if (SubArchName == "arm64e.x1")
+ return Triple::AArch64SubArch_arm64e_x1;
if (SubArchName == "arm64ec")
return Triple::AArch64SubArch_arm64ec;
diff --git a/llvm/test/tools/llvm-readobj/MachO/file-headers-arm64.test b/llvm/test/tools/llvm-readobj/MachO/file-headers-arm64.test
index 910ee019f3293b..4361ac938796a7 100644
--- a/llvm/test/tools/llvm-readobj/MachO/file-headers-arm64.test
+++ b/llvm/test/tools/llvm-readobj/MachO/file-headers-arm64.test
@@ -13,6 +13,11 @@
# RUN: llvm-readobj -h %t.arm64e \
# RUN: | FileCheck %s --strict-whitespace --match-full-lines -DFILE=%t.arm64e --check-prefix=ARM64 -DSUBTYPE="CPU_SUBTYPE_ARM64E (0x2)"
+## Check subtype Arm64E.X1:
+# RUN: yaml2obj %s -o %t.arm64e.x1 -DSUBTYPE=0xC
+# RUN: llvm-readobj -h %t.arm64e.x1 \
+# RUN: | FileCheck %s --strict-whitespace --match-full-lines -DFILE=%t.arm64e.x1 --check-prefix=ARM64 -DSUBTYPE="CPU_SUBTYPE_ARM64E_X1 (0xC)"
+
# ARM64:File: [[FILE]]
# ARM64-NEXT:Format: Mach-O arm64
# ARM64-NEXT:Arch: aarch64
diff --git a/llvm/test/tools/llvm-readobj/macho-arm64e_x1.test b/llvm/test/tools/llvm-readobj/macho-arm64e_x1.test
new file mode 100644
index 00000000000000..d6ea66911b7eb1
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/macho-arm64e_x1.test
@@ -0,0 +1,17 @@
+# RUN: yaml2obj %s -o %t.o
+# RUN: llvm-readobj -h %t.o | FileCheck %s
+
+# CHECK: Magic: Magic64 (0xFEEDFACF)
+# CHECK: CpuType: Arm64 (0x100000C)
+# CHECK: CpuSubType: CPU_SUBTYPE_ARM64E_X1 (0xC)
+
+--- !mach-o
+FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x0100000C
+ cpusubtype: 0x0000000C
+ filetype: 0x00000001
+ ncmds: 0
+ sizeofcmds: 0
+ flags: 0x00000000
+ reserved: 0x00000000
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp
index 8b5a56b0db0951..7a52df2aeeeaf9 100644
--- a/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/llvm/tools/llvm-objdump/MachODump.cpp
@@ -2344,6 +2344,10 @@ static void printCPUType(uint32_t cputype, uint32_t cpusubtype) {
outs() << " cputype CPU_TYPE_ARM64\n";
outs() << " cpusubtype CPU_SUBTYPE_ARM64E\n";
break;
+ case MachO::CPU_SUBTYPE_ARM64E_X1:
+ outs() << " cputype CPU_TYPE_ARM64\n";
+ outs() << " cpusubtype CPU_SUBTYPE_ARM64E_X1\n";
+ break;
default:
printUnknownCPUType(cputype, cpusubtype);
break;
@@ -8472,6 +8476,9 @@ static void PrintMachHeader(uint32_t magic, uint32_t cputype,
case MachO::CPU_SUBTYPE_ARM64E:
outs() << " E";
break;
+ case MachO::CPU_SUBTYPE_ARM64E_X1:
+ outs() << " E.X1";
+ break;
default:
outs() << format(" %10d", cpusubtype & ~MachO::CPU_SUBTYPE_MASK);
break;
diff --git a/llvm/tools/llvm-readobj/MachODumper.cpp b/llvm/tools/llvm-readobj/MachODumper.cpp
index f5b3cf203204ff..f768d3b704498a 100644
--- a/llvm/tools/llvm-readobj/MachODumper.cpp
+++ b/llvm/tools/llvm-readobj/MachODumper.cpp
@@ -189,6 +189,7 @@ constexpr EnumStringDef<uint32_t> MachOHeaderCpuSubtypesARM64Defs[] = {
LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM64_ALL),
LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM64_V8),
LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM64E),
+ LLVM_READOBJ_ENUM_ENT(MachO, CPU_SUBTYPE_ARM64E_X1),
};
constexpr auto MachOHeaderCpuSubtypesARM64 =
BUILD_ENUM_STRINGS(MachOHeaderCpuSubtypesARM64Defs);
diff --git a/llvm/unittests/BinaryFormat/MachOTest.cpp b/llvm/unittests/BinaryFormat/MachOTest.cpp
index 91558f78380165..01545da18454e9 100644
--- a/llvm/unittests/BinaryFormat/MachOTest.cpp
+++ b/llvm/unittests/BinaryFormat/MachOTest.cpp
@@ -66,6 +66,7 @@ TEST(MachOTest, CPUType) {
CHECK_CPUTYPE("thumbv7-apple-darwin", MachO::CPU_TYPE_ARM);
CHECK_CPUTYPE("arm64-apple-darwin", MachO::CPU_TYPE_ARM64);
CHECK_CPUTYPE("arm64e-apple-darwin", MachO::CPU_TYPE_ARM64);
+ CHECK_CPUTYPE("arm64e.x1-apple-darwin", MachO::CPU_TYPE_ARM64);
CHECK_CPUTYPE("arm64_32-apple-darwin", MachO::CPU_TYPE_ARM64_32);
{
@@ -107,6 +108,7 @@ TEST(MachOTest, CPUSubType) {
CHECK_CPUSUBTYPE("thumbv6-apple-darwin", MachO::CPU_SUBTYPE_ARM_V6);
CHECK_CPUSUBTYPE("arm64-apple-darwin", MachO::CPU_SUBTYPE_ARM64_ALL);
CHECK_CPUSUBTYPE("arm64e-apple-darwin", MachO::CPU_SUBTYPE_ARM64E);
+ CHECK_CPUSUBTYPE("arm64e.x1-apple-darwin", MachO::CPU_SUBTYPE_ARM64E_X1);
CHECK_CPUSUBTYPE("arm64_32-apple-darwin", MachO::CPU_SUBTYPE_ARM64_32_V8);
CHECK_CPUSUBTYPE("armv8m.main-apple-darwin", MachO::CPU_SUBTYPE_ARM_V8M_MAIN);
CHECK_CPUSUBTYPE("armv8m.base-apple-darwin", MachO::CPU_SUBTYPE_ARM_V8M_BASE);
>From bc261f330ca42491fe5aa89eb50463fc607659e6 Mon Sep 17 00:00:00 2001
From: Nico Weber <thakis at chromium.org>
Date: Fri, 11 Sep 2026 18:55:29 -0400
Subject: [PATCH 2/3] [lldb] Attempt to unbreak building lldb with the 27 SDK
(#223090)
See this report:
https://github.com/llvm/llvm-project/pull/222721#issuecomment-5636252813
(cherry picked from commit 923902483c7a6937a65b9679795a247ae2a2ad56)
---
lldb/include/lldb/Host/SafeMachO.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/lldb/include/lldb/Host/SafeMachO.h b/lldb/include/lldb/Host/SafeMachO.h
index cfb57571d0e3e3..4e9a42faf9656d 100644
--- a/lldb/include/lldb/Host/SafeMachO.h
+++ b/lldb/include/lldb/Host/SafeMachO.h
@@ -97,6 +97,7 @@
#undef CPU_SUBTYPE_ARM64E
#undef CPU_SUBTYPE_ARM64_32_V8
#undef CPU_SUBTYPE_ARM64_V8
+#undef CPU_SUBTYPE_ARM64E_X1
#undef CPU_SUBTYPE_ARM64_ALL
#undef CPU_SUBTYPE_SPARC_ALL
>From e91bf0082031a0416bfe9e90f411f3b6e94e362c Mon Sep 17 00:00:00 2001
From: Keith Smiley <keithbsmiley at gmail.com>
Date: Mon, 21 Sep 2026 10:44:34 -0700
Subject: [PATCH 3/3] Avoid abi break
---
llvm/include/llvm/TargetParser/Triple.h | 5 +++--
llvm/include/llvm/TextAPI/Architecture.h | 25 ++++++++++++++++++++----
2 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index ebc65d0b6eac5e..c5af232523c695 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -156,7 +156,6 @@ class Triple {
ARMSubArch_v4t,
AArch64SubArch_arm64e,
- AArch64SubArch_arm64e_x1,
AArch64SubArch_arm64ec,
AArch64SubArch_lfi,
@@ -274,7 +273,9 @@ class Triple {
AMDGPUSubArch13,
AMDGPUSubArch1310,
FirstAMDGPUSubArch = AMDGPUSubArch6,
- LastAMDGPUSubArch = AMDGPUSubArch1310
+ LastAMDGPUSubArch = AMDGPUSubArch1310,
+
+ AArch64SubArch_arm64e_x1
};
enum VendorType {
UnknownVendor,
diff --git a/llvm/include/llvm/TextAPI/Architecture.h b/llvm/include/llvm/TextAPI/Architecture.h
index 2ca199489f1d3e..8c1e182e2175ca 100644
--- a/llvm/include/llvm/TextAPI/Architecture.h
+++ b/llvm/include/llvm/TextAPI/Architecture.h
@@ -26,10 +26,27 @@ namespace MachO {
/// Defines the architecture slices that are supported by Text-based Stub files.
enum Architecture : uint8_t {
-#define ARCHINFO(Arch, Name, Type, SubType, NumBits) AK_##Arch,
-#include "llvm/TextAPI/Architecture.def"
-#undef ARCHINFO
- AK_unknown, // this has to go last.
+ AK_i386,
+ AK_x86_64,
+ AK_x86_64h,
+ AK_armv4t,
+ AK_armv6,
+ AK_armv5,
+ AK_armv7,
+ AK_armv7s,
+ AK_armv7k,
+ AK_armv6m,
+ AK_armv7m,
+ AK_armv7em,
+ AK_armv8m_main,
+ AK_armv8m_base,
+ AK_armv8_1m_main,
+ AK_arm64,
+ AK_arm64e,
+ AK_arm64_32,
+ AK_riscv32,
+ AK_unknown,
+ AK_arm64e_x1,
};
/// Convert a CPU Type and Subtype pair to an architecture slice.
More information about the llvm-branch-commits
mailing list