mirror of
https://github.com/rui314/mold.git
synced 2024-09-21 09:57:18 +03:00
wip
This commit is contained in:
parent
3a97d2f75a
commit
1f1e442265
@ -42,7 +42,7 @@ static void visit(Context<E> &ctx, InputSection<E> *isec,
|
||||
// describing how to handle exceptions for that function.
|
||||
// We want to keep associated .eh_frame records.
|
||||
for (FdeRecord<E> &fde : isec->get_fdes())
|
||||
for (ElfRel<E> &rel : fde.get_rels(isec->file).subspan(1))
|
||||
for (ElfRel<E> &rel : fde.get_rels().subspan(1))
|
||||
if (Symbol<E> *sym = isec->file.symbols[rel.r_sym])
|
||||
if (mark_section(sym->input_section))
|
||||
feeder.add(sym->input_section);
|
||||
|
17
icf.cc
17
icf.cc
@ -128,7 +128,7 @@ static bool is_leaf(Context<E> &ctx, InputSection<E> &isec) {
|
||||
return false;
|
||||
|
||||
for (FdeRecord<E> &fde : isec.get_fdes())
|
||||
if (fde.get_rels(isec.file).size() > 1)
|
||||
if (fde.get_rels().size() > 1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -143,7 +143,7 @@ struct LeafHasher {
|
||||
size_t operator()(const InputSection<E> *isec) const {
|
||||
size_t h = hash_string(isec->contents);
|
||||
for (FdeRecord<E> &fde : isec->get_fdes()) {
|
||||
size_t h2 = hash_string(fde.get_contents(isec->file).substr(8));
|
||||
size_t h2 = hash_string(fde.get_contents().substr(8));
|
||||
h = combine_hash(h, h2);
|
||||
}
|
||||
return h;
|
||||
@ -163,8 +163,7 @@ struct LeafEq {
|
||||
return false;
|
||||
|
||||
for (i64 i = 0; i < x.size(); i++)
|
||||
if (x[i].get_contents(a->file).substr(8) !=
|
||||
y[i].get_contents(b->file).substr(8))
|
||||
if (x[i].get_contents().substr(8) != y[i].get_contents().substr(8))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@ -260,19 +259,19 @@ static Digest compute_digest(Context<E> &ctx, InputSection<E> &isec) {
|
||||
hash(isec.get_rels(ctx).size());
|
||||
|
||||
for (FdeRecord<E> &fde : isec.get_fdes()) {
|
||||
hash(isec.file.cies[fde.cie_idx].icf_idx);
|
||||
hash(fde.cie->icf_idx);
|
||||
|
||||
// Bytes 0 to 4 contain the length of this record, and
|
||||
// bytes 4 to 8 contain an offset to CIE.
|
||||
hash_string(fde.get_contents(isec.file).substr(8));
|
||||
hash_string(fde.get_contents().substr(8));
|
||||
|
||||
hash(fde.get_rels(isec.file).size());
|
||||
hash(fde.get_rels().size());
|
||||
|
||||
for (ElfRel<E> &rel : fde.get_rels(isec.file).subspan(1)) {
|
||||
for (ElfRel<E> &rel : fde.get_rels().subspan(1)) {
|
||||
hash_symbol(*isec.file.symbols[rel.r_sym]);
|
||||
hash(rel.r_type);
|
||||
hash(rel.r_offset - fde.input_offset);
|
||||
hash(isec.file.cies[fde.cie_idx].input_section.get_addend(rel));
|
||||
hash(fde.cie->input_section.get_addend(rel));
|
||||
}
|
||||
}
|
||||
|
||||
|
19
mold.h
19
mold.h
@ -51,6 +51,8 @@ template <typename E> class OutputSection;
|
||||
template <typename E> class SharedFile;
|
||||
template <typename E> class Symbol;
|
||||
template <typename E> struct Context;
|
||||
template <typename E> struct FdeRecord;
|
||||
template <typename E> struct CieRecord;
|
||||
|
||||
template <typename E> void cleanup();
|
||||
|
||||
@ -149,31 +151,30 @@ enum {
|
||||
|
||||
template <typename E>
|
||||
struct FdeRecord {
|
||||
FdeRecord(u32 input_offset, u32 rel_idx, u16 cie_idx)
|
||||
: input_offset(input_offset), rel_idx(rel_idx), cie_idx(cie_idx) {}
|
||||
FdeRecord(u32 input_offset, u32 rel_idx)
|
||||
: input_offset(input_offset), rel_idx(rel_idx) {}
|
||||
|
||||
FdeRecord(const FdeRecord &other)
|
||||
: input_offset(other.input_offset),
|
||||
output_offset(other.output_offset),
|
||||
rel_idx(other.rel_idx), cie_idx(other.cie_idx),
|
||||
: cie(other.cie), input_offset(other.input_offset),
|
||||
output_offset(other.output_offset), rel_idx(other.rel_idx),
|
||||
is_alive(other.is_alive.load()) {}
|
||||
|
||||
FdeRecord &operator=(const FdeRecord<E> &other) {
|
||||
cie = other.cie;
|
||||
input_offset = other.input_offset;
|
||||
output_offset = other.output_offset;
|
||||
rel_idx = other.rel_idx;
|
||||
cie_idx = other.cie_idx;
|
||||
is_alive = other.is_alive.load();
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string_view get_contents(ObjectFile<E> &file) const;
|
||||
std::span<ElfRel<E>> get_rels(ObjectFile<E> &file) const;
|
||||
std::string_view get_contents() const;
|
||||
std::span<ElfRel<E>> get_rels() const;
|
||||
|
||||
CieRecord<E> *cie = nullptr;
|
||||
u32 input_offset = -1;
|
||||
u32 output_offset = -1;
|
||||
u32 rel_idx = -1;
|
||||
u16 cie_idx = -1;
|
||||
std::atomic_bool is_alive = true;
|
||||
};
|
||||
|
||||
|
@ -306,13 +306,6 @@ void ObjectFile<E>::read_ehframe(Context<E> &ctx, InputSection<E> &isec) {
|
||||
std::string_view contents = this->get_string(ctx, isec.shdr);
|
||||
i64 rel_idx = 0;
|
||||
|
||||
auto find_cie = [&](i64 offset) -> u16{
|
||||
for (i64 i = cies.size() - 1; i >= 0; i--)
|
||||
if (cies[i].input_offset == offset)
|
||||
return i;
|
||||
Fatal(ctx) << isec << ": bad FDE pointer";
|
||||
};
|
||||
|
||||
for (std::string_view data = contents; !data.empty();) {
|
||||
i64 size = *(u32 *)data.data();
|
||||
if (size == 0) {
|
||||
@ -339,11 +332,25 @@ void ObjectFile<E>::read_ehframe(Context<E> &ctx, InputSection<E> &isec) {
|
||||
if (rels[rel_begin].r_offset - begin_offset != 8)
|
||||
Fatal(ctx) << isec << ": FDE's first relocation should have offset 8";
|
||||
|
||||
i64 cie_idx = find_cie(begin_offset + 4 - id);
|
||||
fdes.push_back(FdeRecord<E>(begin_offset, rel_begin, cie_idx));
|
||||
fdes.push_back(FdeRecord<E>(begin_offset, rel_begin));
|
||||
}
|
||||
}
|
||||
|
||||
// Associate CIEs to FDEs.
|
||||
auto find_cie = [&](i64 offset) -> CieRecord<E> * {
|
||||
for (i64 i = cies.size() - 1; i >= 0; i--)
|
||||
if (cies[i].input_offset == offset)
|
||||
return &cies[i];
|
||||
Fatal(ctx) << isec << ": bad FDE pointer";
|
||||
};
|
||||
|
||||
for (FdeRecord<E> &fde : fdes) {
|
||||
i64 cie_offset = *(i32 *)(contents.data() + fde.input_offset + 4);
|
||||
fde.cie = find_cie(fde.input_offset + 4 - cie_offset);
|
||||
}
|
||||
|
||||
// We assume that FDEs for the same input sections are contiguous
|
||||
// in `fdes` vector.
|
||||
sort(fdes, [&](const FdeRecord<E> &a, const FdeRecord<E> &b) {
|
||||
InputSection<E> *x = this->symbols[rels[a.rel_idx].r_sym]->input_section;
|
||||
InputSection<E> *y = this->symbols[rels[b.rel_idx].r_sym]->input_section;
|
||||
@ -1293,16 +1300,15 @@ bool SharedFile<E>::is_readonly(Context<E> &ctx, Symbol<E> *sym) {
|
||||
}
|
||||
|
||||
template <typename E>
|
||||
std::string_view FdeRecord<E>::get_contents(ObjectFile<E> &file) const {
|
||||
std::string_view data = file.cies[cie_idx].contents;
|
||||
i64 size = *(u32 *)(data.data() + input_offset) + 4;
|
||||
return data.substr(input_offset, size);
|
||||
std::string_view FdeRecord<E>::get_contents() const {
|
||||
i64 size = *(u32 *)(cie->contents.data() + input_offset) + 4;
|
||||
return cie->contents.substr(input_offset, size);
|
||||
}
|
||||
|
||||
template <typename E>
|
||||
std::span<ElfRel<E>> FdeRecord<E>::get_rels(ObjectFile<E> &file) const {
|
||||
std::span<ElfRel<E>> rels = file.cies[cie_idx].rels;
|
||||
i64 size = get_contents(file).size();
|
||||
std::span<ElfRel<E>> FdeRecord<E>::get_rels() const {
|
||||
std::span<ElfRel<E>> rels = cie->rels;
|
||||
i64 size = get_contents().size();
|
||||
i64 end = rel_idx;
|
||||
while (end < rels.size() && rels[end].r_offset < input_offset + size)
|
||||
end++;
|
||||
|
@ -1154,7 +1154,7 @@ void EhFrameSection<E>::construct(Context<E> &ctx) {
|
||||
i64 offset = 0;
|
||||
for (FdeRecord<E> &fde : file->fdes) {
|
||||
fde.output_offset = offset;
|
||||
offset += fde.get_contents(*file).size();
|
||||
offset += fde.get_contents().size();
|
||||
}
|
||||
file->fde_size = offset;
|
||||
});
|
||||
@ -1223,17 +1223,16 @@ void EhFrameSection<E>::copy_buf(Context<E> &ctx) {
|
||||
for (FdeRecord<E> &fde : file->fdes) {
|
||||
i64 offset = file->fde_offset + fde.output_offset;
|
||||
|
||||
std::string_view contents = fde.get_contents(*file);
|
||||
std::string_view contents = fde.get_contents();
|
||||
memcpy(base + offset, contents.data(), contents.size());
|
||||
|
||||
CieRecord<E> &cie = file->cies[fde.cie_idx];
|
||||
*(u32 *)(base + offset + 4) = offset + 4 - cie.output_offset;
|
||||
*(u32 *)(base + offset + 4) = offset + 4 - fde.cie->output_offset;
|
||||
|
||||
for (ElfRel<E> &rel : fde.get_rels(*file)) {
|
||||
for (ElfRel<E> &rel : fde.get_rels()) {
|
||||
assert(rel.r_offset - fde.input_offset < contents.size());
|
||||
u64 loc = offset + rel.r_offset - fde.input_offset;
|
||||
u64 val = file->symbols[rel.r_sym]->get_addr(ctx);
|
||||
u64 addend = cie.input_section.get_addend(rel);
|
||||
u64 addend = fde.cie->input_section.get_addend(rel);
|
||||
apply_reloc(ctx, rel, loc, val + addend);
|
||||
}
|
||||
}
|
||||
@ -1266,9 +1265,9 @@ void EhFrameHdrSection<E>::copy_buf(Context<E> &ctx) {
|
||||
Entry *entry = (Entry *)(base + HEADER_SIZE) + file->fde_idx;
|
||||
|
||||
for (FdeRecord<E> &fde : file->fdes) {
|
||||
ElfRel<E> rel = fde.get_rels(*file)[0];
|
||||
ElfRel<E> rel = fde.get_rels()[0];
|
||||
u64 val = file->symbols[rel.r_sym]->get_addr(ctx);
|
||||
u64 addend = file->cies[fde.cie_idx].input_section.get_addend(rel);
|
||||
u64 addend = fde.cie->input_section.get_addend(rel);
|
||||
|
||||
*entry++ = {(i32)(val + addend - this->shdr.sh_addr),
|
||||
(i32)(eh_frame_addr + file->fde_offset +
|
||||
|
Loading…
Reference in New Issue
Block a user