Skip to content

Commit

Permalink
Reflect the result of code-shrinking relaxation to symbol sizes
Browse files Browse the repository at this point in the history
  • Loading branch information
rui314 committed Jan 5, 2025
1 parent ba35344 commit e6345d5
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/mold.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ struct InputSectionExtras<E> {
std::vector<RelocDelta> r_deltas;
};

static i64 get_removed_bytes(std::span<RelocDelta> deltas, i64 i) {
inline i64 get_removed_bytes(std::span<RelocDelta> deltas, i64 i) {
if (i == 0)
return deltas[i].delta;
return deltas[i].delta - deltas[i - 1].delta;
Expand Down
15 changes: 14 additions & 1 deletion src/output-chunks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1751,6 +1751,19 @@ void RelPltSection<E>::copy_buf(Context<E> &ctx) {
}
}

// RISC-V and LoongArch have code-shrinking linker relaxation. If we
// have removed instructions from a function, we need to update its
// size as well.
template <typename E>
static u64 get_symbol_size(Symbol<E> &sym) {
const ElfSym<E> &esym = sym.esym();
if constexpr (is_riscv<E> || is_loongarch<E>)
if (InputSection<E> *isec = sym.get_input_section())
if (!isec->extra.r_deltas.empty())
return esym.st_size - get_r_delta(*isec, esym.st_value + esym.st_size);
return esym.st_size;
}

template <typename E>
ElfSym<E> to_output_esym(Context<E> &ctx, Symbol<E> &sym, u32 st_name,
U32<E> *shn_xindex) {
Expand All @@ -1759,7 +1772,7 @@ ElfSym<E> to_output_esym(Context<E> &ctx, Symbol<E> &sym, u32 st_name,

esym.st_name = st_name;
esym.st_type = sym.get_type();
esym.st_size = sym.esym().st_size;
esym.st_size = get_symbol_size(sym);

if (sym.is_local(ctx))
esym.st_bind = STB_LOCAL;
Expand Down
28 changes: 28 additions & 0 deletions test/arch-riscv64-symbol-size.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/bash
. $(dirname $0)/common.inc

cat <<EOF | $CC -o $t/a.o -c -xassembler -
.globl get_foo
.type get_foo @function
get_foo:
lui a0, %hi(foo)
add a0, a0, %lo(foo)
ret
.size get_foo, .-get_foo
EOF

cat <<EOF | $CC -o $t/b.o -c -xassembler -
.globl foo, bar, baz
foo = 0xf00
EOF

cat <<EOF | $CC -o $t/c.o -c -xc -
#include <stdio.h>
int get_foo();
int main() { printf("%x\n", get_foo()); }
EOF

$CC -B. -o $t/exe $t/a.o $t/b.o $t/c.o

readelf --syms $t/a.o | grep -Eq ' 10 FUNC .* get_foo$'
readelf --syms $t/exe | grep -Eq ' 8 FUNC .* get_foo$'

0 comments on commit e6345d5

Please sign in to comment.