[clang] cc38b29 - [llvm-readobj] Display Mach-O CPU capability bits (#221617)

via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 9 03:10:35 PDT 2026


Author: Tianyi Chen
Date: 2026-09-09T10:10:29Z
New Revision: cc38b29781cbc0a2b525a18833adf61c51375af2

URL: https://github.com/llvm/llvm-project/commit/cc38b29781cbc0a2b525a18833adf61c51375af2
DIFF: https://github.com/llvm/llvm-project/commit/cc38b29781cbc0a2b525a18833adf61c51375af2.diff

LOG: [llvm-readobj] Display Mach-O CPU capability bits (#221617)

The Mach-O file header output masks the capability bits out of
`cpusubtype`
without printing them separately, so this information is missing from
the
output.

Add a `CpuCapabilities` field to print the high byte in hexadecimal,
matching the numeric representation used by `llvm-objdump`.

Fixes #80198.

Assisted-by: OpenAI Codex (implementation, tests, and initial
description).

Added: 
    llvm/test/tools/llvm-readobj/MachO/cpu-capabilities.yaml

Modified: 
    clang/test/Misc/cc1as-darwin-target-variant-sdk-version.s
    clang/test/Misc/cc1as-darwin-target-variant-triple.s
    llvm/test/MC/MachO/diff-with-two-sections.s
    llvm/test/MC/MachO/weakdef.s
    llvm/test/MC/MachO/zero-space.s
    llvm/test/tools/llvm-readobj/MachO/file-headers-arm64.test
    llvm/test/tools/llvm-readobj/MachO/file-headers.test
    llvm/tools/llvm-readobj/MachODumper.cpp

Removed: 
    


################################################################################
diff  --git a/clang/test/Misc/cc1as-darwin-target-variant-sdk-version.s b/clang/test/Misc/cc1as-darwin-target-variant-sdk-version.s
index 6d22d6d395c98..45229aa0d5584 100644
--- a/clang/test/Misc/cc1as-darwin-target-variant-sdk-version.s
+++ b/clang/test/Misc/cc1as-darwin-target-variant-sdk-version.s
@@ -12,6 +12,7 @@
 // CHECK-NEXT:   Magic: Magic64 (0xFEEDFACF)
 // CHECK-NEXT:   CpuType: X86-64 (0x1000007)
 // CHECK-NEXT:   CpuSubType: CPU_SUBTYPE_X86_64_ALL (0x3)
+// CHECK-NEXT:   CpuCapabilities: 0x0
 // CHECK-NEXT:   FileType: Relocatable (0x1)
 // CHECK-NEXT:   NumOfLoadCommands: 3
 // CHECK-NEXT:   SizeOfLoadCommands: 192

diff  --git a/clang/test/Misc/cc1as-darwin-target-variant-triple.s b/clang/test/Misc/cc1as-darwin-target-variant-triple.s
index b30e5e52c1ef2..d4485f82df3bf 100644
--- a/clang/test/Misc/cc1as-darwin-target-variant-triple.s
+++ b/clang/test/Misc/cc1as-darwin-target-variant-triple.s
@@ -12,6 +12,7 @@
 // CHECK-NEXT:   Magic: Magic64 (0xFEEDFACF)
 // CHECK-NEXT:   CpuType: X86-64 (0x1000007)
 // CHECK-NEXT:   CpuSubType: CPU_SUBTYPE_X86_64_ALL (0x3)
+// CHECK-NEXT:   CpuCapabilities: 0x0
 // CHECK-NEXT:   FileType: Relocatable (0x1)
 // CHECK-NEXT:   NumOfLoadCommands: 3
 // CHECK-NEXT:   SizeOfLoadCommands: 192

diff  --git a/llvm/test/MC/MachO/
diff -with-two-sections.s b/llvm/test/MC/MachO/
diff -with-two-sections.s
index 87a8ad960e4c8..76005c64e71f9 100644
--- a/llvm/test/MC/MachO/
diff -with-two-sections.s
+++ b/llvm/test/MC/MachO/
diff -with-two-sections.s
@@ -15,6 +15,7 @@ Ltmp4 = Leh_func_begin0-Ltmp3
 // CHECK-NEXT:   Magic: Magic (0xFEEDFACE)
 // CHECK-NEXT:   CpuType: X86 (0x7)
 // CHECK-NEXT:   CpuSubType: CPU_SUBTYPE_I386_ALL (0x3)
+// CHECK-NEXT:   CpuCapabilities: 0x0
 // CHECK-NEXT:   FileType: Relocatable (0x1)
 // CHECK-NEXT:   NumOfLoadCommands: 2
 // CHECK-NEXT:   SizeOfLoadCommands: 208

diff  --git a/llvm/test/MC/MachO/weakdef.s b/llvm/test/MC/MachO/weakdef.s
index 200be41cd4c73..1f9fce3911f8f 100644
--- a/llvm/test/MC/MachO/weakdef.s
+++ b/llvm/test/MC/MachO/weakdef.s
@@ -22,6 +22,7 @@ __ZTI3optIbE:
 // CHECK-NEXT:   Magic: Magic (0xFEEDFACE)
 // CHECK-NEXT:   CpuType: X86 (0x7)
 // CHECK-NEXT:   CpuSubType: CPU_SUBTYPE_I386_ALL (0x3)
+// CHECK-NEXT:   CpuCapabilities: 0x0
 // CHECK-NEXT:   FileType: Relocatable (0x1)
 // CHECK-NEXT:   NumOfLoadCommands: 4
 // CHECK-NEXT:   SizeOfLoadCommands: 380

diff  --git a/llvm/test/MC/MachO/zero-space.s b/llvm/test/MC/MachO/zero-space.s
index 753bd7851bf0f..7acca8e2c53bf 100644
--- a/llvm/test/MC/MachO/zero-space.s
+++ b/llvm/test/MC/MachO/zero-space.s
@@ -14,6 +14,7 @@
 // CHECK-NEXT:   Magic: Magic64 (0xFEEDFACF)
 // CHECK-NEXT:   CpuType: X86-64 (0x1000007)
 // CHECK-NEXT:   CpuSubType: CPU_SUBTYPE_X86_64_ALL (0x3)
+// CHECK-NEXT:   CpuCapabilities: 0x0
 // CHECK-NEXT:   FileType: Relocatable (0x1)
 // CHECK-NEXT:   NumOfLoadCommands: 2
 // CHECK-NEXT:   SizeOfLoadCommands: 248

diff  --git a/llvm/test/tools/llvm-readobj/MachO/cpu-capabilities.yaml b/llvm/test/tools/llvm-readobj/MachO/cpu-capabilities.yaml
new file mode 100644
index 0000000000000..0b799d776ea94
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/MachO/cpu-capabilities.yaml
@@ -0,0 +1,61 @@
+## CPU capabilities occupy the high byte of cpusubtype. Display the whole byte
+## without changing the CPU subtype or interpreting architecture-specific bits.
+
+## ARM64e pointer authentication capability bits, including ABI version bits.
+# RUN: yaml2obj %s -DSUBTYPE=0x80000002 -o %t
+# RUN: llvm-readobj -h %t | FileCheck %s --check-prefix=ARM64E -DCAPS=0x80
+# RUN: yaml2obj %s -DSUBTYPE=0x81000002 -o %t
+# RUN: llvm-readobj -h %t | FileCheck %s --check-prefix=ARM64E -DCAPS=0x81
+# RUN: yaml2obj %s -DSUBTYPE=0xC1000002 -o %t
+# RUN: llvm-readobj -h %t | FileCheck %s --check-prefix=ARM64E -DCAPS=0xC1
+
+## Preserve all capability bits, even when their meaning is unknown.
+# RUN: yaml2obj %s -DSUBTYPE=0xFF000002 -o %t
+# RUN: llvm-readobj -h %t | FileCheck %s --check-prefix=ARM64E -DCAPS=0xFF
+# RUN: yaml2obj %s -DSUBTYPE=0x00000002 -o %t
+# RUN: llvm-readobj -h %t | FileCheck %s --check-prefix=ARM64E -DCAPS=0x0
+
+# ARM64E:      CpuSubType: CPU_SUBTYPE_ARM64E (0x2)
+# ARM64E-NEXT: CpuCapabilities: [[CAPS]]{{$}}
+# ARM64E-NEXT: FileType: Relocatable (0x1)
+
+## Also check 32-bit little-endian and 32/64-bit big-endian headers.
+# RUN: yaml2obj %s --docnum=2 -DCPUTYPE=0x7 -DSUBTYPE=0x80000003 -o %t
+# RUN: llvm-readobj -h %t | FileCheck %s --check-prefix=X86
+
+# X86:      CpuSubType: CPU_SUBTYPE_I386_ALL (0x3)
+# X86-NEXT: CpuCapabilities: 0x80{{$}}
+# X86-NEXT: FileType: Relocatable (0x1)
+
+# RUN: yaml2obj %s --docnum=2 -DENDIAN=false -DCPUTYPE=0x12 -DSUBTYPE=0xA5000000 -o %t
+# RUN: llvm-readobj -h %t | FileCheck %s --check-prefixes=PPC,PPC32
+# RUN: yaml2obj %s -DENDIAN=false -DCPUTYPE=0x1000012 -DSUBTYPE=0xA5000000 -o %t
+# RUN: llvm-readobj -h %t | FileCheck %s --check-prefixes=PPC,PPC64
+
+# PPC32:    CpuSubType: CPU_SUBTYPE_POWERPC_ALL (0x0)
+# PPC64:    CpuSubType: 0x0
+# PPC-NEXT: CpuCapabilities: 0xA5{{$}}
+# PPC-NEXT: FileType: Relocatable (0x1)
+
+--- !mach-o
+IsLittleEndian: [[ENDIAN=true]]
+FileHeader:
+  magic:      0xFEEDFACF
+  cputype:    [[CPUTYPE=0x100000C]]
+  cpusubtype: [[SUBTYPE]]
+  filetype:   0x1
+  ncmds:      0
+  sizeofcmds: 0
+  flags:      0
+  reserved:   0
+
+--- !mach-o
+IsLittleEndian: [[ENDIAN=true]]
+FileHeader:
+  magic:      0xFEEDFACE
+  cputype:    [[CPUTYPE]]
+  cpusubtype: [[SUBTYPE]]
+  filetype:   0x1
+  ncmds:      0
+  sizeofcmds: 0
+  flags:      0

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 910ee019f3293..5d97647b6654f 100644
--- a/llvm/test/tools/llvm-readobj/MachO/file-headers-arm64.test
+++ b/llvm/test/tools/llvm-readobj/MachO/file-headers-arm64.test
@@ -21,6 +21,7 @@
 # ARM64-NEXT:  Magic: Magic64 (0xFEEDFACF)
 # ARM64-NEXT:  CpuType: Arm64 (0x100000C)
 # ARM64-NEXT:  CpuSubType: [[SUBTYPE]]
+# ARM64-NEXT:  CpuCapabilities: 0x0
 # ARM64-NEXT:  FileType: Relocatable (0x1)
 # ARM64-NEXT:  NumOfLoadCommands: 0
 # ARM64-NEXT:  SizeOfLoadCommands: 0

diff  --git a/llvm/test/tools/llvm-readobj/MachO/file-headers.test b/llvm/test/tools/llvm-readobj/MachO/file-headers.test
index d3294f5727e11..0bf6cb6bc84ec 100644
--- a/llvm/test/tools/llvm-readobj/MachO/file-headers.test
+++ b/llvm/test/tools/llvm-readobj/MachO/file-headers.test
@@ -41,6 +41,7 @@ FileHeader:
 # MACHO32-NEXT:  Magic: Magic (0xFEEDFACE)
 # MACHO32-NEXT:  CpuType: [[CPUTYPE]]
 # MACHO32-NEXT:  CpuSubType: [[SUBTYPE]]
+# MACHO32-NEXT:  CpuCapabilities: 0x0
 # MACHO32-NEXT:  FileType: Relocatable (0x1)
 # MACHO32-NEXT:  NumOfLoadCommands: 0
 # MACHO32-NEXT:  SizeOfLoadCommands: 0
@@ -88,6 +89,7 @@ FileHeader:
 # MACHO64-NEXT:  Magic: Magic64 (0xFEEDFACF)
 # MACHO64-NEXT:  CpuType: [[CPUTYPE]]
 # MACHO64-NEXT:  CpuSubType: [[SUBTYPE]]
+# MACHO64-NEXT:  CpuCapabilities: 0x0
 # MACHO64-NEXT:  FileType: Relocatable (0x1)
 # MACHO64-NEXT:  NumOfLoadCommands: 0
 # MACHO64-NEXT:  SizeOfLoadCommands: 0

diff  --git a/llvm/tools/llvm-readobj/MachODumper.cpp b/llvm/tools/llvm-readobj/MachODumper.cpp
index a288fbc85058f..8fc92850606af 100644
--- a/llvm/tools/llvm-readobj/MachODumper.cpp
+++ b/llvm/tools/llvm-readobj/MachODumper.cpp
@@ -491,6 +491,8 @@ void MachODumper::printFileHeaders(const MachHeader &Header) {
   default:
     W.printHex("CpuSubType", subtype);
   }
+  W.printHex("CpuCapabilities",
+             (Header.cpusubtype & MachO::CPU_SUBTYPE_MASK) >> 24);
   W.printEnum("FileType", Header.filetype, EnumStrings(MachOHeaderFileTypes));
   W.printNumber("NumOfLoadCommands", Header.ncmds);
   W.printNumber("SizeOfLoadCommands", Header.sizeofcmds);


        


More information about the cfe-commits mailing list