1
1
mirror of https://github.com/rui314/mold.git synced 2024-12-27 10:23:41 +03:00
This commit is contained in:
Rui Ueyama 2021-04-03 21:15:57 +09:00
parent 9931deba39
commit 6cf7d9ea0a
2 changed files with 26 additions and 21 deletions

3
mold.h
View File

@ -643,8 +643,9 @@ public:
}
void construct(Context<E> &ctx);
void copy_buf(Context<E> &ctx) override;
u64 get_addr(Context<E> &ctx, const Symbol<E> &sym);
void apply_reloc(Context<E> &ctx, EhReloc<E> &rel, u64 loc, u64 val);
void copy_buf(Context<E> &ctx) override;
std::vector<CieRecord<E> *> cies;
u32 num_fdes = 0;

View File

@ -1188,6 +1188,28 @@ void EhFrameSection<E>::construct(Context<E> &ctx) {
ctx.eh_frame_hdr->HEADER_SIZE + num_fdes * 8;
}
template <typename E>
void EhFrameSection<E>::apply_reloc(Context<E> &ctx, EhReloc<E> &rel,
u64 loc, u64 val) {
u8 *base = ctx.buf + this->shdr.sh_offset;
switch (rel.type) {
case R_X86_64_32:
*(u32 *)(base + loc) = val;
return;
case R_X86_64_64:
*(u64 *)(base + loc) = val;
return;
case R_X86_64_PC32:
*(u32 *)(base + loc) = val - this->shdr.sh_addr - loc;
return;
case R_X86_64_PC64:
*(u64 *)(base + loc) = val - this->shdr.sh_addr - loc;
return;
}
unreachable(ctx);
}
template <typename E>
void EhFrameSection<E>::copy_buf(Context<E> &ctx) {
u8 *base = ctx.buf + this->shdr.sh_offset;
@ -1196,24 +1218,6 @@ void EhFrameSection<E>::copy_buf(Context<E> &ctx) {
if (ctx.eh_frame_hdr)
hdr_base = ctx.buf + ctx.eh_frame_hdr->shdr.sh_offset;
auto apply_reloc = [&](EhReloc<E> &rel, u64 loc, u64 val) {
switch (rel.type) {
case R_X86_64_32:
*(u32 *)(base + loc) = val;
return;
case R_X86_64_64:
*(u64 *)(base + loc) = val;
return;
case R_X86_64_PC32:
*(u32 *)(base + loc) = val - this->shdr.sh_addr - loc;
return;
case R_X86_64_PC64:
*(u64 *)(base + loc) = val - this->shdr.sh_addr - loc;
return;
}
unreachable(ctx);
};
struct Entry {
i32 init_addr;
i32 fde_addr;
@ -1236,7 +1240,7 @@ void EhFrameSection<E>::copy_buf(Context<E> &ctx) {
for (EhReloc<E> &rel : cie->rels) {
u64 loc = cie->offset + rel.offset;
u64 val = rel.sym.get_addr(ctx) + rel.addend;
apply_reloc(rel, loc, val);
apply_reloc(ctx, rel, loc, val);
}
}
@ -1253,7 +1257,7 @@ void EhFrameSection<E>::copy_buf(Context<E> &ctx) {
EhReloc<E> &rel = fde.rels[i];
u64 loc = fde_off + rel.offset;
u64 val = rel.sym.get_addr(ctx) + rel.addend;
apply_reloc(rel, loc, val);
apply_reloc(ctx, rel, loc, val);
// Write to .eh_frame_hdr
if (ctx.eh_frame_hdr && i == 0) {