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//===----------------------------------------------------------------------===//
987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#ifndef MCLD_TARGET_ELFDYNAMIC_H
1087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#define MCLD_TARGET_ELFDYNAMIC_H
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDSection.h>
1387f34658dec9097d987d254a990ea7f311bfc95fStephen 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*/
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass EntryIF
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprotected:
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  EntryIF();
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual ~EntryIF();
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual EntryIF* clone() const = 0;
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual size_t size() const = 0;
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual size_t symbolSize() const = 0;
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual size_t relSize() const = 0;
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual size_t relaSize() const = 0;
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual size_t emit(uint8_t* pAddress) const = 0;
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual void setValue(uint64_t pTag, uint64_t pValue) = 0;
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<size_t BITNUMBER, bool LITTLEENDIAN>
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass Entry
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ };
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaotemplate<>
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass Entry<32, true> : public EntryIF
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef llvm::ELF::Elf32_Dyn  Pair;
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef llvm::ELF::Elf32_Sym  Symbol;
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef llvm::ELF::Elf32_Rel  Rel;
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef llvm::ELF::Elf32_Rela Rela;
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  inline Entry();
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  inline ~Entry();
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Entry* clone() const
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return new Entry(); }
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t size() const
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return sizeof(Pair); }
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t symbolSize() const
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return sizeof(Symbol); }
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t relSize() const
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return sizeof(Rel); }
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t relaSize() const
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return sizeof(Rela); }
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  inline void setValue(uint64_t pTag, uint64_t pValue);
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  inline size_t emit(uint8_t* pAddress) const;
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Pair m_Pair;
866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines};
876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<>
896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass Entry<64, true> : public EntryIF
906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinespublic:
926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef llvm::ELF::Elf64_Dyn  Pair;
936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef llvm::ELF::Elf64_Sym  Symbol;
946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef llvm::ELF::Elf64_Rel  Rel;
956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef llvm::ELF::Elf64_Rela Rela;
966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinespublic:
986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  inline Entry();
996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  inline ~Entry();
1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Entry* clone() const
1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  { return new Entry(); }
1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t size() const
1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  { return sizeof(Pair); }
1076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t symbolSize() const
1096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  { return sizeof(Symbol); }
1106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t relSize() const
1126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  { return sizeof(Rel); }
1136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t relaSize() const
1156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  { return sizeof(Rela); }
1166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  inline void setValue(uint64_t pTag, uint64_t pValue);
1186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  inline size_t emit(uint8_t* pAddress) const;
1206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesprivate:
1226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Pair m_Pair;
12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao};
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "ELFDynamic.tcc"
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of elf_dynamic
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/** \class ELFDynamic
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  \brief ELFDynamic is the .dynamic section in ELF shared and executable
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  files.
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass ELFDynamic
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef std::vector<elf_dynamic::EntryIF*> EntryListType;
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef EntryListType::iterator iterator;
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef EntryListType::const_iterator const_iterator;
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
141d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  ELFDynamic(const GNULDBackend& pBackend, const LinkerConfig& pConfig);
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual ~ELFDynamic();
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t size() const;
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t entrySize() const;
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t numOfBytes() const;
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// reserveEntries - reserve entries
152d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  void reserveEntries(const ELFFileFormat& pFormat);
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// reserveNeedEntry - reserve on DT_NEED entry.
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void reserveNeedEntry();
15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// applyEntries - apply entries
158d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  void applyEntries(const ELFFileFormat& pFormat);
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void applySoname(uint64_t pStrTabIdx);
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
162d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  const_iterator needBegin() const { return m_NeedList.begin(); }
163d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  iterator       needBegin()       { return m_NeedList.begin(); }
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
165d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  const_iterator needEnd() const { return m_NeedList.end(); }
166d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  iterator       needEnd()       { return m_NeedList.end(); }
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emit
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void emit(const LDSection& pSection, MemoryRegion& pRegion) const;
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprotected:
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// reserveTargetEntries - reserve target dependent entries
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual void reserveTargetEntries(const ELFFileFormat& pFormat) = 0;
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// applyTargetEntries - apply target-dependant
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual void applyTargetEntries(const ELFFileFormat& pFormat) = 0;
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprotected:
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void reserveOne(uint64_t pTag);
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void applyOne(uint64_t pTag, uint64_t pValue);
1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t symbolSize() const;
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
185551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  const LinkerConfig& config() const { return m_Config; }
186551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  EntryListType m_EntryList;
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  EntryListType m_NeedList;
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  elf_dynamic::EntryIF* m_pEntryFactory;
19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const GNULDBackend& m_Backend;
192d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  const LinkerConfig& m_Config;
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // The entry reserved and the entry being applied are not must matched.
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // For better performance, we use a simple counter and apply entry one-by-one
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // by the counter. m_Idx is the counter indicating to the entry being applied.
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t m_Idx;
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
204