Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
rui314 committed Jan 3, 2025
1 parent d884620 commit 88d5e74
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 50 deletions.
2 changes: 1 addition & 1 deletion src/arch-arm32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,7 @@ std::vector<u8> Arm32ExidxSection::get_contents(Context<E> &ctx) {
std::vector<u8> buf(output_section.shdr.sh_size);

output_section.shdr.sh_addr = this->shdr.sh_addr;
output_section.write_to(ctx, buf.data(), nullptr);
output_section.write_to(ctx, buf.data());

// .ARM.exidx records consists of a signed 31-bit relative address
// and a 32-bit value. The relative address indicates the start
Expand Down
11 changes: 6 additions & 5 deletions src/mold.h
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ class __attribute__((aligned(4))) Chunk {
virtual i64 get_reldyn_size(Context<E> &ctx) const { return 0; }
virtual void construct_relr(Context<E> &ctx) {}
virtual void copy_buf(Context<E> &ctx) {}
virtual void write_to(Context<E> &ctx, u8 *buf, ElfRel<E> *rel) { unreachable(); }
virtual void write_to(Context<E> &ctx, u8 *buf) { unreachable(); }
virtual void update_shdr(Context<E> &ctx) {}

std::string_view name;
Expand Down Expand Up @@ -539,7 +539,7 @@ class OutputSection : public Chunk<E> {
i64 get_reldyn_size(Context<E> &ctx) const override;
void construct_relr(Context<E> &ctx) override;
void copy_buf(Context<E> &ctx) override;
void write_to(Context<E> &ctx, u8 *buf, ElfRel<E> *rel) override;
void write_to(Context<E> &ctx, u8 *buf) override;

void compute_symtab_size(Context<E> &ctx) override;
void populate_symtab(Context<E> &ctx) override;
Expand Down Expand Up @@ -873,7 +873,7 @@ class MergedSection : public Chunk<E> {
void resolve(Context<E> &ctx);
void compute_section_size(Context<E> &ctx) override;
void copy_buf(Context<E> &ctx) override;
void write_to(Context<E> &ctx, u8 *buf, ElfRel<E> *rel) override;
void write_to(Context<E> &ctx, u8 *buf) override;
void print_stats(Context<E> &ctx);

std::vector<MergeableSection<E> *> members;
Expand Down Expand Up @@ -2955,8 +2955,9 @@ Symbol<E>::get_thunk_addr(Context<E> &ctx, u64 P) const requires needs_thunk<E>
std::span<u64> vec = ctx.symbol_aux[aux_idx].thunk_addrs;
u64 lo = (P < branch_distance<E>) ? 0 : P - branch_distance<E>;
u64 val = *std::lower_bound(vec.begin(), vec.end(), lo);
assert(-branch_distance<E> <= (i64)(val - P) &&
(i64)(val - P) < branch_distance<E>);
i64 disp = val - P;
if (disp < -branch_distance<E> || branch_distance<E> <= disp)
Fatal(ctx) << "range extension thunk out of range: " << *this;
return val;
}

Expand Down
92 changes: 48 additions & 44 deletions src/output-chunks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -946,18 +946,56 @@ void OutputSection<E>::compute_section_size(Context<E> &ctx) {

template <typename E>
void OutputSection<E>::copy_buf(Context<E> &ctx) {
if (this->shdr.sh_type != SHT_NOBITS) {
ElfRel<E> *rel = nullptr;
if (ctx.reldyn)
rel = (ElfRel<E> *)(ctx.buf + ctx.reldyn->shdr.sh_offset +
this->reldyn_offset);
if (this->shdr.sh_type == SHT_NOBITS)
return;

// Copy section contents
u8 *buf = ctx.buf + this->shdr.sh_offset;
write_to(ctx, buf);

// Emit dynamic relocations
if (!ctx.reldyn)
return;

ElfRel<E> *rel = (ElfRel<E> *)(ctx.buf + ctx.reldyn->shdr.sh_offset +
this->reldyn_offset);

for (AbsRel<E> &r : abs_rels) {
Word<E> *loc = (Word<E> *)(buf + r.isec->offset + r.offset);
u64 addr = this->shdr.sh_addr + r.isec->offset + r.offset;
Symbol<E> &sym = *r.sym;

write_to(ctx, ctx.buf + this->shdr.sh_offset, rel);
switch (r.kind) {
case ABS_REL_NONE:
case ABS_REL_RELR:
*loc = sym.get_addr(ctx) + r.addend;
break;
case ABS_REL_BASEREL: {
u64 val = sym.get_addr(ctx) + r.addend;
*rel++ = ElfRel<E>(addr, E::R_RELATIVE, 0, val);
if (ctx.arg.apply_dynamic_relocs)
*loc = val;
break;
}
case ABS_REL_IFUNC:
if constexpr (supports_ifunc<E>) {
u64 val = sym.get_addr(ctx, NO_PLT) + r.addend;
*rel++ = ElfRel<E>(addr, E::R_IRELATIVE, 0, val);
if (ctx.arg.apply_dynamic_relocs)
*loc = val;
}
break;
case ABS_REL_DYNREL:
*rel++ = ElfRel<E>(addr, E::R_ABS, sym.get_dynsym_idx(ctx), r.addend);
if (ctx.arg.apply_dynamic_relocs)
*loc = r.addend;
break;
}
}
}

template <typename E>
void OutputSection<E>::write_to(Context<E> &ctx, u8 *buf, ElfRel<E> *rel) {
void OutputSection<E>::write_to(Context<E> &ctx, u8 *buf) {
// Copy section contents to an output file.
tbb::parallel_for((i64)0, (i64)members.size(), [&](i64 i) {
InputSection<E> &isec = *members[i];
Expand Down Expand Up @@ -990,40 +1028,6 @@ void OutputSection<E>::write_to(Context<E> &ctx, u8 *buf, ElfRel<E> *rel) {
thunk->copy_buf(ctx);
});
}

// Emit dynamic relocations.
for (AbsRel<E> &r : abs_rels) {
Word<E> *loc = (Word<E> *)(buf + r.isec->offset + r.offset);
u64 addr = this->shdr.sh_addr + r.isec->offset + r.offset;
Symbol<E> &sym = *r.sym;

switch (r.kind) {
case ABS_REL_NONE:
case ABS_REL_RELR:
*loc = sym.get_addr(ctx) + r.addend;
break;
case ABS_REL_BASEREL: {
u64 val = sym.get_addr(ctx) + r.addend;
*rel++ = ElfRel<E>(addr, E::R_RELATIVE, 0, val);
if (ctx.arg.apply_dynamic_relocs)
*loc = val;
break;
}
case ABS_REL_IFUNC:
if constexpr (supports_ifunc<E>) {
u64 val = sym.get_addr(ctx, NO_PLT) + r.addend;
*rel++ = ElfRel<E>(addr, E::R_IRELATIVE, 0, val);
if (ctx.arg.apply_dynamic_relocs)
*loc = val;
}
break;
case ABS_REL_DYNREL:
*rel++ = ElfRel<E>(addr, E::R_ABS, sym.get_dynsym_idx(ctx), r.addend);
if (ctx.arg.apply_dynamic_relocs)
*loc = r.addend;
break;
}
}
}

// .relr.dyn contains base relocations encoded in a space-efficient form.
Expand Down Expand Up @@ -2197,11 +2201,11 @@ void MergedSection<E>::compute_section_size(Context<E> &ctx) {

template <typename E>
void MergedSection<E>::copy_buf(Context<E> &ctx) {
write_to(ctx, ctx.buf + this->shdr.sh_offset, nullptr);
write_to(ctx, ctx.buf + this->shdr.sh_offset);
}

template <typename E>
void MergedSection<E>::write_to(Context<E> &ctx, u8 *buf, ElfRel<E> *rel) {
void MergedSection<E>::write_to(Context<E> &ctx, u8 *buf) {
i64 shard_size = map.nbuckets / map.NUM_SHARDS;

tbb::parallel_for((i64)0, map.NUM_SHARDS, [&](i64 i) {
Expand Down Expand Up @@ -2838,7 +2842,7 @@ CompressedSection<E>::CompressedSection(Context<E> &ctx, Chunk<E> &chunk) {
this->uncompressed_data.resize(chunk.shdr.sh_size);
u8 *buf = this->uncompressed_data.data();

chunk.write_to(ctx, buf, nullptr);
chunk.write_to(ctx, buf);

switch (ctx.arg.compress_debug_sections) {
case COMPRESS_ZLIB:
Expand Down

0 comments on commit 88d5e74

Please sign in to comment.