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