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-03-30 22:26:03 +09:00
parent adcccbeeef
commit b2cf86b51a
2 changed files with 68 additions and 113 deletions

View File

@ -263,15 +263,14 @@ void ObjectFile<E>::initialize_ehframe_sections(Context<E> &ctx) {
// In order to create .eh_frame_hdr, linker has to read .eh_frame.
//
// This function parses an input .eh_frame section.
template <>
void ObjectFile<X86_64>::read_ehframe(Context<X86_64> &ctx,
InputSection<X86_64> &isec) {
std::span<ElfRel<X86_64>> rels = isec.rels;
template <typename E>
void ObjectFile<E>::read_ehframe(Context<E> &ctx, InputSection<E> &isec) {
std::span<ElfRel<E>> rels = isec.rels;
std::string_view data = this->get_string(ctx, isec.shdr);
const char *begin = data.data();
if (data.empty()) {
cies.push_back(CieRecord<X86_64>{data});
cies.push_back(CieRecord<E>{data});
return;
}
@ -279,7 +278,7 @@ void ObjectFile<X86_64>::read_ehframe(Context<X86_64> &ctx,
i64 cur_cie = -1;
i64 cur_cie_offset = -1;
for (ElfRel<X86_64> rel : rels)
for (ElfRel<E> rel : rels)
if (rel.r_type != R_X86_64_32 && rel.r_type != R_X86_64_64 &&
rel.r_type != R_X86_64_PC32 && rel.r_type != R_X86_64_PC64)
Fatal(ctx) << isec << ": unsupported relocation type: "
@ -290,7 +289,7 @@ void ObjectFile<X86_64>::read_ehframe(Context<X86_64> &ctx,
if (size == 0) {
if (data.size() != 4)
Fatal(ctx) << isec << ": garbage at end of section";
cies.push_back(CieRecord<X86_64>{data});
cies.push_back(CieRecord<E>{data});
return;
}
@ -304,16 +303,16 @@ void ObjectFile<X86_64>::read_ehframe(Context<X86_64> &ctx,
data = data.substr(size + 4);
i64 id = *(u32 *)(contents.data() + 4);
std::vector<EhReloc<X86_64>> eh_rels;
std::vector<EhReloc<E>> eh_rels;
while (!rels.empty() && rels[0].r_offset < end_offset) {
if (id && first_global <= rels[0].r_sym)
Fatal(ctx) << isec
<< ": FDE with non-local relocations is not supported";
Symbol<X86_64> &sym = *this->symbols[rels[0].r_sym];
eh_rels.push_back(EhReloc<X86_64>{sym, rels[0].r_type,
Symbol<E> &sym = *this->symbols[rels[0].r_sym];
eh_rels.push_back(EhReloc<E>{sym, rels[0].r_type,
(u32)(rels[0].r_offset - begin_offset),
rels[0].r_addend});
isec.get_addend(rels[0])});
rels = rels.subspan(1);
}
@ -321,7 +320,7 @@ void ObjectFile<X86_64>::read_ehframe(Context<X86_64> &ctx,
// CIE
cur_cie = cies.size();
offset_to_cie[begin_offset] = cies.size();
cies.push_back(CieRecord<X86_64>{contents, std::move(eh_rels)});
cies.push_back(CieRecord<E>{contents, std::move(eh_rels)});
} else {
// FDE
i64 cie_offset = begin_offset + 4 - id;
@ -343,10 +342,10 @@ void ObjectFile<X86_64>::read_ehframe(Context<X86_64> &ctx,
}
}
for (CieRecord<X86_64> &cie : cies) {
std::span<FdeRecord<X86_64>> fdes = cie.fdes;
for (CieRecord<E> &cie : cies) {
std::span<FdeRecord<E>> fdes = cie.fdes;
while (!fdes.empty()) {
InputSection<X86_64> *isec = fdes[0].rels[0].sym.input_section;
InputSection<E> *isec = fdes[0].rels[0].sym.input_section;
i64 i = 1;
while (i < fdes.size() && isec == fdes[i].rels[0].sym.input_section)
i++;
@ -356,10 +355,6 @@ void ObjectFile<X86_64>::read_ehframe(Context<X86_64> &ctx,
}
}
template <>
void ObjectFile<I386>::read_ehframe(Context<I386> &ctx, InputSection<I386> &isec) {
}
template <typename E>
static bool should_write_to_local_symtab(Context<E> &ctx, Symbol<E> &sym) {
if (ctx.arg.discard_all || ctx.arg.strip_all)
@ -538,12 +533,12 @@ split_section(Context<E> &ctx, InputSection<E> &sec) {
return rec;
}
template <>
void ObjectFile<X86_64>::initialize_mergeable_sections(Context<X86_64> &ctx) {
std::vector<MergeableSection<X86_64>> mergeable_sections(sections.size());
template <typename E>
void ObjectFile<E>::initialize_mergeable_sections(Context<E> &ctx) {
std::vector<MergeableSection<E>> mergeable_sections(sections.size());
for (i64 i = 0; i < sections.size(); i++) {
if (InputSection<X86_64> *isec = sections[i]) {
if (InputSection<E> *isec = sections[i]) {
if (isec->shdr.sh_flags & SHF_MERGE) {
mergeable_sections[i] = split_section(ctx, *isec);
sections[i] = nullptr;
@ -552,21 +547,21 @@ void ObjectFile<X86_64>::initialize_mergeable_sections(Context<X86_64> &ctx) {
}
// Initialize rel_fragments
for (InputSection<X86_64> *isec : sections) {
for (InputSection<E> *isec : sections) {
if (!isec || isec->rels.empty())
continue;
for (i64 i = 0; i < isec->rels.size(); i++) {
const ElfRel<X86_64> &rel = isec->rels[i];
const ElfSym<X86_64> &esym = elf_syms[rel.r_sym];
const ElfRel<E> &rel = isec->rels[i];
const ElfSym<E> &esym = elf_syms[rel.r_sym];
if (esym.st_type != STT_SECTION)
continue;
MergeableSection<X86_64> &m = mergeable_sections[get_shndx(esym)];
MergeableSection<E> &m = mergeable_sections[get_shndx(esym)];
if (m.fragments.empty())
continue;
i64 offset = esym.st_value + rel.r_addend;
i64 offset = esym.st_value + isec->get_addend(rel);
std::span<u32> offsets = m.frag_offsets;
auto it = std::upper_bound(offsets.begin(), offsets.end(), offset);
@ -574,8 +569,7 @@ void ObjectFile<X86_64>::initialize_mergeable_sections(Context<X86_64> &ctx) {
Fatal(ctx) << *this << ": bad relocation at " << rel.r_sym;
i64 idx = it - 1 - offsets.begin();
SectionFragmentRef<X86_64> ref{m.fragments[idx],
(i32)(offset - offsets[idx])};
SectionFragmentRef<E> ref{m.fragments[idx], (i32)(offset - offsets[idx])};
isec->rel_fragments.push_back(ref);
isec->has_fragments[i] = true;
}
@ -583,11 +577,11 @@ void ObjectFile<X86_64>::initialize_mergeable_sections(Context<X86_64> &ctx) {
// Initialize sym_fragments
for (i64 i = 0; i < elf_syms.size(); i++) {
const ElfSym<X86_64> &esym = elf_syms[i];
const ElfSym<E> &esym = elf_syms[i];
if (esym.is_abs() || esym.is_common())
continue;
MergeableSection<X86_64> &m = mergeable_sections[get_shndx(esym)];
MergeableSection<E> &m = mergeable_sections[get_shndx(esym)];
if (m.fragments.empty())
continue;
@ -607,14 +601,10 @@ void ObjectFile<X86_64>::initialize_mergeable_sections(Context<X86_64> &ctx) {
}
}
for (MergeableSection<X86_64> &m : mergeable_sections)
for (MergeableSection<E> &m : mergeable_sections)
fragments.insert(fragments.end(), m.fragments.begin(), m.fragments.end());
}
template <>
void ObjectFile<I386>::initialize_mergeable_sections(Context<I386> &ctx) {
}
template <typename E>
void ObjectFile<E>::parse(Context<E> &ctx) {
sections.resize(this->elf_sections.size());
@ -1252,16 +1242,11 @@ bool SharedFile<E>::is_readonly(Context<E> &ctx, Symbol<E> *sym) {
return false;
}
template class MemoryMappedFile<X86_64>;
template class ObjectFile<X86_64>;
template class SharedFile<X86_64>;
#define INSTANTIATE(E) \
template class MemoryMappedFile<E>; \
template class ObjectFile<E>; \
template class SharedFile<E>; \
template std::ostream &operator<<(std::ostream &, const InputFile<E> &)
template
std::ostream &operator<<(std::ostream &out, const InputFile<X86_64> &file);
template class MemoryMappedFile<I386>;
template class ObjectFile<I386>;
template class SharedFile<I386>;
template
std::ostream &operator<<(std::ostream &out, const InputFile<I386> &file);
INSTANTIATE(X86_64);
INSTANTIATE(I386);

View File

@ -1496,68 +1496,38 @@ void BuildIdSection<E>::write_buildid(Context<E> &ctx, i64 filesize) {
unreachable(ctx);
}
template class OutputChunk<X86_64>;
template class OutputEhdr<X86_64>;
template class OutputShdr<X86_64>;
template class OutputPhdr<X86_64>;
template class InterpSection<X86_64>;
template class OutputSection<X86_64>;
template class GotSection<X86_64>;
template class GotPltSection<X86_64>;
template class PltSection<X86_64>;
template class PltGotSection<X86_64>;
template class RelPltSection<X86_64>;
template class RelDynSection<X86_64>;
template class StrtabSection<X86_64>;
template class ShstrtabSection<X86_64>;
template class DynstrSection<X86_64>;
template class DynamicSection<X86_64>;
template class SymtabSection<X86_64>;
template class DynsymSection<X86_64>;
template class HashSection<X86_64>;
template class GnuHashSection<X86_64>;
template class MergedSection<X86_64>;
template class EhFrameSection<X86_64>;
template class EhFrameHdrSection<X86_64>;
template class DynbssSection<X86_64>;
template class VersymSection<X86_64>;
template class VerneedSection<X86_64>;
template class VerdefSection<X86_64>;
template class BuildIdSection<X86_64>;
#define INSTANTIATE(E) \
template class OutputChunk<E>; \
template class OutputEhdr<E>; \
template class OutputShdr<E>; \
template class OutputPhdr<E>; \
template class InterpSection<E>; \
template class OutputSection<E>; \
template class GotSection<E>; \
template class GotPltSection<E>; \
template class PltSection<E>; \
template class PltGotSection<E>; \
template class RelPltSection<E>; \
template class RelDynSection<E>; \
template class StrtabSection<E>; \
template class ShstrtabSection<E>; \
template class DynstrSection<E>; \
template class DynamicSection<E>; \
template class SymtabSection<E>; \
template class DynsymSection<E>; \
template class HashSection<E>; \
template class GnuHashSection<E>; \
template class MergedSection<E>; \
template class EhFrameSection<E>; \
template class EhFrameHdrSection<E>; \
template class DynbssSection<E>; \
template class VersymSection<E>; \
template class VerneedSection<E>; \
template class VerdefSection<E>; \
template class BuildIdSection<E>; \
template i64 BuildId::size(Context<E> &) const; \
template bool is_relro(Context<E> &, OutputChunk<E> *); \
template std::vector<ElfPhdr<E>> create_phdr(Context<E> &)
template i64 BuildId::size(Context<X86_64> &ctx) const;
template bool is_relro(Context<X86_64> &ctx, OutputChunk<X86_64> *chunk);
template std::vector<ElfPhdr<X86_64>> create_phdr(Context<X86_64> &ctx);
template class OutputChunk<I386>;
template class OutputEhdr<I386>;
template class OutputShdr<I386>;
template class OutputPhdr<I386>;
template class InterpSection<I386>;
template class OutputSection<I386>;
template class GotSection<I386>;
template class GotPltSection<I386>;
template class PltSection<I386>;
template class PltGotSection<I386>;
template class RelPltSection<I386>;
template class RelDynSection<I386>;
template class StrtabSection<I386>;
template class ShstrtabSection<I386>;
template class DynstrSection<I386>;
template class DynamicSection<I386>;
template class SymtabSection<I386>;
template class DynsymSection<I386>;
template class HashSection<I386>;
template class GnuHashSection<I386>;
template class MergedSection<I386>;
template class EhFrameSection<I386>;
template class EhFrameHdrSection<I386>;
template class DynbssSection<I386>;
template class VersymSection<I386>;
template class VerneedSection<I386>;
template class VerdefSection<I386>;
template class BuildIdSection<I386>;
template i64 BuildId::size(Context<I386> &ctx) const;
template bool is_relro(Context<I386> &ctx, OutputChunk<I386> *chunk);
template std::vector<ElfPhdr<I386>> create_phdr(Context<I386> &ctx);
INSTANTIATE(X86_64);
INSTANTIATE(I386);