1
1
mirror of https://github.com/rui314/mold.git synced 2024-11-11 16:58:12 +03:00
This commit is contained in:
Rui Ueyama 2021-04-12 19:42:26 +09:00
parent fc45f0f3d2
commit 7b5e459b35
5 changed files with 33 additions and 25 deletions

View File

@ -134,9 +134,9 @@ static void write_val(Context<I386> &ctx, u64 r_type, u8 *loc, u64 val) {
template <> template <>
void InputSection<I386>::apply_reloc_alloc(Context<I386> &ctx, u8 *base) { void InputSection<I386>::apply_reloc_alloc(Context<I386> &ctx, u8 *base) {
i64 ref_idx = 0;
ElfRel<I386> *dynrel = nullptr; ElfRel<I386> *dynrel = nullptr;
std::span<ElfRel<I386>> rels = get_rels(ctx); std::span<ElfRel<I386>> rels = get_rels(ctx);
i64 frag_idx = 0;
if (ctx.reldyn) if (ctx.reldyn)
dynrel = (ElfRel<I386> *)(ctx.buf + ctx.reldyn->shdr.sh_offset + dynrel = (ElfRel<I386> *)(ctx.buf + ctx.reldyn->shdr.sh_offset +
@ -148,8 +148,8 @@ void InputSection<I386>::apply_reloc_alloc(Context<I386> &ctx, u8 *base) {
u8 *loc = base + rel.r_offset; u8 *loc = base + rel.r_offset;
const SectionFragmentRef<I386> *ref = nullptr; const SectionFragmentRef<I386> *ref = nullptr;
if (has_fragments[i]) if (frag_idx < rel_fragments.size() && rel_fragments[frag_idx].idx == i)
ref = &rel_fragments[ref_idx++]; ref = &rel_fragments[frag_idx++];
auto write = [&](u64 val) { auto write = [&](u64 val) {
write_val(ctx, rel.r_type, loc, val); write_val(ctx, rel.r_type, loc, val);
@ -214,7 +214,7 @@ void InputSection<I386>::apply_reloc_alloc(Context<I386> &ctx, u8 *base) {
template <> template <>
void InputSection<I386>::apply_reloc_nonalloc(Context<I386> &ctx, u8 *base) { void InputSection<I386>::apply_reloc_nonalloc(Context<I386> &ctx, u8 *base) {
std::span<ElfRel<I386>> rels = get_rels(ctx); std::span<ElfRel<I386>> rels = get_rels(ctx);
i64 ref_idx = 0; i64 frag_idx = 0;
for (i64 i = 0; i < rels.size(); i++) { for (i64 i = 0; i < rels.size(); i++) {
const ElfRel<I386> &rel = rels[i]; const ElfRel<I386> &rel = rels[i];
@ -227,8 +227,8 @@ void InputSection<I386>::apply_reloc_nonalloc(Context<I386> &ctx, u8 *base) {
} }
const SectionFragmentRef<I386> *ref = nullptr; const SectionFragmentRef<I386> *ref = nullptr;
if (has_fragments[i]) if (frag_idx < rel_fragments.size() && rel_fragments[frag_idx].idx == i)
ref = &rel_fragments[ref_idx++]; ref = &rel_fragments[frag_idx++];
auto write = [&](u64 val) { auto write = [&](u64 val) {
write_val(ctx, rel.r_type, loc, val); write_val(ctx, rel.r_type, loc, val);

View File

@ -242,9 +242,9 @@ static u32 relax_gottpoff(u8 *loc) {
// scan_relocations(). // scan_relocations().
template <> template <>
void InputSection<X86_64>::apply_reloc_alloc(Context<X86_64> &ctx, u8 *base) { void InputSection<X86_64>::apply_reloc_alloc(Context<X86_64> &ctx, u8 *base) {
i64 ref_idx = 0;
ElfRel<X86_64> *dynrel = nullptr; ElfRel<X86_64> *dynrel = nullptr;
std::span<ElfRel<X86_64>> rels = get_rels(ctx); std::span<ElfRel<X86_64>> rels = get_rels(ctx);
i64 frag_idx = 0;
if (ctx.reldyn) if (ctx.reldyn)
dynrel = (ElfRel<X86_64> *)(ctx.buf + ctx.reldyn->shdr.sh_offset + dynrel = (ElfRel<X86_64> *)(ctx.buf + ctx.reldyn->shdr.sh_offset +
@ -256,8 +256,8 @@ void InputSection<X86_64>::apply_reloc_alloc(Context<X86_64> &ctx, u8 *base) {
u8 *loc = base + rel.r_offset; u8 *loc = base + rel.r_offset;
const SectionFragmentRef<X86_64> *ref = nullptr; const SectionFragmentRef<X86_64> *ref = nullptr;
if (has_fragments[i]) if (frag_idx < rel_fragments.size() && rel_fragments[frag_idx].idx == i)
ref = &rel_fragments[ref_idx++]; ref = &rel_fragments[frag_idx++];
auto write = [&](u64 val) { auto write = [&](u64 val) {
overflow_check(ctx, this, sym, rel.r_type, val); overflow_check(ctx, this, sym, rel.r_type, val);
@ -402,7 +402,7 @@ void InputSection<X86_64>::apply_reloc_alloc(Context<X86_64> &ctx, u8 *base) {
template <> template <>
void InputSection<X86_64>::apply_reloc_nonalloc(Context<X86_64> &ctx, u8 *base) { void InputSection<X86_64>::apply_reloc_nonalloc(Context<X86_64> &ctx, u8 *base) {
std::span<ElfRel<X86_64>> rels = get_rels(ctx); std::span<ElfRel<X86_64>> rels = get_rels(ctx);
i64 ref_idx = 0; i64 frag_idx = 0;
for (i64 i = 0; i < rels.size(); i++) { for (i64 i = 0; i < rels.size(); i++) {
const ElfRel<X86_64> &rel = rels[i]; const ElfRel<X86_64> &rel = rels[i];
@ -415,8 +415,8 @@ void InputSection<X86_64>::apply_reloc_nonalloc(Context<X86_64> &ctx, u8 *base)
} }
const SectionFragmentRef<X86_64> *ref = nullptr; const SectionFragmentRef<X86_64> *ref = nullptr;
if (has_fragments[i]) if (frag_idx < rel_fragments.size() && rel_fragments[frag_idx].idx == i)
ref = &rel_fragments[ref_idx++]; ref = &rel_fragments[frag_idx++];
auto write = [&](u64 val) { auto write = [&](u64 val) {
overflow_check(ctx, this, sym, rel.r_type, val); overflow_check(ctx, this, sym, rel.r_type, val);

18
icf.cc
View File

@ -278,7 +278,7 @@ static Digest compute_digest(Context<E> &ctx, InputSection<E> &isec) {
} }
} }
i64 ref_idx = 0; i64 frag_idx = 0;
for (i64 i = 0; i < isec.get_rels(ctx).size(); i++) { for (i64 i = 0; i < isec.get_rels(ctx).size(); i++) {
ElfRel<E> &rel = isec.get_rels(ctx)[i]; ElfRel<E> &rel = isec.get_rels(ctx)[i];
@ -286,8 +286,9 @@ static Digest compute_digest(Context<E> &ctx, InputSection<E> &isec) {
hash(rel.r_type); hash(rel.r_type);
hash(isec.get_addend(rel)); hash(isec.get_addend(rel));
if (isec.has_fragments[i]) { if (frag_idx < isec.rel_fragments.size() &&
SectionFragmentRef<E> &ref = isec.rel_fragments[ref_idx++]; isec.rel_fragments[frag_idx].idx == i) {
SectionFragmentRef<E> &ref = isec.rel_fragments[frag_idx++];
hash('a'); hash('a');
isec.get_addend(rel); isec.get_addend(rel);
hash_string(ref.frag->data); hash_string(ref.frag->data);
@ -359,9 +360,13 @@ static void gather_edges(Context<E> &ctx,
tbb::parallel_for((i64)0, (i64)sections.size(), [&](i64 i) { tbb::parallel_for((i64)0, (i64)sections.size(), [&](i64 i) {
InputSection<E> &isec = *sections[i]; InputSection<E> &isec = *sections[i];
assert(isec.icf_eligible); assert(isec.icf_eligible);
i64 frag_idx = 0;
for (i64 j = 0; j < isec.get_rels(ctx).size(); j++) { for (i64 j = 0; j < isec.get_rels(ctx).size(); j++) {
if (!isec.has_fragments[j]) { if (frag_idx < isec.rel_fragments.size() &&
isec.rel_fragments[frag_idx].idx == j) {
frag_idx++;
} else {
ElfRel<E> &rel = isec.get_rels(ctx)[j]; ElfRel<E> &rel = isec.get_rels(ctx)[j];
Symbol<E> &sym = *isec.file.symbols[rel.r_sym]; Symbol<E> &sym = *isec.file.symbols[rel.r_sym];
if (!sym.get_frag() && sym.input_section && sym.input_section->icf_eligible) if (!sym.get_frag() && sym.input_section && sym.input_section->icf_eligible)
@ -377,10 +382,13 @@ static void gather_edges(Context<E> &ctx,
tbb::parallel_for((i64)0, (i64)num_edges.size(), [&](i64 i) { tbb::parallel_for((i64)0, (i64)num_edges.size(), [&](i64 i) {
InputSection<E> &isec = *sections[i]; InputSection<E> &isec = *sections[i];
i64 frag_idx = 0;
i64 idx = edge_indices[i]; i64 idx = edge_indices[i];
for (i64 j = 0; j < isec.get_rels(ctx).size(); j++) { for (i64 j = 0; j < isec.get_rels(ctx).size(); j++) {
if (!isec.has_fragments[j]) { if (frag_idx < isec.rel_fragments.size() &&
isec.rel_fragments[frag_idx].idx == j) {
frag_idx++;
ElfRel<E> &rel = isec.get_rels(ctx)[j]; ElfRel<E> &rel = isec.get_rels(ctx)[j];
Symbol<E> &sym = *isec.file.symbols[rel.r_sym]; Symbol<E> &sym = *isec.file.symbols[rel.r_sym];
if (!sym.get_frag() && sym.input_section && sym.input_section->icf_eligible) if (!sym.get_frag() && sym.input_section && sym.input_section->icf_eligible)

4
mold.h
View File

@ -83,6 +83,7 @@ struct SectionFragment {
template <typename E> template <typename E>
struct SectionFragmentRef { struct SectionFragmentRef {
SectionFragment<E> *frag = nullptr; SectionFragment<E> *frag = nullptr;
i32 idx = 0;
i32 addend = 0; i32 addend = 0;
}; };
@ -255,9 +256,8 @@ public:
std::string_view name; std::string_view name;
std::string_view contents; std::string_view contents;
std::vector<u8> has_fragments;
std::vector<SectionFragmentRef<E>> rel_fragments; std::vector<SectionFragmentRef<E>> rel_fragments;
std::vector<u8> rel_types; std::unique_ptr<u8[]> rel_types;
std::span<FdeRecord<E>> fdes; std::span<FdeRecord<E>> fdes;
u32 offset = -1; u32 offset = -1;

View File

@ -230,10 +230,10 @@ void ObjectFile<E>::initialize_sections(Context<E> &ctx) {
assert(target->relsec_idx == -1); assert(target->relsec_idx == -1);
target->relsec_idx = i; target->relsec_idx = i;
i64 size = shdr.sh_size / sizeof(ElfRel<E>); if (target->shdr.sh_flags & SHF_ALLOC) {
target->has_fragments.resize(size); i64 size = shdr.sh_size / sizeof(ElfRel<E>);
if (target->shdr.sh_flags & SHF_ALLOC) target->rel_types.reset(new u8[size]);
target->rel_types.resize(size); }
} }
} }
} }
@ -602,9 +602,9 @@ void ObjectFile<E>::initialize_mergeable_sections(Context<E> &ctx) {
Fatal(ctx) << *this << ": bad relocation at " << rel.r_sym; Fatal(ctx) << *this << ": bad relocation at " << rel.r_sym;
i64 idx = it - 1 - offsets.begin(); i64 idx = it - 1 - offsets.begin();
SectionFragmentRef<E> ref{m.fragments[idx], (i32)(offset - offsets[idx])}; SectionFragmentRef<E> ref{m.fragments[idx], (i32)i,
(i32)(offset - offsets[idx])};
isec->rel_fragments.push_back(ref); isec->rel_fragments.push_back(ref);
isec->has_fragments[i] = true;
} }
} }