diff options
Diffstat (limited to 'lib/ReaderWriter/ELF/Mips/MipsDynamicTable.h')
| -rw-r--r-- | lib/ReaderWriter/ELF/Mips/MipsDynamicTable.h | 89 |
1 files changed, 49 insertions, 40 deletions
diff --git a/lib/ReaderWriter/ELF/Mips/MipsDynamicTable.h b/lib/ReaderWriter/ELF/Mips/MipsDynamicTable.h index 2b9562f42b57..480c69cf4600 100644 --- a/lib/ReaderWriter/ELF/Mips/MipsDynamicTable.h +++ b/lib/ReaderWriter/ELF/Mips/MipsDynamicTable.h @@ -9,83 +9,89 @@ #ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_DYNAMIC_TABLE_H #define LLD_READER_WRITER_ELF_MIPS_MIPS_DYNAMIC_TABLE_H -#include "DefaultLayout.h" +#include "TargetLayout.h" #include "SectionChunks.h" namespace lld { namespace elf { -template <class ELFType> class MipsTargetLayout; +template <class ELFT> class MipsTargetLayout; -template <class MipsELFType> -class MipsDynamicTable : public DynamicTable<MipsELFType> { +template <class ELFT> class MipsDynamicTable : public DynamicTable<ELFT> { public: - MipsDynamicTable(const ELFLinkingContext &ctx, - MipsTargetLayout<MipsELFType> &layout) - : DynamicTable<MipsELFType>(ctx, layout, ".dynamic", - DefaultLayout<MipsELFType>::ORDER_DYNAMIC), - _mipsTargetLayout(layout) {} + MipsDynamicTable(const ELFLinkingContext &ctx, MipsTargetLayout<ELFT> &layout) + : DynamicTable<ELFT>(ctx, layout, ".dynamic", + TargetLayout<ELFT>::ORDER_DYNAMIC), + _targetLayout(layout) {} void createDefaultEntries() override { - DynamicTable<MipsELFType>::createDefaultEntries(); - - typename DynamicTable<MipsELFType>::Elf_Dyn dyn; + DynamicTable<ELFT>::createDefaultEntries(); // Version id for the Runtime Linker Interface. - dyn.d_un.d_val = 1; - dyn.d_tag = DT_MIPS_RLD_VERSION; - this->addEntry(dyn); + this->addEntry(DT_MIPS_RLD_VERSION, 1); + + // The .rld_map section address. + if (this->_ctx.getOutputELFType() == ET_EXEC) { + _dt_rldmap = this->addEntry(DT_MIPS_RLD_MAP, 0); + _dt_rldmaprel = this->addEntry(DT_MIPS_RLD_MAP_REL, 0); + } // MIPS flags. - dyn.d_un.d_val = RHF_NOTPOT; - dyn.d_tag = DT_MIPS_FLAGS; - this->addEntry(dyn); + this->addEntry(DT_MIPS_FLAGS, RHF_NOTPOT); // The base address of the segment. - dyn.d_un.d_ptr = 0; - dyn.d_tag = DT_MIPS_BASE_ADDRESS; - _dt_baseaddr = this->addEntry(dyn); + _dt_baseaddr = this->addEntry(DT_MIPS_BASE_ADDRESS, 0); // Number of local global offset table entries. - dyn.d_un.d_val = 0; - dyn.d_tag = DT_MIPS_LOCAL_GOTNO; - _dt_localgot = this->addEntry(dyn); + _dt_localgot = this->addEntry(DT_MIPS_LOCAL_GOTNO, 0); // Number of entries in the .dynsym section. - dyn.d_un.d_val = 0; - dyn.d_tag = DT_MIPS_SYMTABNO; - _dt_symtabno = this->addEntry(dyn); + _dt_symtabno = this->addEntry(DT_MIPS_SYMTABNO, 0); // The index of the first dynamic symbol table entry that corresponds // to an entry in the global offset table. - dyn.d_un.d_val = 0; - dyn.d_tag = DT_MIPS_GOTSYM; - _dt_gotsym = this->addEntry(dyn); + _dt_gotsym = this->addEntry(DT_MIPS_GOTSYM, 0); // Address of the .got section. - dyn.d_un.d_val = 0; - dyn.d_tag = DT_PLTGOT; - _dt_pltgot = this->addEntry(dyn); + _dt_pltgot = this->addEntry(DT_PLTGOT, 0); + } + + void doPreFlight() override { + DynamicTable<ELFT>::doPreFlight(); + + if (_targetLayout.findOutputSection(".MIPS.options")) { + _dt_options = this->addEntry(DT_MIPS_OPTIONS, 0); + } } void updateDynamicTable() override { - DynamicTable<MipsELFType>::updateDynamicTable(); + DynamicTable<ELFT>::updateDynamicTable(); // Assign the minimum segment address to the DT_MIPS_BASE_ADDRESS tag. auto baseAddr = std::numeric_limits<uint64_t>::max(); - for (auto si : _mipsTargetLayout.segments()) + for (auto si : _targetLayout.segments()) if (si->segmentType() != llvm::ELF::PT_NULL) baseAddr = std::min(baseAddr, si->virtualAddr()); this->_entries[_dt_baseaddr].d_un.d_val = baseAddr; - auto &got = _mipsTargetLayout.getGOTSection(); + auto &got = _targetLayout.getGOTSection(); this->_entries[_dt_symtabno].d_un.d_val = this->getSymbolTable()->size(); this->_entries[_dt_gotsym].d_un.d_val = - this-> getSymbolTable()->size() - got.getGlobalCount(); + this->getSymbolTable()->size() - got.getGlobalCount(); this->_entries[_dt_localgot].d_un.d_val = got.getLocalCount(); - this->_entries[_dt_pltgot].d_un.d_ptr = - _mipsTargetLayout.findOutputSection(".got")->virtualAddr(); + this->_entries[_dt_pltgot].d_un.d_ptr = got.virtualAddr(); + + if (const auto *sec = _targetLayout.findOutputSection(".MIPS.options")) + this->_entries[_dt_options].d_un.d_ptr = sec->virtualAddr(); + + if (const auto *sec = _targetLayout.findOutputSection(".rld_map")) { + this->_entries[_dt_rldmap].d_un.d_ptr = sec->virtualAddr(); + this->_entries[_dt_rldmaprel].d_un.d_ptr = + sec->virtualAddr() - + (this->virtualAddr() + + _dt_rldmaprel * sizeof(typename DynamicTable<ELFT>::Elf_Dyn)); + } } int64_t getGotPltTag() override { return DT_MIPS_PLTGOT; } @@ -106,7 +112,10 @@ private: std::size_t _dt_gotsym; std::size_t _dt_pltgot; std::size_t _dt_baseaddr; - MipsTargetLayout<MipsELFType> &_mipsTargetLayout; + std::size_t _dt_options; + std::size_t _dt_rldmap; + std::size_t _dt_rldmaprel; + MipsTargetLayout<ELFT> &_targetLayout; }; } // end namespace elf |
