diff --git a/main.cc b/main.cc index 843fe733..bfa7f296 100644 --- a/main.cc +++ b/main.cc @@ -519,6 +519,7 @@ int main(int argc, char **argv) { // out::interp = new InterpSection; out::got = new GotSection(".got"); out::gotplt = new GotSection(".got.plt"); + out::relplt = new RelPltSection; out::shstrtab = new ShstrtabSection; out::symtab = new SymtabSection; out::strtab = new StrtabSection; diff --git a/mold.h b/mold.h index b1839621..e1f95c0a 100644 --- a/mold.h +++ b/mold.h @@ -382,10 +382,10 @@ public: std::vector> symbols; }; -class RelSection : public OutputChunk { +class RelPltSection : public OutputChunk { public: - RelSection() { - name = ".rela.dyn"; + RelPltSection() { + this->name = ".rela.plt"; shdr.sh_flags = llvm::ELF::SHF_ALLOC; shdr.sh_type = llvm::ELF::SHT_RELA; shdr.sh_addralign = 8; @@ -397,6 +397,9 @@ public: u64 get_size() const override { return size; } u64 size = 0; + OutputChunk *output_chunk = nullptr; + + std::vector> contents; }; class ShstrtabSection : public OutputChunk { @@ -465,6 +468,7 @@ extern OutputPhdr *phdr; extern InterpSection *interp; extern GotSection *got; extern GotSection *gotplt; +extern RelPltSection *relplt; extern ShstrtabSection *shstrtab; extern SymtabSection *symtab; extern StrtabSection *strtab; diff --git a/output_chunks.cc b/output_chunks.cc index 876130ca..e01ef779 100644 --- a/output_chunks.cc +++ b/output_chunks.cc @@ -8,6 +8,7 @@ OutputPhdr *out::phdr; InterpSection *out::interp; GotSection *out::got; GotSection *out::gotplt; +RelPltSection *out::relplt; ShstrtabSection *out::shstrtab; SymtabSection *out::symtab; StrtabSection *out::strtab; @@ -192,3 +193,18 @@ void GotSection::relocate(u8 *buf) { buf += 8; } } + +void RelPltSection::relocate(u8 *buf) { + assert(size == contents.size()); + + auto *rel = (ELF64LE::Rela *)(buf + shdr.sh_offset); + + for (auto pair : contents) { + u32 offset = pair.first; + Symbol *sym = pair.second; + + rel->r_offset = output_chunk->shdr.sh_addr + offset; + rel->setType(R_X86_64_IRELATIVE, false); + rel->r_addend = sym->addr; + } +}