diff --git a/elf/mold.h b/elf/mold.h index 92de242920..3f826ac264 100644 --- a/elf/mold.h +++ b/elf/mold.h @@ -124,8 +124,10 @@ class Thunk { }; struct ThunkRef { - i16 thunk_idx = -1; - i16 sym_idx = -1; + static constexpr i64 MAX_SYM_IDX = (1 << 17) - 1; + + i32 thunk_idx : 14 = -1; + i32 sym_idx : 18 = -1; }; // diff --git a/elf/thunks.cc b/elf/thunks.cc index 79d1e52fbe..26b0d15cef 100644 --- a/elf/thunks.cc +++ b/elf/thunks.cc @@ -63,10 +63,10 @@ static consteval i64 max_distance() { // ARM64/ARM32/PPC, respectively. static constexpr i64 batch_size = max_distance() / 10; -// We assume that a single thunk group is smaller than 100 KiB. -static constexpr i64 max_thunk_size = 102400; +// We assume that a single thunk group is smaller than 900 KiB. +static constexpr i64 max_thunk_size = 900 * 1024; -static_assert(max_thunk_size / E::thunk_size < INT16_MAX); +static_assert(max_thunk_size / E::thunk_size < ThunkRef::MAX_SYM_IDX); template static bool is_reachable(Context &ctx, InputSection &isec, diff --git a/test/elf/range-extension-thunk3.sh b/test/elf/range-extension-thunk3.sh new file mode 100755 index 0000000000..bb45e594fe --- /dev/null +++ b/test/elf/range-extension-thunk3.sh @@ -0,0 +1,17 @@ +#!/bin/bash +. $(dirname $0)/common.inc + +[ $MACHINE = alpha ] && skip +[ $MACHINE = sh4 ] && skip + +seq 1 10000 | sed 's/.*/void func\0() {}/' > $t/a.c +$CC -B. -o $t/b.so -shared $t/a.c + +seq 1 10000 | sed 's/.*/void func\0();/' > $t/c.c +echo 'int main() {' >> $t/c.c +seq 1 10000 | sed 's/.*/func\0();/' >> $t/c.c +echo '}' >> $t/c.c + +$CC -c -o $t/d.o $t/c.c +$CC -B. -o $t/exe $t/d.o $t/b.so +$QEMU $t/exe