[llvm] [BOLT] Correctly handle entry point at FDE boundaries (PR #176173)
Elvina Yakubova via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 28 09:47:15 PST 2026
================
@@ -0,0 +1,97 @@
+## Test that BOLT correctly handles entry points at exact FDE boundaries.
+##
+## This test simulates a real-world scenario where:
+## 1. A large function (big_func) contains an FDE with no symbol
+## 2. The FDE covers a sub-function within big_func [fde_start, fde_end)
+## 3. Inlined code follows immediately after the FDE (no symbol, no FDE)
+## 4. .init branches to exactly the FDE end address via section relocation
+##
+## Without the fix, getOrCreateLocalLabel() would return getFunctionEndLabel()
+## when offset == FDE size. The fix ensures a proper entry point label is created.
+##
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o
+# RUN: %clang %cflags %t.o -pie -Wl,-q -Wl,--init=_init -o %t.exe
+# RUN: llvm-bolt %t.exe -o %t.bolt --print-disasm -v=1 2>&1 | FileCheck %s
+
+## The FDE-only function should get an entry point for the inlined code
+# CHECK: BOLT-WARNING: FDE {{.*}} has no corresponding symbol table entry
+# CHECK: Binary Function "{{.*}}__BOLT_FDE_FUNC{{.*}}" after disassembly
+# CHECK: Size : 0x1c
+# CHECK: MaxSize : 0x30
+# CHECK: IsMultiEntry: 1
+
+## _init function in .init section
+ .section .init,"ax", at progbits
+ .globl _init
+ .type _init, %function
+_init:
+ .cfi_startproc
+ stp x29, x30, [sp, #-16]!
+ mov x29, sp
+ ## Branch to inlined code that's right after FDE end
+ ## Linker converts this to: R_AARCH64_CALL26 .text + offset
+ bl .Linlined_code
+ ldp x29, x30, [sp], #16
+ ret
+ .cfi_endproc
+ .size _init, .-_init
+
+## Main code in .text section
+ .text
+
+## Large function that contains the FDE and inlined code
+ .globl big_func
+ .type big_func, %function
+big_func:
+ .cfi_startproc
+ stp x29, x30, [sp, #-16]!
+ mov x29, sp
+ mov w0, #1
+ add w0, w0, #1
+ ldp x29, x30, [sp], #16
+ ret
+ .cfi_endproc
+ .size big_func, .-big_func
+
+## FDE-covered code WITHOUT a symbol - simulates sub-function within big_func
+## This has its own FDE but no symbol in the symbol table
+.Lfde_start:
+ .cfi_startproc
+ stp x29, x30, [sp, #-16]!
+ mov x29, sp
+ adrp x0, .Lsome_data
+ add x0, x0, :lo12:.Lsome_data
+ ldr x0, [x0]
+ ldp x29, x30, [sp], #16
+ ret
+ .cfi_endproc
+## FDE ends here - inlined code follows immediately
+
+## Inlined code at exactly FDE end (offset == FDE size)
+## _init branches here - this is what triggers the bug without the fix
+.Linlined_code:
+ adrp x0, .Lsome_data
+ ldr x0, [x0, :lo12:.Lsome_data]
+ cbz x0, .Linlined_ret
+ mov w0, #1
+.Linlined_ret:
+ ret
----------------
ElvinaYakubova wrote:
Thanks Pascalis, you're right, we can remove that, I just tried to make the test closer to the original case, but that part is not essential.
https://github.com/llvm/llvm-project/pull/176173
More information about the llvm-commits
mailing list