-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[lld-macho] Fix code section ordering in output binary #134010
Conversation
@llvm/pr-subscribers-lld-macho @llvm/pr-subscribers-lld Author: None (alx32) ChangesIn We also modify the Full diff: https://github.com/llvm/llvm-project/pull/134010.diff 2 Files Affected:
diff --git a/lld/MachO/OutputSegment.cpp b/lld/MachO/OutputSegment.cpp
index c320af3fb3177..185444673ae47 100644
--- a/lld/MachO/OutputSegment.cpp
+++ b/lld/MachO/OutputSegment.cpp
@@ -103,20 +103,32 @@ static int sectionOrder(OutputSection *osec) {
// be the section that determines whether we need thunks or not.
if (osec->name == section_names::text)
return -6;
+
+ // Prioritize specific section ordering based on our knowledge. This ensures
+ // that certain sections are placed in a particular order, even if they
+ // are also categorized as code sections. This explicit ordering takes
+ // precedence over the general code section ordering.
+ int knownPriority =
+ StringSwitch<int>(osec->name)
+ .Case(section_names::stubs, -4)
+ .Case(section_names::stubHelper, -3)
+ .Case(section_names::objcStubs, -2)
+ .Case(section_names::initOffsets, -1)
+ .Case(section_names::unwindInfo,
+ std::numeric_limits<int>::max() - 1)
+ .Case(section_names::ehFrame, std::numeric_limits<int>::max())
+ .Default(0);
+
+ if (knownPriority != 0)
+ return knownPriority;
+
// Ensure all code sections are contiguous with `__text` for thunk
// calculations.
- if (sections::isCodeSection(osec->name, segment_names::text, osec->flags) &&
- osec->name != section_names::stubHelper) {
+ if (sections::isCodeSection(osec->name, segment_names::text, osec->flags)) {
return -5;
}
- return StringSwitch<int>(osec->name)
- .Case(section_names::stubs, -4)
- .Case(section_names::stubHelper, -3)
- .Case(section_names::objcStubs, -2)
- .Case(section_names::initOffsets, -1)
- .Case(section_names::unwindInfo, std::numeric_limits<int>::max() - 1)
- .Case(section_names::ehFrame, std::numeric_limits<int>::max())
- .Default(osec->inputOrder);
+
+ return osec->inputOrder;
} else if (segname == segment_names::data ||
segname == segment_names::dataConst) {
// For each thread spawned, dyld will initialize its TLVs by copying the
diff --git a/lld/test/MachO/arm64-objc-stubs.s b/lld/test/MachO/arm64-objc-stubs.s
index 1b8ebff924300..da25b1292faa6 100644
--- a/lld/test/MachO/arm64-objc-stubs.s
+++ b/lld/test/MachO/arm64-objc-stubs.s
@@ -1,22 +1,23 @@
# 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
+# RUN: %lld -arch arm64 -lSystem -o %t.out %t.o -U _external_func
# RUN: llvm-otool -vs __TEXT __objc_stubs %t.out | FileCheck %s
-# RUN: %lld -arch arm64 -lSystem -o %t.out %t.o -dead_strip
+# 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
+# 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
+# RUN: %lld -arch arm64 -lSystem -o %t.out %t.o -objc_stubs_small -U _external_func
# 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: llvm-objdump --section-headers %t.out | FileCheck %s --check-prefix=SECTIONS
# CHECK: Contents of (__TEXT,__objc_stubs) section
# CHECK-NEXT: _objc_msgSend$foo:
# CHECK-NEXT: adrp x1, 8 ; 0x100008000
-# CHECK-NEXT: ldr x1, [x1, #0x10]
+# CHECK-NEXT: ldr x1, [x1, #0x18]
# CHECK-NEXT: adrp x16, 4 ; 0x100004000
# CHECK-NEXT: ldr x16, [x16]
# CHECK-NEXT: br x16
@@ -26,7 +27,7 @@
# CHECK-NEXT: _objc_msgSend$length:
# CHECK-NEXT: adrp x1, 8 ; 0x100008000
-# CHECK-NEXT: ldr x1, [x1, #0x18]
+# CHECK-NEXT: ldr x1, [x1, #0x20]
# CHECK-NEXT: adrp x16, 4 ; 0x100004000
# CHECK-NEXT: ldr x16, [x16]
# CHECK-NEXT: br x16
@@ -44,13 +45,13 @@
# FASTALIGN-NEXT: align 2^5 (32)
# SMALL: _objc_msgSend$foo:
-# SMALL-NEXT: adrp x1, 4 ; 0x100004000
-# SMALL-NEXT: ldr x1, [x1, #0x10]
+# SMALL-NEXT: adrp x1, 8 ; 0x100008000
+# SMALL-NEXT: ldr x1, [x1, #0x18]
# SMALL-NEXT: b
# SMALL-NEXT: _objc_msgSend$length:
-# SMALL-NEXT: adrp x1, 4 ; 0x100004000
-# SMALL-NEXT: ldr x1, [x1, #0x18]
+# SMALL-NEXT: adrp x1, 8 ; 0x100008000
+# SMALL-NEXT: ldr x1, [x1, #0x20]
# SMALL-NEXT: b
# SMALLALIGN: sectname __objc_stubs
@@ -60,6 +61,12 @@
# SMALLALIGN-NEXT: offset
# SMALLALIGN-NEXT: align 2^2 (4)
+## Check correct section ordering
+# SECTIONS: Sections:
+# SECTIONS: __text
+# SECTIONS: __stubs
+# SECTIONS: __objc_stubs
+
.section __TEXT,__objc_methname,cstring_literals
lselref1:
.asciz "foo"
@@ -81,4 +88,5 @@ _main:
bl _objc_msgSend$length
bl _objc_msgSend$foo
bl _objc_msgSend$foo
+ bl _external_func
ret
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
In
OutputSegment.cpp
, we need to ensure a specific order for certain sections. The current sorting logic incorrectly prioritizes code sections over explicitly defined section orders. This is problematic because the__objc_stubs
section is both a code section and has a specific ordering requirement. The current logic would incorrectly prioritize its code section status, causing it to be sorted before the__stubs
section. This incorrect ordering breaks the branch extension algorithm, ultimately leading to linker failures due to relocation errors.We also modify the
lld/test/MachO/arm64-objc-stubs.s
test to ensure correct section ordering.