[llvm] [llvm-otool] Add -a option to print archive headers (PR #189411)

Ryan Mansfield via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 15 06:38:22 PDT 2026


https://github.com/rjmansfield updated https://github.com/llvm/llvm-project/pull/189411

>From 8d847285e3ac8647d0c9ff384875f046a899ab0a Mon Sep 17 00:00:00 2001
From: Ryan Mansfield <ryan_mansfield at apple.com>
Date: Mon, 30 Mar 2026 11:29:59 -0400
Subject: [PATCH 1/3] [llvm-otool] Add -a option to print archive headers

---
 .../tools/llvm-objdump/MachO/archive-headers.test    | 12 ++++++++++++
 llvm/tools/llvm-objdump/MachODump.cpp                |  2 +-
 llvm/tools/llvm-objdump/OtoolOpts.td                 |  2 +-
 llvm/tools/llvm-objdump/llvm-objdump.cpp             |  1 +
 4 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/llvm/test/tools/llvm-objdump/MachO/archive-headers.test b/llvm/test/tools/llvm-objdump/MachO/archive-headers.test
index 946671a53dfdf..1a3631840510a 100644
--- a/llvm/test/tools/llvm-objdump/MachO/archive-headers.test
+++ b/llvm/test/tools/llvm-objdump/MachO/archive-headers.test
@@ -5,6 +5,18 @@ RUN: | FileCheck %s -check-prefix=OFFSETS
 RUN: llvm-objdump %p/Inputs/macho-universal-archive.x86_64.i386 --macho --archive-headers --arch all --non-verbose \
 RUN: | FileCheck %s -check-prefix=NON-VERBOSE
 
+# llvm-otool -a shows all architectures by default.
+RUN: llvm-otool -a %p/Inputs/macho-universal-archive.x86_64.i386 \
+RUN: | FileCheck %s -check-prefix=NON-VERBOSE
+
+# llvm-otool -a -arch filters to one slice.
+RUN: llvm-otool -a -arch x86_64 %p/Inputs/macho-universal-archive.x86_64.i386 \
+RUN: | FileCheck %s -check-prefix=OTOOL-ARCH
+OTOOL-ARCH:     Archive : {{.*}}macho-universal-archive.x86_64.i386
+OTOOL-ARCH:     0100644 124/11     44
+OTOOL-ARCH:     0100644 124/0     860
+OTOOL-ARCH-NOT: (architecture i386)
+
 # Note the date as printed by ctime(3) is time zone dependent and not checked.
 CHECK: Archive : {{.*}}/macho-universal-archive.x86_64.i386 (architecture x86_64)
 CHECK: -rw-r--r--124/11     44 {{.*}} __.SYMDEF SORTED
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp
index c59a0c8721dd0..0856f9e8a15ac 100644
--- a/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/llvm/tools/llvm-objdump/MachODump.cpp
@@ -2676,7 +2676,7 @@ void objdump::parseInputMachO(MachOUniversalBinary *UB) {
   }
   // No architecture flags were specified so if this contains a slice that
   // matches the host architecture dump only that.
-  if (!ArchAll) {
+  if (!ArchAll && !(IsOtool && ArchiveHeaders)) {
     for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
                                                 E = UB->end_objects();
           I != E; ++I) {
diff --git a/llvm/tools/llvm-objdump/OtoolOpts.td b/llvm/tools/llvm-objdump/OtoolOpts.td
index 706d9e0182f58..8cc70d3207245 100644
--- a/llvm/tools/llvm-objdump/OtoolOpts.td
+++ b/llvm/tools/llvm-objdump/OtoolOpts.td
@@ -4,6 +4,7 @@ def help : Flag<["--"], "help">, HelpText<"print help">;
 def help_hidden : Flag<["--"], "help-hidden">,
   HelpText<"print help for hidden flags">;
 
+def a : Flag<["-"], "a">, HelpText<"print archive header">;
 def arch : Separate<["-"], "arch">,
   HelpText<"select slice of universal Mach-O file">;
 def C : Flag<["-"], "C">, HelpText<"print linker optimization hints">;
@@ -43,7 +44,6 @@ def dyld_info : Flag<["-"], "dyld_info">,
   HelpText<"print bind and rebase information">;
 
 // Not (yet?) implemented:
-// def a : Flag<["-"], "a">, HelpText<"print archive header">;
 // -c print argument strings of a core file
 // -m don't use archive(member) syntax
 // -dyld_opcodes
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index ec2ecb58d6385..92421b82b3036 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -3661,6 +3661,7 @@ static void parseOtoolOptions(const llvm::opt::InputArgList &InputArgs) {
   ArchName = InputArgs.getLastArgValue(OTOOL_arch).str();
   if (!ArchName.empty())
     ArchFlags.push_back(ArchName);
+  ArchiveHeaders = InputArgs.hasArg(OTOOL_a);
   LinkOptHints = InputArgs.hasArg(OTOOL_C);
   if (InputArgs.hasArg(OTOOL_d))
     FilterSections.push_back("__DATA,__data");

>From b3cdd019c5439d76c66db17ff7a8e1fdd379c120 Mon Sep 17 00:00:00 2001
From: Ryan Mansfield <ryan_mansfield at apple.com>
Date: Tue, 14 Apr 2026 10:19:53 -0400
Subject: [PATCH 2/3] Add entry in llvm-otool.rst for -a option. Use
 --implicit-check-not instead of -NOT.

---
 llvm/docs/CommandGuide/llvm-otool.rst                   | 4 ++++
 llvm/test/tools/llvm-objdump/MachO/archive-headers.test | 9 ++++-----
 llvm/tools/llvm-objdump/MachODump.cpp                   | 3 ++-
 3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/llvm/docs/CommandGuide/llvm-otool.rst b/llvm/docs/CommandGuide/llvm-otool.rst
index 5a517a2c8ecee..ab92673092c9c 100644
--- a/llvm/docs/CommandGuide/llvm-otool.rst
+++ b/llvm/docs/CommandGuide/llvm-otool.rst
@@ -19,6 +19,10 @@ It attempts to be command-line-compatible and output-compatible with macOS's
 OPTIONS
 -------
 
+.. option:: -a
+
+ Print archive header.
+
 .. option:: -arch <value>
 
  Select slice of universal Mach-O file.
diff --git a/llvm/test/tools/llvm-objdump/MachO/archive-headers.test b/llvm/test/tools/llvm-objdump/MachO/archive-headers.test
index 1a3631840510a..b8a5d1ffa1b68 100644
--- a/llvm/test/tools/llvm-objdump/MachO/archive-headers.test
+++ b/llvm/test/tools/llvm-objdump/MachO/archive-headers.test
@@ -11,11 +11,10 @@ RUN: | FileCheck %s -check-prefix=NON-VERBOSE
 
 # llvm-otool -a -arch filters to one slice.
 RUN: llvm-otool -a -arch x86_64 %p/Inputs/macho-universal-archive.x86_64.i386 \
-RUN: | FileCheck %s -check-prefix=OTOOL-ARCH
-OTOOL-ARCH:     Archive : {{.*}}macho-universal-archive.x86_64.i386
-OTOOL-ARCH:     0100644 124/11     44
-OTOOL-ARCH:     0100644 124/0     860
-OTOOL-ARCH-NOT: (architecture i386)
+RUN: | FileCheck %s -check-prefix=OTOOL-ARCH --implicit-check-not="(architecture i386)"
+OTOOL-ARCH: Archive : {{.*}}macho-universal-archive.x86_64.i386
+OTOOL-ARCH: 0100644 124/11     44
+OTOOL-ARCH: 0100644 124/0     860
 
 # Note the date as printed by ctime(3) is time zone dependent and not checked.
 CHECK: Archive : {{.*}}/macho-universal-archive.x86_64.i386 (architecture x86_64)
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp
index 0856f9e8a15ac..25fbd4d60ecc3 100644
--- a/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/llvm/tools/llvm-objdump/MachODump.cpp
@@ -2675,7 +2675,8 @@ void objdump::parseInputMachO(MachOUniversalBinary *UB) {
     return;
   }
   // No architecture flags were specified so if this contains a slice that
-  // matches the host architecture dump only that.
+  // matches the host architecture dump only that. For otool -a dump all
+  // architectures to match classic otool behaviour.
   if (!ArchAll && !(IsOtool && ArchiveHeaders)) {
     for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
                                                 E = UB->end_objects();

>From f57f78b89fc1a46a0bfc921263a93a747d6241b8 Mon Sep 17 00:00:00 2001
From: Ryan Mansfield <ryan_mansfield at apple.com>
Date: Wed, 15 Apr 2026 08:38:27 -0400
Subject: [PATCH 3/3] Move OTOOL-ARCH checks to end of file and use -NEXT.

---
 llvm/test/tools/llvm-objdump/MachO/archive-headers.test | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/llvm/test/tools/llvm-objdump/MachO/archive-headers.test b/llvm/test/tools/llvm-objdump/MachO/archive-headers.test
index b8a5d1ffa1b68..d32ad7e9b637e 100644
--- a/llvm/test/tools/llvm-objdump/MachO/archive-headers.test
+++ b/llvm/test/tools/llvm-objdump/MachO/archive-headers.test
@@ -12,9 +12,6 @@ RUN: | FileCheck %s -check-prefix=NON-VERBOSE
 # llvm-otool -a -arch filters to one slice.
 RUN: llvm-otool -a -arch x86_64 %p/Inputs/macho-universal-archive.x86_64.i386 \
 RUN: | FileCheck %s -check-prefix=OTOOL-ARCH --implicit-check-not="(architecture i386)"
-OTOOL-ARCH: Archive : {{.*}}macho-universal-archive.x86_64.i386
-OTOOL-ARCH: 0100644 124/11     44
-OTOOL-ARCH: 0100644 124/0     860
 
 # Note the date as printed by ctime(3) is time zone dependent and not checked.
 CHECK: Archive : {{.*}}/macho-universal-archive.x86_64.i386 (architecture x86_64)
@@ -37,3 +34,7 @@ NON-VERBOSE: 0100644 124/0     860 1399501499 #1/12
 NON-VERBOSE: Archive : {{.*}}/macho-universal-archive.x86_64.i386 (architecture i386)
 NON-VERBOSE: 0100644 124/11     60 1399572709 #1/20
 NON-VERBOSE: 0100644 124/0     388 1399572697 #1/12
+
+OTOOL-ARCH:      Archive : {{.*}}macho-universal-archive.x86_64.i386
+OTOOL-ARCH-NEXT: 0100644 124/11     44
+OTOOL-ARCH-NEXT: 0100644 124/0     860



More information about the llvm-commits mailing list