Skip to content

[lld][elf] Skip BP ordering input sections with null data #149265

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

Merged
merged 2 commits into from
Jul 18, 2025

Conversation

Colibrow
Copy link
Contributor

@Colibrow Colibrow commented Jul 17, 2025

LLD crashes when BP (Balanced Partitioning) ordering is applied to the .bss section, since .bss has a non-zero size but its data pointer is null.

This patch adds a null check for section data in ELF's BPSectionOrderer to avoid crash.

The fix is consistent with the Mach-O implementation in #137906.

@llvmbot
Copy link
Member

llvmbot commented Jul 17, 2025

@llvm/pr-subscribers-lld-elf

@llvm/pr-subscribers-lld

Author: Pengying Xu (Colibrow)

Changes

Same as #137906.


Full diff: https://github.com/llvm/llvm-project/pull/149265.diff

2 Files Affected:

  • (modified) lld/ELF/BPSectionOrderer.cpp (+2-2)
  • (modified) lld/test/ELF/bp-section-orderer.s (+15-6)
diff --git a/lld/ELF/BPSectionOrderer.cpp b/lld/ELF/BPSectionOrderer.cpp
index f464b1d4518a4..c471ab163708f 100644
--- a/lld/ELF/BPSectionOrderer.cpp
+++ b/lld/ELF/BPSectionOrderer.cpp
@@ -76,10 +76,10 @@ DenseMap<const InputSectionBase *, int> elf::runBalancedPartitioning(
     if (!d)
       return;
     auto *sec = dyn_cast_or_null<InputSection>(d->section);
-    // Skip empty, discarded, ICF folded sections. Skipping ICF folded sections
+    // Skip empty, discarded, ICF folded sections, .bss. Skipping ICF folded sections
     // reduces duplicate detection work in BPSectionOrderer.
     if (!sec || sec->size == 0 || !sec->isLive() || sec->repl != sec ||
-        !orderer.secToSym.try_emplace(sec, d).second)
+        !orderer.secToSym.try_emplace(sec, d).second || !sec->content().data())
       return;
     rootSymbolToSectionIdxs[CachedHashStringRef(
                                 lld::utils::getRootSymbol(sym.getName()))]
diff --git a/lld/test/ELF/bp-section-orderer.s b/lld/test/ELF/bp-section-orderer.s
index 4df2e8d43022e..438d7c2da0f76 100644
--- a/lld/test/ELF/bp-section-orderer.s
+++ b/lld/test/ELF/bp-section-orderer.s
@@ -26,28 +26,28 @@
 
 # RUN: ld.lld -o out.s a.o --irpgo-profile=a.profdata --bp-startup-sort=function
 # RUN: llvm-nm -jn out.s | tr '\n' , | FileCheck %s --check-prefix=STARTUP
-# STARTUP: s5,s4,s3,s2,s1,A,B,C,F,E,D,merged1,merged2,_start,d4,d3,d2,d1,{{$}}
+# STARTUP: s5,s4,s3,s2,s1,A,B,C,F,E,D,merged1,merged2,_start,d4,d3,d2,d1,g1,{{$}}
 
 # RUN: ld.lld -o out.os a.o --irpgo-profile=a.profdata --bp-startup-sort=function --symbol-ordering-file a.txt
 # RUN: llvm-nm -jn out.os | tr '\n' , | FileCheck %s --check-prefix=ORDER-STARTUP
-# ORDER-STARTUP: s2,s1,s5,s4,s3,A,F,E,D,B,C,merged1,merged2,_start,d3,d2,d4,d1,{{$}}
+# ORDER-STARTUP: s2,s1,s5,s4,s3,A,F,E,D,B,C,merged1,merged2,_start,d3,d2,d4,d1,g1,{{$}}
 
 # RUN: ld.lld -o out.cf a.o --verbose-bp-section-orderer --bp-compression-sort=function 2>&1 | FileCheck %s --check-prefix=BP-COMPRESSION-FUNC
 # RUN: ld.lld -o out.cf.icf a.o --verbose-bp-section-orderer --bp-compression-sort=function --icf=all --gc-sections 2>&1 | FileCheck %s --check-prefix=BP-COMPRESSION-ICF-FUNC
 # RUN: llvm-nm -jn out.cf | tr '\n' , | FileCheck %s --check-prefix=CFUNC
-# CFUNC: s5,s4,s3,s2,s1,A,F,merged1,merged2,C,E,D,B,_start,d4,d3,d2,d1,{{$}}
+# CFUNC: s5,s4,s3,s2,s1,A,F,merged1,merged2,C,E,D,B,_start,d4,d3,d2,d1,g1,{{$}}
 
 # RUN: ld.lld -o out.cd a.o --verbose-bp-section-orderer --bp-compression-sort=data 2>&1 | FileCheck %s --check-prefix=BP-COMPRESSION-DATA
 # RUN: llvm-nm -jn out.cd | tr '\n' , | FileCheck %s --check-prefix=CDATA
-# CDATA: s5,s3,s4,s2,s1,F,C,E,D,B,A,merged1,merged2,_start,d4,d1,d3,d2,{{$}}
+# CDATA: s5,s3,s4,s2,s1,F,C,E,D,B,A,merged1,merged2,_start,d4,d1,d3,d2,g1,{{$}}
 
 # RUN: ld.lld -o out.cb a.o --verbose-bp-section-orderer --bp-compression-sort=both 2>&1 | FileCheck %s --check-prefix=BP-COMPRESSION-BOTH
 # RUN: llvm-nm -jn out.cb | tr '\n' , | FileCheck %s --check-prefix=CBOTH
-# CBOTH: s5,s3,s4,s2,s1,A,F,merged1,merged2,C,E,D,B,_start,d4,d1,d3,d2,{{$}}
+# CBOTH: s5,s3,s4,s2,s1,A,F,merged1,merged2,C,E,D,B,_start,d4,d1,d3,d2,g1,{{$}}
 
 # RUN: ld.lld -o out.cbs a.o --verbose-bp-section-orderer --bp-compression-sort=both --irpgo-profile=a.profdata --bp-startup-sort=function 2>&1 | FileCheck %s --check-prefix=BP-COMPRESSION-BOTH
 # RUN: llvm-nm -jn out.cbs | tr '\n' , | FileCheck %s --check-prefix=CBOTH-STARTUP
-# CBOTH-STARTUP: s5,s3,s4,s2,s1,A,B,C,F,E,D,merged1,merged2,_start,d4,d1,d3,d2,{{$}}
+# CBOTH-STARTUP: s5,s3,s4,s2,s1,A,B,C,F,E,D,merged1,merged2,_start,d4,d1,d3,d2,g1,{{$}}
 
 # BP-COMPRESSION-FUNC: Ordered 9 sections ([[#]] bytes) using balanced partitioning
 # BP-COMPRESSION-ICF-FUNC: Ordered 8 sections ([[#]] bytes) using balanced partitioning
@@ -108,6 +108,7 @@ d3
 d2
 
 #--- a.c
+int g1;
 const char s5[] = "engineering";
 const char s4[] = "computer program";
 const char s3[] = "hardware engineer";
@@ -377,6 +378,14 @@ d1:
 	.word	6                               // 0x6
 	.size	d1, 16
 
+	.type	g1,@object                      // @g1
+	.section	.bss.g1,"aw",@nobits
+	.globl	g1
+	.p2align	2, 0x0
+g1:
+	.word	0                               // 0x0
+	.size	g1, 4
+
 	.section	".note.GNU-stack","",@progbits
 	.addrsig
 	.addrsig_sym F

Copy link

github-actions bot commented Jul 17, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@Colibrow Colibrow force-pushed the colibrow/fix-elf-bss-bp branch from e7afef3 to 4fba85b Compare July 17, 2025 07:01
@Colibrow
Copy link
Contributor Author

@ellishg @MaskRay Can you take a look at this PR?

if (!sec || sec->size == 0 || !sec->isLive() || sec->repl != sec ||
!orderer.secToSym.try_emplace(sec, d).second)
!orderer.secToSym.try_emplace(sec, d).second || !sec->content().data())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not move the check to before we add the section to secToSym?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. Fixed it.

@MaskRay
Copy link
Member

MaskRay commented Jul 17, 2025

Same as #137906.

The description is too brief. Does a .bss lead to a crash?

@Colibrow
Copy link
Contributor Author

@MaskRay Yes. I encountered a crash after updating lld to the latest version and enabling BP (Balanced Partitioning) ordering for the .data section in the ELF output.

The ld.lld command returned non-zero exit code: 139.
output:
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: ld.lld --export ...
1.	0x00000001025f7432 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (ld.lld+0x101934324)
2.	0x00000001025f4998 llvm::sys::RunSignalHandlers() (ld.lld+0x101932768)
3.	0x00000001025f4998 SignalHandler(int) (ld.lld+0x101932768)
4.	0x0000000193ecfe04 (/usr/lib/system/libsystem_platform.dylib+0x10842e04)
5.	0x0000000101ac1f1c llvm::SmallVectorBase::unsigned int, 12u>::base::grow_pod(void*, unsigned long, unsigned long) (ld.lld+0x100b6271c)
6.	0x0000000101e56f14 lld::elf::runBalancedPartitioning(lld::elf::PartitioningParams const&) (ld.lld+0x100eccc14)
7.	0x0000000101e58204 lld::elf::Ctx::Ctx() (ld.lld+0x100ecde14)
8.	0x0000000101e5d268 lld::elf::LinkerDriver::LinkerDriver() (ld.lld+0x100ed2c78)
9.	0x0000000101e5eb74 void lld::elf::writeResult<llvm::object::ELFType<llvm::endianness::little, true>>(lld::elf::Ctx&) (ld.lld+0x100ed4644)
10.	0x0000000101e5ed3c lld::elf::LinkerDriver::link(llvm::ArrayRef<char const*>) (ld.lld+0x100ed47f4)
11.	0x0000000101e5ef54 lld::elf::Link(llvm::ArrayRef<char const*>, bool, llvm::raw_ostream&, bool, bool) (ld.lld+0x100ed4a0c)
12.	0x0000000100003798 lld_main(int, char**, llvm::ToolContext const&) (ld.lld+0x100003798)
13.	0x0000000100003c98 main (ld.lld+0x100003c98)
14.	0x000000019fb0274b (/usr/lib/dyld+0x10004274b)

After investigation, I found that the crash occurs in BPSectionOrderer.cpp, where data.data() is nullptr, leading to a segmentation fault.

@Colibrow
Copy link
Contributor Author

@MaskRay I don't have commit access — could you please merge this PR on my behalf? Thank you!

@ellishg
Copy link
Contributor

ellishg commented Jul 18, 2025

I can land it tomorrow morning if it hasn't already (I like to wait until mornings to land changes to give myself time to revert or fix if needed).

@ellishg ellishg merged commit 6c705d1 into llvm:main Jul 18, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants