Skip to content

Commit

Permalink
Relax a GOT load into a PC-relative address materialization
Browse files Browse the repository at this point in the history
  • Loading branch information
rui314 committed Sep 19, 2023
1 parent 9ee10ba commit a19783d
Showing 1 changed file with 25 additions and 0 deletions.
25 changes: 25 additions & 0 deletions elf/arch-riscv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,31 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
break;
}
case R_RISCV_GOT_HI20:
if (ctx.arg.relax &&
sym.is_pcrel_linktime_const(ctx) &&
i + 3 < rels.size() &&
rels[i + 1].r_type == R_RISCV_RELAX &&
rels[i + 2].r_type == R_RISCV_PCREL_LO12_I &&
rels[i + 2].r_offset == rels[i].r_offset + 4 &&
file.symbols[rels[i + 2].r_sym]->value == r_offset &&
rels[i + 3].r_type == R_RISCV_RELAX) {
// AUIPC + LD is used to load a value from a GOT slot. If the
// value is actually a PC-relative link-time constant, we can
// rewrite AUIPC + LD with AUIPC + ADDI to eliminate the memory
// load.
i64 val = S + A - P;
if ((i32)val == val) {
// auipc <rd>, %hi20(val)
write_utype(loc, val);

// addi <rd>, <rd>, %lo12(val)
i64 rd = get_rd(rel.r_offset);
*(ul32 *)(loc + 4) = 0b0010011 | (rd << 15) | (rd << 7);
write_itype(loc + 4, val);
i += 3;
break;
}
}
write_utype(loc, G + GOT + A - P);
break;
case R_RISCV_TLS_GOT_HI20:
Expand Down

0 comments on commit a19783d

Please sign in to comment.