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//===----------------------------------------------------------------------===//
95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#ifndef MCLD_ELF_DYNAMIC_SECTION_H
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#define MCLD_ELF_DYNAMIC_SECTION_H
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#ifdef ENABLE_UNITTEST
125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <gtest.h>
135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ELF.h>
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDSection.h>
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <vector>
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cstring>
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
20d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaonamespace mcld {
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass ELFFileFormat;
23d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaoclass GNULDBackend;
2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass LinkerConfig;
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass MemoryRegion;
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace elf_dynamic {
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/** \class EntryIF
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao*  \brief EntryIF provides a common interface for one entry in the dynamic
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao*  section
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao*/
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass EntryIF
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprotected:
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  EntryIF();
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual ~EntryIF();
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual EntryIF* clone() const = 0;
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual size_t size() const = 0;
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual size_t symbolSize() const = 0;
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual size_t relSize() const = 0;
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual size_t relaSize() const = 0;
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual size_t emit(uint8_t* pAddress) const = 0;
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual void setValue(uint64_t pTag, uint64_t pValue) = 0;
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<size_t BITNUMBER, bool LITTLEENDIAN>
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass Entry
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ };
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<>
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass Entry<32, true> : public EntryIF
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef llvm::ELF::Elf32_Dyn  Pair;
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef llvm::ELF::Elf32_Sym  Symbol;
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef llvm::ELF::Elf32_Rel  Rel;
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef llvm::ELF::Elf32_Rela Rela;
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  inline Entry();
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  inline ~Entry();
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Entry* clone() const
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return new Entry(); }
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t size() const
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return sizeof(Pair); }
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t symbolSize() const
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return sizeof(Symbol); }
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t relSize() const
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return sizeof(Rel); }
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t relaSize() const
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return sizeof(Rela); }
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  inline void setValue(uint64_t pTag, uint64_t pValue);
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  inline size_t emit(uint8_t* pAddress) const;
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Pair m_Pair;
896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines};
906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<>
926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass Entry<64, true> : public EntryIF
936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinespublic:
956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef llvm::ELF::Elf64_Dyn  Pair;
966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef llvm::ELF::Elf64_Sym  Symbol;
976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef llvm::ELF::Elf64_Rel  Rel;
986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef llvm::ELF::Elf64_Rela Rela;
996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinespublic:
1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  inline Entry();
1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  inline ~Entry();
1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Entry* clone() const
1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  { return new Entry(); }
1076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t size() const
1096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  { return sizeof(Pair); }
1106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t symbolSize() const
1126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  { return sizeof(Symbol); }
1136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t relSize() const
1156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  { return sizeof(Rel); }
1166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t relaSize() const
1186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  { return sizeof(Rela); }
1196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  inline void setValue(uint64_t pTag, uint64_t pValue);
1216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  inline size_t emit(uint8_t* pAddress) const;
1236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesprivate:
1256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Pair m_Pair;
12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao};
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "ELFDynamic.tcc"
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of elf_dynamic
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/** \class ELFDynamic
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  \brief ELFDynamic is the .dynamic section in ELF shared and executable
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  files.
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass ELFDynamic
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef std::vector<elf_dynamic::EntryIF*> EntryListType;
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef EntryListType::iterator iterator;
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef EntryListType::const_iterator const_iterator;
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
144d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  ELFDynamic(const GNULDBackend& pBackend, const LinkerConfig& pConfig);
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual ~ELFDynamic();
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t size() const;
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t entrySize() const;
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t numOfBytes() const;
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// reserveEntries - reserve entries
155d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  void reserveEntries(const ELFFileFormat& pFormat);
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// reserveNeedEntry - reserve on DT_NEED entry.
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void reserveNeedEntry();
15922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// applyEntries - apply entries
161d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  void applyEntries(const ELFFileFormat& pFormat);
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void applySoname(uint64_t pStrTabIdx);
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
165d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  const_iterator needBegin() const { return m_NeedList.begin(); }
166d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  iterator       needBegin()       { return m_NeedList.begin(); }
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
168d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  const_iterator needEnd() const { return m_NeedList.end(); }
169d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  iterator       needEnd()       { return m_NeedList.end(); }
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emit
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void emit(const LDSection& pSection, MemoryRegion& pRegion) const;
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprotected:
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// reserveTargetEntries - reserve target dependent entries
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual void reserveTargetEntries(const ELFFileFormat& pFormat) = 0;
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// applyTargetEntries - apply target-dependant
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual void applyTargetEntries(const ELFFileFormat& pFormat) = 0;
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprotected:
1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void reserveOne(uint64_t pTag);
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void applyOne(uint64_t pTag, uint64_t pValue);
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t symbolSize() const;
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  EntryListType m_EntryList;
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  EntryListType m_NeedList;
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  elf_dynamic::EntryIF* m_pEntryFactory;
19222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const GNULDBackend& m_Backend;
193d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  const LinkerConfig& m_Config;
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // The entry reserved and the entry being applied are not must matched.
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // For better performance, we use a simple counter and apply entry one-by-one
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // by the counter. m_Idx is the counter indicating to the entry being applied.
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t m_Idx;
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
205