15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- MipsLDBackend.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 MIPS_LDBACKEND_H
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#define MIPS_LDBACKEND_H
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "mcld/Target/GNULDBackend.h"
125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "MipsELFDynamic.h"
135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "MipsGOT.h"
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld {
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass MCLinker;
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass OutputRelocSection;
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass SectionMap;
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// MipsGNULDBackend - linker backend of Mips target of GNU ELF format
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass MipsGNULDBackend : public GNULDBackend
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  enum ReservedEntryType {
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    None          = 0,  // no reserved entry
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ReserveRel    = 1,  // reserve a dynamic relocation entry
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ReserveGot    = 2,  // reserve a GOT entry
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ReserveGpDisp = 8   // reserve _gp_disp symbol
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  };
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MipsGNULDBackend();
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ~MipsGNULDBackend();
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// initTargetSectionMap - initialize target dependent section mapping.
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool initTargetSectionMap(SectionMap& pSectionMap);
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// initTargetSections - initialize target dependent sections in output
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void initTargetSections(MCLinker& pLinker);
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// initTargetSymbols - initialize target dependent symbols in output.
46affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  void initTargetSymbols(MCLinker& pLinker, const Output& pOutput);
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// initRelocFactory - create and initialize RelocationFactory.
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool initRelocFactory(const MCLinker& pLinker);
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getRelocFactory - return relocation factory.
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  RelocationFactory* getRelocFactory();
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// scanRelocation - determine the empty entries are needed or not and
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// create the empty entries if needed.
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// For Mips, the GOT, GP, and dynamic relocation entries are check to create.
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void scanRelocation(Relocation& pReloc,
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      const LDSymbol& pInputSym,
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      MCLinker& pLinker,
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      const MCLDInfo& pLDInfo,
61affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      const Output& pOutput,
62affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                      const LDSection& pSection);
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t machine() const;
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// OSABI - the value of e_ident[EI_OSABI]
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint8_t OSABI() const;
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// ABIVersion - the value of e_ident[EI_ABIVRESION]
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint8_t ABIVersion() const;
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// flags - the value of ElfXX_Ehdr::e_flags
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t flags() const;
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool isLittleEndian() const;
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int bitclass() const;
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t defaultTextSegmentAddr() const;
80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
81cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  /// abiPageSize - the abi page size of the target machine
82cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  uint64_t abiPageSize(const MCLDInfo& pInfo) const;
83cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// preLayout - Backend can do any needed modification before layout
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void doPreLayout(const Output& pOutput,
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   const MCLDInfo& pInfo,
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   MCLinker& pLinker);
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// postLayout -Backend can do any needed modification after layout
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void doPostLayout(const Output& pOutput,
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                    const MCLDInfo& pInfo,
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                    MCLinker& pLinker);
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// dynamic - the dynamic section of the target machine.
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// Use co-variant return type to return its own dynamic section.
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MipsELFDynamic& dynamic();
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// dynamic - the dynamic section of the target machine.
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// Use co-variant return type to return its own dynamic section.
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const MipsELFDynamic& dynamic() const;
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitSectionData - write out the section data into the memory region.
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// call back target backend to emit the data.
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// Backends handle the target-special tables (plt, gp,...) by themselves.
107cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  /// Backend can put the data of the tables in SectionData directly
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///  - LDSection.getSectionData can get the section data.
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// Or, backend can put the data into special data structure
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///  - backend can maintain its own map<LDSection, table> to get the table
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// from given LDSection.
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param pOutput - the output file
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param pSection - the given LDSection
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param pInfo - all options in the command line.
116affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @param pLayout - for comouting the size of fragment
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param pRegion - the region to write out data
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @return the size of the table in the file.
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t emitSectionData(const Output& pOutput,
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                           const LDSection& pSection,
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                           const MCLDInfo& pInfo,
122affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                           const Layout& pLayout,
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                           MemoryRegion& pRegion) const;
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual void emitDynNamePools(Output& pOutput,
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                SymbolCategory& pSymbols,
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                const Layout& pLayout,
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                const MCLDInfo& pLDInfo);
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MipsGOT& getGOT();
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const MipsGOT& getGOT() const;
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  OutputRelocSection& getRelDyn();
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const OutputRelocSection& getRelDyn() const;
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getTargetSectionOrder - compute the layout order of ARM target sections
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int getTargetSectionOrder(const Output& pOutput,
139affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                     const LDSection& pSectHdr,
140affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                     const MCLDInfo& pInfo) const;
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// finalizeSymbol - finalize the symbol value
143affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  bool finalizeTargetSymbols(MCLinker& pLinker, const Output& pOutput);
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// allocateCommonSymbols - allocate common symbols in the corresponding
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// sections.
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool allocateCommonSymbols(const MCLDInfo& pLDInfo, MCLinker& pLinker) const;
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void scanLocalReloc(Relocation& pReloc,
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      const LDSymbol& pInputSym,
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      MCLinker& pLinker,
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      const MCLDInfo& pLDInfo,
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      const Output& pOutput);
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void scanGlobalReloc(Relocation& pReloc,
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      const LDSymbol& pInputSym,
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      MCLinker& pLinker,
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      const MCLDInfo& pLDInfo,
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      const Output& pOutput);
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void createGOT(MCLinker& pLinker, const Output& pOutput);
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void createRelDyn(MCLinker& pLinker, const Output& pOutput);
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// updateAddend - update addend value of the relocation if the
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// the target symbol is a section symbol. Addend is the offset
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// in the section. This value should be updated after section
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// merged.
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void updateAddend(Relocation& pReloc,
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                    const LDSymbol& pInputSym,
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                    const Layout& pLayout) const;
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  RelocationFactory* m_pRelocFactory;
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MipsGOT* m_pGOT;                      // .got
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  OutputRelocSection* m_pRelDyn;        // .rel.dyn
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MipsELFDynamic* m_pDynamic;
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSymbol* m_pGOTSymbol;
1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSymbol* m_pGpDispSymbol;
1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  std::vector<LDSymbol*> m_GlobalGOTSyms;
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
186affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// isGlobalGOTSymbol - return true if the symbol is the global GOT entry.
187affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  bool isGlobalGOTSymbol(const LDSymbol& pSymbol) const;
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitDynamicSymbol - emit dynamic symbol.
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void emitDynamicSymbol(llvm::ELF::Elf32_Sym& sym32,
190d8a752331fe7a30ce41835f139aa8a4c675ad07aShih-wei Liao                         Output& pOutput,
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                         LDSymbol& pSymbol,
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                         const Layout& pLayout,
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                         char* strtab,
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                         size_t strtabsize,
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                         size_t symtabIdx);
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
201affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
202