mirror of
https://github.com/rui314/mold.git
synced 2024-11-11 16:58:12 +03:00
wip
This commit is contained in:
parent
fc45f0f3d2
commit
7b5e459b35
12
arch_i386.cc
12
arch_i386.cc
@ -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);
|
||||||
|
@ -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
18
icf.cc
@ -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
4
mold.h
@ -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;
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user