[lld] f5f1fd6 - [lld-macho] Print Objective-C stubs in map files (#225302)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 22 22:40:20 PDT 2026
Author: Kyungwoo Lee
Date: 2026-09-23T05:40:13Z
New Revision: f5f1fd6fc00bdd2ace69100fc5c4a78839f53010
URL: https://github.com/llvm/llvm-project/commit/f5f1fd6fc00bdd2ace69100fc5c4a78839f53010
DIFF: https://github.com/llvm/llvm-project/commit/f5f1fd6fc00bdd2ace69100fc5c4a78839f53010.diff
LOG: [lld-macho] Print Objective-C stubs in map files (#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.
Added:
Modified:
lld/MachO/MapFile.cpp
lld/MachO/SyntheticSections.h
lld/test/MachO/arm64-objc-stubs-dead.s
lld/test/MachO/arm64-objc-stubs.s
lld/test/MachO/objc-stubs-order-file.s
lld/test/MachO/x86-64-objc-stubs.s
Removed:
################################################################################
diff --git a/lld/MachO/MapFile.cpp b/lld/MachO/MapFile.cpp
index 29ebcdcf9a832..8d65f39afe8f1 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] ", sym->getVA(), sym->size)
+ << sym->getName() << '\n';
+}
+
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 9acbd73d277e8..1b5c4e13f8fa9 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 5dcb171c17eac..2639db073d83a 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 da25b1292faa6..53cf3ebc119f8 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
diff --git a/lld/test/MachO/objc-stubs-order-file.s b/lld/test/MachO/objc-stubs-order-file.s
index 66fbaaaf4ea8a..6881bb44b282e 100644
--- a/lld/test/MachO/objc-stubs-order-file.s
+++ b/lld/test/MachO/objc-stubs-order-file.s
@@ -16,9 +16,10 @@
## _hot is ordered first, so the stub it calls moves ahead of the others, which
## keep their relative order.
# RUN: %lld -arch arm64 -e _main -U _objc_msgSend -o %t/ordered.out %t/a.o \
-# RUN: -objc_stubs_small -order_file %t/order
+# RUN: -objc_stubs_small -order_file %t/order -map %t/ordered.map
# RUN: llvm-objdump --no-show-raw-insn --section=__TEXT,__objc_stubs --macho \
# RUN: %t/ordered.out | FileCheck %s --check-prefix=ORDERED
+# RUN: FileCheck %s --check-prefix=MAP < %t/ordered.map
# RUN: %lld -arch arm64 -e _main -U _objc_msgSend -o %t/fast.out %t/a.o \
# RUN: -objc_stubs_fast -order_file %t/order
@@ -47,6 +48,12 @@
# ORDERED: _objc_msgSend$cold:
# ORDERED: _objc_msgSend$mild:
+# MAP: 0x[[#%.8X,OBJC_STUBS:]] 0x00000024 __TEXT __objc_stubs
+# MAP-LABEL: # Symbols:
+# MAP: 0x[[#OBJC_STUBS]] 0x0000000C [ 0] _objc_msgSend$hot
+# MAP-NEXT: 0x[[#OBJC_STUBS+0xC]] 0x0000000C [ 0] _objc_msgSend$cold
+# MAP-NEXT: 0x[[#OBJC_STUBS+0x18]] 0x0000000C [ 0] _objc_msgSend$mild
+
#--- a.s
.text
.globl _cold
diff --git a/lld/test/MachO/x86-64-objc-stubs.s b/lld/test/MachO/x86-64-objc-stubs.s
index a8bf5de9fe03d..49a1164247f1d 100644
--- a/lld/test/MachO/x86-64-objc-stubs.s
+++ b/lld/test/MachO/x86-64-objc-stubs.s
@@ -1,11 +1,12 @@
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
-# RUN: %lld -arch x86_64 -lSystem -o %t.out %t.o
+# RUN: %lld -arch x86_64 -lSystem -o %t.out %t.o -map %t.map
# RUN: llvm-objdump --macho --section-headers %t.out > %t.txt
# RUN: llvm-otool -vs __DATA __objc_selrefs %t.out >> %t.txt
# RUN: llvm-otool -vs __TEXT __objc_stubs %t.out >> %t.txt
# RUN: FileCheck %s < %t.txt
+# RUN: FileCheck %s --check-prefix=MAP < %t.map
# RUN: %no-fatal-warnings-lld -arch x86_64 -lSystem -o %t.out %t.o -objc_stubs_small 2>&1 | FileCheck %s --check-prefix=WARNING
# WARNING: warning: -objc_stubs_small is not yet implemented, defaulting to -objc_stubs_fast
@@ -49,6 +50,11 @@
# CHECK-EMPTY:
+# MAP: 0x[[#%.8X,OBJC_STUBS:]] 0x0000001A __TEXT __objc_stubs
+# MAP-LABEL: # Symbols:
+# MAP: 0x[[#OBJC_STUBS]] 0x0000000D [ 0] _objc_msgSend$foo
+# MAP-NEXT: 0x[[#OBJC_STUBS+0xD]] 0x0000000D [ 0] _objc_msgSend$length
+
.section __TEXT,__objc_methname,cstring_literals
lselref1:
.asciz "foo"
More information about the llvm-commits
mailing list