MipsLDBackend.h revision 5460a1f25d9ddecb5c70667267d66d51af177a99
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.
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void initTargetSymbols(MCLinker& pLinker);
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,
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      const Output& pOutput);
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t machine() const;
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// OSABI - the value of e_ident[EI_OSABI]
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint8_t OSABI() const;
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// ABIVersion - the value of e_ident[EI_ABIVRESION]
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint8_t ABIVersion() const;
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// flags - the value of ElfXX_Ehdr::e_flags
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t flags() const;
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool isLittleEndian() const;
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int bitclass() const;
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// preLayout - Backend can do any needed modification before layout
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void doPreLayout(const Output& pOutput,
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   const MCLDInfo& pInfo,
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   MCLinker& pLinker);
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// postLayout -Backend can do any needed modification after layout
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void doPostLayout(const Output& pOutput,
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                    const MCLDInfo& pInfo,
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                    MCLinker& pLinker);
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// dynamic - the dynamic section of the target machine.
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// Use co-variant return type to return its own dynamic section.
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MipsELFDynamic& dynamic();
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// dynamic - the dynamic section of the target machine.
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// Use co-variant return type to return its own dynamic section.
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const MipsELFDynamic& dynamic() const;
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitSectionData - write out the section data into the memory region.
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// call back target backend to emit the data.
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// Backends handle the target-special tables (plt, gp,...) by themselves.
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// Backend can put the data of the tables in MCSectionData directly
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///  - LDSection.getSectionData can get the section data.
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// Or, backend can put the data into special data structure
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///  - backend can maintain its own map<LDSection, table> to get the table
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// from given LDSection.
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param pOutput - the output file
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param pSection - the given LDSection
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param pInfo - all options in the command line.
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @param pRegion - the region to write out data
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @return the size of the table in the file.
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t emitSectionData(const Output& pOutput,
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                           const LDSection& pSection,
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                           const MCLDInfo& pInfo,
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                           MemoryRegion& pRegion) const;
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual void emitDynNamePools(Output& pOutput,
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                SymbolCategory& pSymbols,
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                const Layout& pLayout,
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                const MCLDInfo& pLDInfo);
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MipsGOT& getGOT();
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const MipsGOT& getGOT() const;
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  OutputRelocSection& getRelDyn();
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const OutputRelocSection& getRelDyn() const;
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getTargetSectionOrder - compute the layout order of ARM target sections
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int getTargetSectionOrder(const Output& pOutput,
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                     const LDSection& pSectHdr) const;
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// finalizeSymbol - finalize the symbol value
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// If the symbol's reserved field is not zero, MCLinker will call back this
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// function to ask the final value of the symbol
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool finalizeSymbol(LDSymbol& pSymbol) const;
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// allocateCommonSymbols - allocate common symbols in the corresponding
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// sections.
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool allocateCommonSymbols(const MCLDInfo& pLDInfo, MCLinker& pLinker) const;
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void scanLocalReloc(Relocation& pReloc,
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      const LDSymbol& pInputSym,
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      MCLinker& pLinker,
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      const MCLDInfo& pLDInfo,
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      const Output& pOutput);
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void scanGlobalReloc(Relocation& pReloc,
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      const LDSymbol& pInputSym,
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      MCLinker& pLinker,
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      const MCLDInfo& pLDInfo,
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                      const Output& pOutput);
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool isSymbolNeedsPLT(ResolveInfo& pSym, const Output& pOutput) const;
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool isSymbolNeedsDynRel(ResolveInfo& pSym, const Output& pOutput) const;
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void createGOT(MCLinker& pLinker, const Output& pOutput);
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void createRelDyn(MCLinker& pLinker, const Output& pOutput);
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFFileFormat* getOutputFormat(const Output& pOutput) const;
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// updateAddend - update addend value of the relocation if the
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// the target symbol is a section symbol. Addend is the offset
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// in the section. This value should be updated after section
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// merged.
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void updateAddend(Relocation& pReloc,
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                    const LDSymbol& pInputSym,
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                    const Layout& pLayout) const;
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  RelocationFactory* m_pRelocFactory;
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MipsGOT* m_pGOT;                      // .got
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  OutputRelocSection* m_pRelDyn;        // .rel.dyn
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MipsELFDynamic* m_pDynamic;
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSymbol* m_pGOTSymbol;
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSymbol* m_pGpDispSymbol;
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  std::vector<LDSymbol*> m_LocalGOTSyms;
1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  std::vector<LDSymbol*> m_GlobalGOTSyms;
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// isGOTSymbol - return true if the symbol is the GOT entry.
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool isGOTSymbol(const LDSymbol& pSymbol) const;
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitDynamicSymbol - emit dynamic symbol.
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void emitDynamicSymbol(llvm::ELF::Elf32_Sym& sym32,
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                         Output& pOutput,
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                         LDSymbol& pSymbol,
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                         const Layout& pLayout,
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                         char* strtab,
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                         size_t strtabsize,
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                         size_t symtabIdx);
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
201