[lld] [lld-macho] Print Objective-C stubs in map files (PR #225302)
Kyungwoo Lee via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 21 22:35:03 PDT 2026
https://github.com/kyulee-com created https://github.com/llvm/llvm-project/pull/225302
Match ld-prime by listing synthesized Objective-C message-send stubs in Mach-O map files, including their final addresses and mode-specific sizes.
>From 7c894abcca958dc97768165d9f451921d2394ddb Mon Sep 17 00:00:00 2001
From: Kyungwoo Lee <kyulee at meta.com>
Date: Mon, 21 Sep 2026 20:51:10 -0700
Subject: [PATCH] [lld-macho] Print Objective-C stubs in map files
Match ld-prime by listing synthesized Objective-C message-send stubs in Mach-O map files, including their final addresses and mode-specific sizes.
---
lld/MachO/MapFile.cpp | 10 ++++++++++
lld/MachO/SyntheticSections.h | 1 +
lld/test/MachO/arm64-objc-stubs-dead.s | 20 ++++++++++++++------
lld/test/MachO/arm64-objc-stubs.s | 16 ++++++++++++++--
4 files changed, 39 insertions(+), 8 deletions(-)
diff --git a/lld/MachO/MapFile.cpp b/lld/MachO/MapFile.cpp
index 29ebcdcf9a832d..ab9f2d1daf53b0 100644
--- a/lld/MachO/MapFile.cpp
+++ b/lld/MachO/MapFile.cpp
@@ -141,6 +141,14 @@ static void printStubsEntries(
sym->getName().str().data());
}
+// For printing the contents of the __objc_stubs section.
+static void printObjCStubsEntries(raw_fd_ostream &os,
+ const ObjCStubsSection *osec) {
+ for (const Defined *sym : osec->getSymbols())
+ os << format("0x%08llX\t0x%08llX\t[ 0] %s\n", sym->getVA(), sym->size,
+ sym->getName().str().data());
+}
+
static void printNonLazyPointerSection(raw_fd_ostream &os,
NonLazyPointerSectionBase *osec) {
// ld64 considers stubs to belong to particular files, but considers GOT
@@ -257,6 +265,8 @@ void macho::writeMapFile() {
osec->addr, osec->getSize());
} else if (osec == in.stubs) {
printStubsEntries(os, readerToFileOrdinal, osec, target->stubSize);
+ } else if (osec == in.objcStubs) {
+ printObjCStubsEntries(os, in.objcStubs);
} else if (osec == in.lazyPointers) {
printStubsEntries(os, readerToFileOrdinal, osec, target->wordSize);
} else if (osec == in.stubHelper) {
diff --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h
index 9acbd73d277e81..1b5c4e13f8fa95 100644
--- a/lld/MachO/SyntheticSections.h
+++ b/lld/MachO/SyntheticSections.h
@@ -345,6 +345,7 @@ class ObjCStubsSection final : public SyntheticSection {
static constexpr llvm::StringLiteral symbolPrefix = "_objc_msgSend$";
static bool isObjCStubSymbol(Symbol *sym);
static StringRef getMethname(Symbol *sym);
+ ArrayRef<Defined *> getSymbols() const { return symbols; }
/// Stably sort the stubs by \p priorities and reassign their offsets. Must
/// run before addresses are assigned.
diff --git a/lld/test/MachO/arm64-objc-stubs-dead.s b/lld/test/MachO/arm64-objc-stubs-dead.s
index 5dcb171c17eac5..2639db073d83a6 100644
--- a/lld/test/MachO/arm64-objc-stubs-dead.s
+++ b/lld/test/MachO/arm64-objc-stubs-dead.s
@@ -4,24 +4,32 @@
# RUN: %lld -arch arm64 -lSystem -U _objc_msgSend -o %t.out %t.o
# RUN: llvm-nm %t.out | FileCheck %s
-# RUN: %lld -arch arm64 -lSystem -U _objc_msgSend -dead_strip -o %t.out %t.o
-# RUN: llvm-nm %t.out | FileCheck %s --check-prefix=DEAD
+# RUN: %lld -arch arm64 -lSystem -U _objc_msgSend -dead_strip -o %t.out %t.o -map %t.map
+# RUN: llvm-nm %t.out | FileCheck %s --check-prefix=DEAD \
+# RUN: --implicit-check-not=_foo --implicit-check-not='_objc_msgSend$deadsel'
+# RUN: FileCheck %s --check-prefix=DEAD-MAP \
+# RUN: --implicit-check-not='_objc_msgSend$deadsel' < %t.map
# CHECK: _foo
-# CHECK: _objc_msgSend$length
+# CHECK: _objc_msgSend$deadsel
+# CHECK: _objc_msgSend$livesel
-# DEAD-NOT: _foo
-# DEAD-NOT: _objc_msgSend$length
+# DEAD: _objc_msgSend$livesel
+
+# DEAD-MAP: 0x[[#%.8X,OBJC_STUBS:]] 0x00000020 __TEXT __objc_stubs
+# DEAD-MAP-LABEL: # Symbols:
+# DEAD-MAP: 0x[[#OBJC_STUBS]] 0x00000020 [ 0] _objc_msgSend$livesel
.section __TEXT,__text
.globl _foo
_foo:
- bl _objc_msgSend$length
+ bl _objc_msgSend$deadsel
ret
.globl _main
_main:
+ bl _objc_msgSend$livesel
ret
.subsections_via_symbols
diff --git a/lld/test/MachO/arm64-objc-stubs.s b/lld/test/MachO/arm64-objc-stubs.s
index da25b1292faa65..53cf3ebc119f86 100644
--- a/lld/test/MachO/arm64-objc-stubs.s
+++ b/lld/test/MachO/arm64-objc-stubs.s
@@ -1,16 +1,18 @@
# REQUIRES: aarch64
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %s -o %t.o
-# RUN: %lld -arch arm64 -lSystem -o %t.out %t.o -U _external_func
+# RUN: %lld -arch arm64 -lSystem -o %t.out %t.o -U _external_func -map %t.map
# RUN: llvm-otool -vs __TEXT __objc_stubs %t.out | FileCheck %s
+# RUN: FileCheck %s --check-prefix=MAP < %t.map
# RUN: %lld -arch arm64 -lSystem -o %t.out %t.o -dead_strip -U _external_func
# RUN: llvm-otool -vs __TEXT __objc_stubs %t.out | FileCheck %s
# RUN: %lld -arch arm64 -lSystem -o %t.out %t.o -objc_stubs_fast -U _external_func
# RUN: llvm-otool -vs __TEXT __objc_stubs %t.out | FileCheck %s
# RUN: llvm-otool -l %t.out | FileCheck %s --check-prefix=FASTALIGN
-# RUN: %lld -arch arm64 -lSystem -o %t.out %t.o -objc_stubs_small -U _external_func
+# RUN: %lld -arch arm64 -lSystem -o %t.out %t.o -objc_stubs_small -U _external_func -map %t.small.map
# RUN: llvm-otool -vs __TEXT __objc_stubs %t.out | FileCheck %s --check-prefix=SMALL
# RUN: llvm-otool -l %t.out | FileCheck %s --check-prefix=SMALLALIGN
+# RUN: FileCheck %s --check-prefix=SMALLMAP < %t.small.map
# RUN: llvm-objdump --section-headers %t.out | FileCheck %s --check-prefix=SECTIONS
# CHECK: Contents of (__TEXT,__objc_stubs) section
@@ -37,6 +39,16 @@
# CHECK-EMPTY:
+# MAP: 0x[[#%.8X,OBJC_STUBS:]] 0x00000040 __TEXT __objc_stubs
+# MAP: # Symbols:
+# MAP-DAG: 0x[[#OBJC_STUBS]] 0x00000020 [ 0] _objc_msgSend$foo
+# MAP-DAG: 0x[[#OBJC_STUBS+0x20]] 0x00000020 [ 0] _objc_msgSend$length
+
+# SMALLMAP: 0x[[#%.8X,OBJC_STUBS:]] 0x00000018 __TEXT __objc_stubs
+# SMALLMAP: # Symbols:
+# SMALLMAP-DAG: 0x[[#OBJC_STUBS]] 0x0000000C [ 0] _objc_msgSend$foo
+# SMALLMAP-DAG: 0x[[#OBJC_STUBS+0xC]] 0x0000000C [ 0] _objc_msgSend$length
+
# FASTALIGN: sectname __objc_stubs
# FASTALIGN-NEXT: segname __TEXT
# FASTALIGN-NEXT: addr
More information about the llvm-commits
mailing list