summaryrefslogtreecommitdiff
path: root/lib/ReaderWriter/ELF/Mips/MipsDynamicTable.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ReaderWriter/ELF/Mips/MipsDynamicTable.h')
-rw-r--r--lib/ReaderWriter/ELF/Mips/MipsDynamicTable.h89
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