15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- ELFDynamic.h -------------------------------------------------------===// 25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// The MCLinker Project 45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source 65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details. 75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#ifndef MCLD_TARGET_ELFDYNAMIC_H_ 1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define MCLD_TARGET_ELFDYNAMIC_H_ 115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSection.h" 1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/FileOutputBuffer.h" 1487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/ELF.h> 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <vector> 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cstring> 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 18d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaonamespace mcld { 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass ELFFileFormat; 21d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaoclass GNULDBackend; 2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass LinkerConfig; 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace elf_dynamic { 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/** \class EntryIF 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao* \brief EntryIF provides a common interface for one entry in the dynamic 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao* section 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao*/ 3037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass EntryIF { 3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines protected: 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao EntryIF(); 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3437b74a387bb3993387029859c2d9d051c41c724eStephen Hines public: 3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao virtual ~EntryIF(); 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao virtual EntryIF* clone() const = 0; 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao virtual size_t size() const = 0; 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao virtual size_t symbolSize() const = 0; 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao virtual size_t relSize() const = 0; 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao virtual size_t relaSize() const = 0; 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao virtual size_t emit(uint8_t* pAddress) const = 0; 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao virtual void setValue(uint64_t pTag, uint64_t pValue) = 0; 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}; 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4637b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <size_t BITNUMBER, bool LITTLEENDIAN> 4737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass Entry {}; 4837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 4937b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <> 5037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass Entry<32, true> : public EntryIF { 5137b74a387bb3993387029859c2d9d051c41c724eStephen Hines public: 5237b74a387bb3993387029859c2d9d051c41c724eStephen Hines typedef llvm::ELF::Elf32_Dyn Pair; 5337b74a387bb3993387029859c2d9d051c41c724eStephen Hines typedef llvm::ELF::Elf32_Sym Symbol; 5437b74a387bb3993387029859c2d9d051c41c724eStephen Hines typedef llvm::ELF::Elf32_Rel Rel; 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao typedef llvm::ELF::Elf32_Rela Rela; 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5737b74a387bb3993387029859c2d9d051c41c724eStephen Hines public: 585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao inline Entry(); 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao inline ~Entry(); 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6237b74a387bb3993387029859c2d9d051c41c724eStephen Hines Entry* clone() const { return new Entry(); } 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6437b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t size() const { return sizeof(Pair); } 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6637b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t symbolSize() const { return sizeof(Symbol); } 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6837b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t relSize() const { return sizeof(Rel); } 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7037b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t relaSize() const { return sizeof(Rela); } 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao inline void setValue(uint64_t pTag, uint64_t pValue); 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao inline size_t emit(uint8_t* pAddress) const; 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7637b74a387bb3993387029859c2d9d051c41c724eStephen Hines private: 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Pair m_Pair; 786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}; 796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8037b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <> 8137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass Entry<64, true> : public EntryIF { 8237b74a387bb3993387029859c2d9d051c41c724eStephen Hines public: 8337b74a387bb3993387029859c2d9d051c41c724eStephen Hines typedef llvm::ELF::Elf64_Dyn Pair; 8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines typedef llvm::ELF::Elf64_Sym Symbol; 8537b74a387bb3993387029859c2d9d051c41c724eStephen Hines typedef llvm::ELF::Elf64_Rel Rel; 866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef llvm::ELF::Elf64_Rela Rela; 876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8837b74a387bb3993387029859c2d9d051c41c724eStephen Hines public: 896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines inline Entry(); 906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines inline ~Entry(); 926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9337b74a387bb3993387029859c2d9d051c41c724eStephen Hines Entry* clone() const { return new Entry(); } 946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9537b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t size() const { return sizeof(Pair); } 966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9737b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t symbolSize() const { return sizeof(Symbol); } 986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9937b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t relSize() const { return sizeof(Rel); } 1006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10137b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t relaSize() const { return sizeof(Rela); } 1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines inline void setValue(uint64_t pTag, uint64_t pValue); 1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines inline size_t emit(uint8_t* pAddress) const; 1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10737b74a387bb3993387029859c2d9d051c41c724eStephen Hines private: 1086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Pair m_Pair; 10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}; 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "ELFDynamic.tcc" 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11337b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace elf_dynamic 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/** \class ELFDynamic 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * \brief ELFDynamic is the .dynamic section in ELF shared and executable 1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao * files. 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */ 11937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass ELFDynamic { 12037b74a387bb3993387029859c2d9d051c41c724eStephen Hines public: 1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao typedef std::vector<elf_dynamic::EntryIF*> EntryListType; 1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao typedef EntryListType::iterator iterator; 1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao typedef EntryListType::const_iterator const_iterator; 1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 12537b74a387bb3993387029859c2d9d051c41c724eStephen Hines public: 126d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ELFDynamic(const GNULDBackend& pBackend, const LinkerConfig& pConfig); 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao virtual ~ELFDynamic(); 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t size() const; 1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t entrySize() const; 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t numOfBytes() const; 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// reserveEntries - reserve entries 137d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao void reserveEntries(const ELFFileFormat& pFormat); 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// reserveNeedEntry - reserve on DT_NEED entry. 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao void reserveNeedEntry(); 14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// applyEntries - apply entries 143d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao void applyEntries(const ELFFileFormat& pFormat); 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao void applySoname(uint64_t pStrTabIdx); 1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 147d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao const_iterator needBegin() const { return m_NeedList.begin(); } 14837b74a387bb3993387029859c2d9d051c41c724eStephen Hines iterator needBegin() { return m_NeedList.begin(); } 1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 150d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao const_iterator needEnd() const { return m_NeedList.end(); } 15137b74a387bb3993387029859c2d9d051c41c724eStephen Hines iterator needEnd() { return m_NeedList.end(); } 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// emit 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao void emit(const LDSection& pSection, MemoryRegion& pRegion) const; 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 15637b74a387bb3993387029859c2d9d051c41c724eStephen Hines protected: 1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// reserveTargetEntries - reserve target dependent entries 1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao virtual void reserveTargetEntries(const ELFFileFormat& pFormat) = 0; 1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// applyTargetEntries - apply target-dependant 1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao virtual void applyTargetEntries(const ELFFileFormat& pFormat) = 0; 1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 16337b74a387bb3993387029859c2d9d051c41c724eStephen Hines protected: 1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao void reserveOne(uint64_t pTag); 1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao void applyOne(uint64_t pTag, uint64_t pValue); 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t symbolSize() const; 1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 170551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines const LinkerConfig& config() const { return m_Config; } 171551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 17237b74a387bb3993387029859c2d9d051c41c724eStephen Hines private: 1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao EntryListType m_EntryList; 1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao EntryListType m_NeedList; 1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao elf_dynamic::EntryIF* m_pEntryFactory; 17622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const GNULDBackend& m_Backend; 177d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao const LinkerConfig& m_Config; 1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // The entry reserved and the entry being applied are not must matched. 1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // For better performance, we use a simple counter and apply entry one-by-one 1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // by the counter. m_Idx is the counter indicating to the entry being applied. 1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t m_Idx; 1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}; 1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 18537b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 18737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#endif // MCLD_TARGET_ELFDYNAMIC_H_ 188