[lld] [lld][ELF] Merge .ltext.* input sections into .ltext output section (PR #190305)

Farid Zakaria via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 2 22:12:20 PDT 2026


https://github.com/fzakaria updated https://github.com/llvm/llvm-project/pull/190305

>From d49ef89f65375fd9d5c9e2e9c04acb399a0ee1bf Mon Sep 17 00:00:00 2001
From: Farid Zakaria <fmzakari at fb.com>
Date: Thu, 2 Apr 2026 22:11:45 -0700
Subject: [PATCH] [lld][ELF] Merge .ltext.* input sections into .ltext output
 section

The default output section name rules in getOutputSectionName() already
merge .ldata.*, .lrodata.*, and .lbss.* into their respective output
sections, but .ltext.* was missing. This caused mcmodel=large builds
with -ffunction-sections to produce a separate output section for every
function instead of combining them into .ltext.

Add .ltext handling mirroring .text, including -z keep-text-section-prefix
support so that .ltext.hot, .ltext.unlikely, etc. are preserved when
that flag is set.

Co-authored-by: Grigory Pastukhov <gpastukhov at meta.com>
---
 lld/ELF/LinkerScript.cpp             |  8 ++++++++
 lld/test/ELF/x86-64-section-layout.s | 27 ++++++++++++++++++++++++++-
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 76f04a27b9997..d76ee6b5aa55f 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -102,6 +102,14 @@ StringRef LinkerScript::getOutputSectionName(const InputSectionBase *s) const {
           return v;
     return ".text";
   }
+  if (isSectionPrefix(".ltext", s->name)) {
+    if (ctx.arg.zKeepTextSectionPrefix)
+      for (StringRef v : {".ltext.hot", ".ltext.unknown", ".ltext.unlikely",
+                          ".ltext.startup", ".ltext.exit", ".ltext.split"})
+        if (isSectionPrefix(v.substr(6), s->name.substr(6)))
+          return v;
+    return ".ltext";
+  }
 
   for (StringRef v : {".data.rel.ro", ".data",       ".rodata",
                       ".bss.rel.ro",  ".bss",        ".ldata",
diff --git a/lld/test/ELF/x86-64-section-layout.s b/lld/test/ELF/x86-64-section-layout.s
index 1432271b885a8..81cc16d566239 100644
--- a/lld/test/ELF/x86-64-section-layout.s
+++ b/lld/test/ELF/x86-64-section-layout.s
@@ -22,6 +22,10 @@
 # RUN: ld.lld c.o -o c
 # RUN: llvm-readelf -S -l c | FileCheck %s --check-prefix=CHECK4
 
+# RUN: llvm-mc -filetype=obj -triple=x86_64 d.s -o d.o
+# RUN: ld.lld d.o -z keep-text-section-prefix -o d
+# RUN: llvm-readelf -S d | FileCheck %s --check-prefix=CHECK5
+
 # CHECK:       Name              Type            Address          Off    Size   ES Flg Lk Inf Al
 # CHECK-NEXT:                    NULL            0000000000000000 000000 000000 00      0   0  0
 # CHECK-NEXT:  .note             NOTE            0000000000200300 000300 000001 00   A  0   0  1
@@ -132,6 +136,13 @@
 # CHECK4-NEXT: .ltext_w   PROGBITS
 # CHECK4-NEXT: .comment   PROGBITS
 
+## .ltext.hot and .ltext.unlikely are kept separate with -z keep-text-section-prefix.
+# CHECK5:      .ltext.hot      PROGBITS
+# CHECK5-NEXT: .ltext.unlikely PROGBITS
+# CHECK5-NEXT: .ltext          PROGBITS
+# CHECK5:      .text.hot       PROGBITS
+# CHECK5-NEXT: .text.unlikely  PROGBITS
+
 #--- a.s
 .globl _start, _etext, _edata, _end
 _start:
@@ -173,12 +184,17 @@ SECTIONS {
 }
 
 #--- c.s
-## Test .ltext layout
+## Test .ltext layout. .ltext.1 should be merged into .ltext.
 .section .ltext,"axl", at progbits
 .globl f
 f:
   ret
 
+.section .ltext.1,"axl", at progbits
+.globl f1
+f1:
+  ret
+
 .section .ltext_w,"awxl", at progbits
 .globl g
 g:
@@ -196,3 +212,12 @@ h:
 .section .lrodata,"al"; .space 1
 .section .ldata,"awl"; .space 1
 .section .lbss,"awl", at nobits; .space 1
+
+#--- d.s
+## Test -z keep-text-section-prefix with .ltext
+.section .ltext.hot.f1,"axl", at progbits; ret
+.section .ltext.unlikely.f2,"axl", at progbits; ret
+.section .ltext.f3,"axl", at progbits; ret
+.section .text.hot.f4,"ax", at progbits; ret
+.section .text.unlikely.f5,"ax", at progbits; ret
+.section .text.f6,"ax", at progbits; ret



More information about the llvm-commits mailing list