Report branches to section offsets that need thunks

Assemblers emit a call to a static function as a relocation against a
section symbol plus an offset. A range extension thunk jumps to the
start of a symbol, so taking such a branch through a thunk landed at
the wrong address. Report it as an error instead.
This commit is contained in:
Rui Ueyama committed 2026-10-01 10:09:13 +09:00
1 parent 3717460027
commit 9b91621465
2 files changed
+45

No files matched your search

+19
View File
@@ -30,6 +30,7 @@ use crate::chunks::output_section::OutputSection;
use crate::chunks::{ChunkId, OutputSectionId};
use crate::context::Context;
use crate::elf::*;
use crate::error;
use crate::input_sections::{InputSection, InputSectionId};
use crate::symbol::{AddrFlags, Symbol, SymbolId};
use crate::target::{Family, Target};
@@ -454,6 +455,24 @@ pub fn remove_redundant_thunks<E: Target>(ctx: &mut Context<E>) {
continue;
}
let sym = &ctx.symbols[file.base.symbols[rel.r_sym() as usize]];
// A thunk jumps to the start of a symbol, so it can't serve a
// branch to an offset from a section symbol, which assemblers
// emit for calls to static functions.
if sym.ty() == STT_SECTION
&& isec.rel_addend(rel) != 0
&& requires_thunk(ctx, isec, rel, sym, false)
{
error!(
"{}: relocation {} against {} needs a range extension thunk, \
which can't jump to an offset from a section; recompile \
with -ffunction-sections",
isec.display(file),
rel.type_name::<E>(),
sym
);
}
if !sym.is_marked() && requires_thunk(ctx, isec, rel, sym, false) {
sym.mark();
}
+26
View File
@@ -0,0 +1,26 @@
#!/usr/bin/env bash
. $(dirname $0)/common.inc
# Assemblers emit calls to static functions as relocations against a
# section symbol plus an offset. A range extension thunk jumps to the
# start of a symbol, so such a call is an error if it needs a thunk.
cat <<EOF | $CC -c -o $t/a.o -xassembler -
.text
f1:
ret
f2:
ret
.section .far,"ax"
.globl _start
_start:
bl f1
bl f2
EOF
$CC -B. -nostdlib -static -o $t/exe1 $t/a.o
not $CC -B. -nostdlib -static -o $t/exe2 $t/a.o \
-Wl,--section-start=.text=0x10000000,--section-start=.far=0x20000000 >& $t/log
grep -F 'R_AARCH64_CALL26 against .text needs a range extension thunk' $t/log