15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- GNULDBackend.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_GNULDBACKEND_H
1087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#define MCLD_TARGET_GNULDBACKEND_H
1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Target/TargetLDBackend.h>
125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Module.h>
1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/GNUArchiveReader.h>
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFDynObjReader.h>
16d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LD/ELFBinaryReader.h>
1787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFObjectReader.h>
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFObjectWriter.h>
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/ELF.h>
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
22a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#include <cstdint>
23a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines
2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaonamespace mcld {
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass Module;
2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass LinkerConfig;
28d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaoclass IRBuilder;
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass Layout;
3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass EhFrameHdr;
3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass BranchIslandFactory;
3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass StubFactory;
33d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaoclass GNUInfo;
3487f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFFileFormat;
3587f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFSegmentFactory;
3687f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFAttribute;
3787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFDynamic;
3887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFDynObjFileFormat;
3987f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFExecFileFormat;
4087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFObjectFileFormat;
4187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass LinkerScript;
4287f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass Relocation;
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/** \class GNULDBackend
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  \brief GNULDBackend provides a common interface for all GNU Unix-OS
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  LDBackend.
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass GNULDBackend : public TargetLDBackend
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprotected:
51d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo);
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual ~GNULDBackend();
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
56affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  readers/writers  ----- //
5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  GNUArchiveReader* createArchiveReader(Module& pModule);
58d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  ELFObjectReader* createObjectReader(IRBuilder& pBuilder);
59d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  ELFDynObjReader* createDynObjReader(IRBuilder& pBuilder);
60d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  ELFBinaryReader* createBinaryReader(IRBuilder& pBuilder);
616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFObjectWriter* createWriter();
62affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
63affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  output sections  ----- //
6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// initStdSections - initialize standard sections of the output file.
6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool initStdSections(ObjectBuilder& pBuilder);
66affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
67affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// getOutputFormat - get the sections of the output file.
6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const ELFFileFormat* getOutputFormat() const;
6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat*       getOutputFormat();
70affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
71affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  target symbols ----- //
72affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// initStandardSymbols - initialize standard symbols.
73affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// Some section symbols is undefined in input object, and linkers must set
74affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// up its value. Take __init_array_begin for example. This symbol is an
756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// undefined symbol in input objects. ObjectLinker must finalize its value
76affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// to the begin of the .init_array section, then relocation enties to
77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// __init_array_begin can be applied without emission of "undefined
78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// reference to `__init_array_begin'".
796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool initStandardSymbols(IRBuilder& pBuilder, Module& pModule);
80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// finalizeSymbol - Linker checks pSymbol.reserved() if it's not zero,
82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// then it will ask backend to finalize the symbol value.
83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @return ture - if backend set the symbol value sucessfully
84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @return false - if backend do not recognize the symbol
856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool finalizeSymbols() {
866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return (finalizeStandardSymbols() &&
876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            finalizeTargetSymbols());
88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// finalizeStandardSymbols - set the value of standard symbols
916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual bool finalizeStandardSymbols();
92affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
93affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// finalizeTargetSymbols - set the value of target symbols
946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual bool finalizeTargetSymbols() = 0;
9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// finalizeTLSSymbol - set the value of a TLS symbol
9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual bool finalizeTLSSymbol(LDSymbol& pSymbol);
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t sectionStartOffset() const;
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
101d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  const GNUInfo& getInfo() const { return *m_pInfo; }
102d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  GNUInfo&       getInfo()       { return *m_pInfo; }
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool hasTextRel() const { return m_bHasTextRel; }
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool hasStaticTLS() const { return m_bHasStaticTLS; }
10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
108f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// getSegmentStartAddr - this function returns the start address of the segment
109f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  uint64_t getSegmentStartAddr(const LinkerScript& pScript) const;
110affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
11187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// sizeShstrtab - compute the size of .shstrtab
11287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void sizeShstrtab(Module& pModule);
11387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// sizeNamePools - compute the size of regular name pools
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// In ELF executable files, regular name pools are .symtab, .strtab.,
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// .dynsym, .dynstr, and .hash
117f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  virtual void sizeNamePools(Module& pModule);
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitSectionData - emit target-dependent section data
12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual uint64_t emitSectionData(const LDSection& pSection,
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   MemoryRegion& pRegion) const = 0;
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitRegNamePools - emit regular name pools - .symtab, .strtab
12487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void emitRegNamePools(const Module& pModule, FileOutputBuffer& pOutput);
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
12787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void emitDynNamePools(Module& pModule, FileOutputBuffer& pOutput);
1286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// emitELFHashTab - emit .hash
1306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual void emitELFHashTab(const Module::SymbolTable& pSymtab,
13187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              FileOutputBuffer& pOutput);
1326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// emitGNUHashTab - emit .gnu.hash
1346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual void emitGNUHashTab(Module::SymbolTable& pSymtab,
13587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              FileOutputBuffer& pOutput);
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
137affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// sizeInterp - compute the size of program interpreter's name
138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// In ELF executables, this is the length of dynamic linker's path name
13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual void sizeInterp();
140affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
141affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// emitInterp - emit the .interp
14287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void emitInterp(FileOutputBuffer& pOutput);
143affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
144f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// hasEntryInStrTab - symbol has an entry in a .strtab
145f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  virtual bool hasEntryInStrTab(const LDSymbol& pSym) const;
146f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
147f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// orderSymbolTable - order symbol table before emitting
148f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  virtual void orderSymbolTable(Module& pModule);
149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
150f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void setHasStaticTLS(bool pVal = true)
151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  { m_bHasStaticTLS = pVal; }
152f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getSectionOrder - compute the layout order of the section
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// Layout calls this function to get the default order of the pSectHdr.
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// If the pSectHdr.type() is LDFileFormat::Target, then getSectionOrder()
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// will call getTargetSectionOrder().
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// If targets favors certain order for general sections, please override
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// this function.
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @see getTargetSectionOrder
16222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual unsigned int getSectionOrder(const LDSection& pSectHdr) const;
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getTargetSectionOrder - compute the layout order of target section
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// If the target favors certain order for the given gSectHdr, please
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// override this function.
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// By default, this function returns the maximun order, and pSectHdr
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// will be the last section to be laid out.
17022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return (unsigned int)-1; }
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
173affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// elfSegmentTable - return the reference of the elf segment table
17487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ELFSegmentFactory&       elfSegmentTable();
175affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
176affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// elfSegmentTable - return the reference of the elf segment table
17787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const ELFSegmentFactory& elfSegmentTable() const;
178affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// commonPageSize - the common page size of the target machine
1806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t commonPageSize() const;
181affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// abiPageSize - the abi page size of the target machine
1836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t abiPageSize() const;
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getSymbolIdx - get the symbol index of ouput symbol table
1866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t getSymbolIdx(const LDSymbol* pSymbol) const;
187affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
188affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// allocateCommonSymbols - allocate common symbols in the corresponding
189affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// sections.
190affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// Different concrete target backend may overlap this function.
19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual bool allocateCommonSymbols(Module& pModule);
192affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// updateSectionFlags - update pTo's flags when merging pFrom
1946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// update the output section flags based on input section flags.
1956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual bool updateSectionFlags(LDSection& pTo, const LDSection& pFrom);
1966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
19787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// readRelocation - read ELF32_Rel entry
19887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual bool readRelocation(const llvm::ELF::Elf32_Rel& pRel,
19987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pType,
20087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pSymIdx,
20187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pOffset) const;
20287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
20387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// readRelocation - read ELF32_Rela entry
20487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual bool readRelocation(const llvm::ELF::Elf32_Rela& pRel,
20587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pType,
20687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pSymIdx,
20787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pOffset,
20887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              int32_t& pAddend) const;
20987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
21087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// readRelocation - read ELF64_Rel entry
21187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual bool readRelocation(const llvm::ELF::Elf64_Rel& pRel,
21287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pType,
21387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pSymIdx,
21487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint64_t& pOffset) const;
21587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
21687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// readRel - read ELF64_Rela entry
21787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual bool readRelocation(const llvm::ELF::Elf64_Rela& pRel,
21887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pType,
21987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pSymIdx,
22087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint64_t& pOffset,
22187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              int64_t& pAddend) const;
22287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
22387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// emitRelocation - write data to the ELF32_Rel entry
22487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void emitRelocation(llvm::ELF::Elf32_Rel& pRel,
22587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pType,
22687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pSymIdx,
22787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pOffset) const;
22887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
22987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// emitRelocation - write data to the ELF32_Rela entry
23087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void emitRelocation(llvm::ELF::Elf32_Rela& pRel,
23187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pType,
23287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pSymIdx,
23387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pOffset,
23487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              int32_t pAddend) const;
23587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
23687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// emitRelocation - write data to the ELF64_Rel entry
23787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void emitRelocation(llvm::ELF::Elf64_Rel& pRel,
23887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pType,
23987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pSymIdx,
24087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint64_t pOffset) const;
24187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
24287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// emitRelocation - write data to the ELF64_Rela entry
24387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void emitRelocation(llvm::ELF::Elf64_Rela& pRel,
24487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pType,
24587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pSymIdx,
24687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint64_t pOffset,
24787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              int64_t pAddend) const;
24887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
249f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// symbolNeedsPLT - return whether the symbol needs a PLT entry
250f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// @ref Google gold linker, symtab.h:596
251f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool symbolNeedsPLT(const ResolveInfo& pSym) const;
252f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
253f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// symbolNeedsCopyReloc - return whether the symbol needs a copy relocation
254f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool symbolNeedsCopyReloc(const Relocation& pReloc,
255f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                            const ResolveInfo& pSym) const;
256f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
257f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// symbolNeedsDynRel - return whether the symbol needs a dynamic relocation
258f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// @ref Google gold linker, symtab.h:645
259f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool symbolNeedsDynRel(const ResolveInfo& pSym,
260f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                         bool pSymHasPLT,
261f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                         bool isAbsReloc) const;
262f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
263a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  /// isSymbolPreemptible - whether the symbol can be preemted by other link
264a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  /// units
265affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @ref Google gold linker, symtab.h:551
26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool isSymbolPreemptible(const ResolveInfo& pSym) const;
267affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
268f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// symbolHasFinalValue - return true if the symbol's value can be decided at
269f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// link time
270f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool symbolFinalValueIsKnown(const ResolveInfo& pSym) const;
271f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
272f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// isDynamicSymbol
273f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// @ref Google gold linker: symtab.cc:311
27487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool isDynamicSymbol(const LDSymbol& pSymbol) const;
275f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
276f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// isDynamicSymbol
277f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// @ref Google gold linker: symtab.cc:311
27887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool isDynamicSymbol(const ResolveInfo& pResolveInfo) const;
279f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
2806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual ResolveInfo::Desc getSymDesc(uint16_t pShndx) const {
2816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return ResolveInfo::Define;
2826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
284f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool hasTDATASymbol() const { return (NULL != f_pTDATA); }
285f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool hasTBSSSymbol()  const { return (NULL != f_pTBSS);  }
286f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
287f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void setTDATASymbol(LDSymbol& pTDATA) { f_pTDATA = &pTDATA; }
288f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void setTBSSSymbol(LDSymbol& pTBSS)   { f_pTBSS  = &pTBSS;  }
28967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // getTDATASymbol - get section symbol of .tdata
29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol& getTDATASymbol();
29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const LDSymbol& getTDATASymbol() const;
29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// getTBSSSymbol - get section symbol of .tbss
29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol& getTBSSSymbol();
29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const LDSymbol& getTBSSSymbol() const;
29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
29887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// getEntry - get the entry point name
29987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  llvm::StringRef getEntry(const Module& pModule) const;
30087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  //  -----  relaxation  -----  //
30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// initBRIslandFactory - initialize the branch island factory for relaxation
30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool initBRIslandFactory();
30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// initStubFactory - initialize the stub factory for relaxation
30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool initStubFactory();
30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// getBRIslandFactory
30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  BranchIslandFactory* getBRIslandFactory() { return m_pBRIslandFactory; }
31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// getStubFactory
31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  StubFactory*         getStubFactory()     { return m_pStubFactory; }
31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
314a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  /// maxFwdBranchOffset - return the max forward branch offset of the backend.
315a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  /// Target can override this function if needed.
316a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  virtual int64_t maxFwdBranchOffset() { return INT64_MAX; }
317a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines
318a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  /// maxBwdBranchOffset - return the max backward branch offset of the backend.
31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// Target can override this function if needed.
320a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  virtual int64_t maxBwdBranchOffset() { return 0; }
32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
322f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// checkAndSetHasTextRel - check pSection flag to set HasTextRel
323f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void checkAndSetHasTextRel(const LDSection& pSection);
324f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
32587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// sortRelocation - sort the dynamic relocations to let dynamic linker
32687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// process relocations more efficiently
32787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void sortRelocation(LDSection& pSection);
32887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
32987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// createAndSizeEhFrameHdr - This is seperated since we may add eh_frame
33087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// entry in the middle
33187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void createAndSizeEhFrameHdr(Module& pModule);
33287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
33387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// attribute - the attribute section data.
33487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ELFAttribute& attribute() { return *m_pAttribute; }
33587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
33687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// attribute - the attribute section data.
33787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const ELFAttribute& attribute() const { return *m_pAttribute; }
33887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
339a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  /// mayHaveUnsafeFunctionPointerAccess - check if the section may have unsafe
340a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  /// function pointer access
341a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  bool mayHaveUnsafeFunctionPointerAccess(const LDSection& pSection) const;
342a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines
343affc150dc44fab1911775a49636d0ce85333b634Zonr Changprotected:
34487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// getRelEntrySize - the size in BYTE of rel type relocation
34587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual size_t getRelEntrySize() = 0;
34687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
34787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// getRelEntrySize - the size in BYTE of rela type relocation
34887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual size_t getRelaEntrySize() = 0;
34987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
350affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t getSymbolSize(const LDSymbol& pSymbol) const;
351affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
352affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t getSymbolInfo(const LDSymbol& pSymbol) const;
353affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
354affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t getSymbolValue(const LDSymbol& pSymbol) const;
355affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
35622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t getSymbolShndx(const LDSymbol& pSymbol) const;
357affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
3586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// isTemporary - Whether pSymbol is a local label.
3596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual bool isTemporary(const LDSymbol& pSymbol) const;
3606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
361affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// getHashBucketCount - calculate hash bucket count.
362affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @ref Google gold linker, dynobj.cc:791
363affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  static unsigned getHashBucketCount(unsigned pNumOfSymbols, bool pIsGNUStyle);
364affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
3656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// getGNUHashMaskbitslog2 - calculate the number of mask bits in log2
3666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// @ref binutils gold, dynobj.cc:1165
3676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned getGNUHashMaskbitslog2(unsigned pNumOfSymbols) const;
3686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// emitSymbol32 - emit an ELF32 symbol
37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void emitSymbol32(llvm::ELF::Elf32_Sym& pSym32,
37122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    LDSymbol& pSymbol,
37222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    char* pStrtab,
37322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    size_t pStrtabsize,
37422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    size_t pSymtabIdx);
37522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
37622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// emitSymbol64 - emit an ELF64 symbol
37722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void emitSymbol64(llvm::ELF::Elf64_Sym& pSym64,
37822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    LDSymbol& pSymbol,
37922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    char* pStrtab,
38022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    size_t pStrtabsize,
38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    size_t pSymtabIdx);
38222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// createProgramHdrs - base on output sections to create the program headers
3856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void createProgramHdrs(Module& pModule);
38622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
38722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// doCreateProgramHdrs - backend can implement this function to create the
38822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// target-dependent segments
3896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual void doCreateProgramHdrs(Module& pModule) = 0;
3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
391affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// setupProgramHdrs - set up the attributes of segments
392affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ///  (i.e., offset, addresses, file/mem size, flag,  and alignment)
393f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void setupProgramHdrs(const LinkerScript& pScript);
3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getSegmentFlag - give a section flag and return the corresponding segment
3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// flag
39787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  inline uint32_t getSegmentFlag(const uint32_t pSectionFlag);
3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
39922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// setupGNUStackInfo - setup the section flag of .note.GNU-stack in output
4006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void setupGNUStackInfo(Module& pModule);
40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
40287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// setOutputSectionOffset - helper function to set output sections' offset.
40387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void setOutputSectionOffset(Module& pModule);
40422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
40587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// setOutputSectionAddress - helper function to set output sections' address.
40687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void setOutputSectionAddress(Module& pModule);
40722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
40887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// placeOutputSections - place output sections based on SectionMap
40987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void placeOutputSections(Module& pModule);
410affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
411d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  /// layout - layout method
4126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void layout(Module& pModule);
413d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// preLayout - Backend can do any needed modification before layout
4156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void preLayout(Module& pModule, IRBuilder& pBuilder);
4165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// postLayout -Backend can do any needed modification after layout
4186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void postLayout(Module& pModule, IRBuilder& pBuilder);
4195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// preLayout - Backend can do any needed modification before layout
4216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual void doPreLayout(IRBuilder& pBuilder) = 0;
4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// postLayout -Backend can do any needed modification after layout
4246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual void doPostLayout(Module& pModule, IRBuilder& pLinker) = 0;
4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
426affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// postProcessing - Backend can do any needed modification in the final stage
42787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void postProcessing(FileOutputBuffer& pOutput);
428affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// dynamic - the dynamic section of the target machine.
4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual ELFDynamic& dynamic() = 0;
4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// dynamic - the dynamic section of the target machine.
4335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual const ELFDynamic& dynamic() const = 0;
4345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
43522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// relax - the relaxation pass
4366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool relax(Module& pModule, IRBuilder& pBuilder);
43722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
43822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// mayRelax - Backends should override this function if they need relaxation
43922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual bool mayRelax() { return false; }
44022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
44122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// doRelax - Backend can orevride this function to add its relaxation
44222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// implementation. Return true if the output (e.g., .text) is "relaxed"
44322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// (i.e. layout is changed), and set pFinished to true if everything is fit,
44422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// otherwise set it to false.
4456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished)
44622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  { return false; }
44722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprotected:
449affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Based on Kind in LDFileFormat to define basic section orders for ELF, and
450affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // refer gold linker to add more enumerations to handle Regular and BSS kind
451affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  enum SectionOrder {
45287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_NULL = 0,        // NULL
45387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_INTERP,          // .interp
45487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_RO_NOTE,         // .note.ABI-tag, .note.gnu.build-id
45587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_NAMEPOOL,        // *.hash, .dynsym, .dynstr
45687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_RELOCATION,      // .rel.*, .rela.*
45787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_REL_PLT,         // .rel.plt should come after other .rel.*
45887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_INIT,            // .init
45987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_PLT,             // .plt
46087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_TEXT,            // .text
46187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_FINI,            // .fini
46287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_RO,              // .rodata
46387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_EXCEPTION,       // .eh_frame_hdr, .eh_frame, .gcc_except_table
46487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_TLS_DATA,        // .tdata
46587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_TLS_BSS,         // .tbss
46687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_RELRO_LOCAL,     // .data.rel.ro.local
46787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_RELRO,           // .data.rel.ro,
46887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_RELRO_LAST,      // for x86 to adjust .got if needed
46987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_NON_RELRO_FIRST, // for x86 to adjust .got.plt if needed
47087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_DATA,            // .data
47187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_LARGE_DATA,      // .ldata
47287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_RW_NOTE,         //
47387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_SMALL_DATA,      // .sdata
47487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_SMALL_BSS,       // .sbss
47587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_BSS,             // .bss
47687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_LARGE_BSS,       // .lbss
47787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_UNDEFINED,       // default order
47887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_STRTAB           // .strtab
479affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  };
480affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
48187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // for -z combreloc
48287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  struct RelocCompare
48322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  {
48487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    RelocCompare(const GNULDBackend& pBackend)
48587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      : m_Backend(pBackend) {
48687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
48787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    bool operator()(const Relocation* X, const Relocation* Y) const;
48887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  private:
48987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    const GNULDBackend& m_Backend;
49022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  };
49122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // for gnu style hash table
4936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  struct DynsymCompare
4946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  {
4956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    bool needGNUHash(const LDSymbol& X) const;
4966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    bool operator()(const LDSymbol* X, const LDSymbol* Y) const;
4986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  };
4996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
50087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  struct SymCompare
50187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  {
50287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    bool operator()(const LDSymbol* X, const LDSymbol* Y) const
50387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    { return (X==Y); }
50487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  };
50587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
50622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  struct SymPtrHash
50722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  {
50822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    size_t operator()(const LDSymbol* pKey) const
50922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    {
51022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return (unsigned((uintptr_t)pKey) >> 4) ^
51122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao             (unsigned((uintptr_t)pKey) >> 9);
51222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
51322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  };
51422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
51522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  typedef HashEntry<LDSymbol*, size_t, SymCompare> SymHashEntryType;
51622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  typedef HashTable<SymHashEntryType,
51722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    SymPtrHash,
51822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    EntryFactory<SymHashEntryType> > HashTableType;
51922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
520affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
521affc150dc44fab1911775a49636d0ce85333b634Zonr Changprotected:
5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFObjectReader* m_pObjectReader;
5235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // -----  file formats  ----- //
5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynObjFileFormat* m_pDynObjFileFormat;
52622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFExecFileFormat*   m_pExecFileFormat;
52722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFObjectFileFormat* m_pObjectFileFormat;
5285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
529d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // GNUInfo
530d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  GNUInfo* m_pInfo;
531d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
532affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // ELF segment factory
53387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ELFSegmentFactory* m_pELFSegmentTable;
5345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
53522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // branch island factory
53622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  BranchIslandFactory* m_pBRIslandFactory;
53722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
53822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // stub factory
53922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  StubFactory* m_pStubFactory;
54022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
541affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // map the LDSymbol to its index in the output symbol table
5425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  HashTableType* m_pSymIndexMap;
543affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // section .eh_frame_hdr
545affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  EhFrameHdr* m_pEhFrameHdr;
546affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
54787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // attribute section
54887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ELFAttribute* m_pAttribute;
54987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
55022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // ----- dynamic flags ----- //
55122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // DF_TEXTREL of DT_FLAGS
55222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool m_bHasTextRel;
55322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
55422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // DF_STATIC_TLS of DT_FLAGS
55522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool m_bHasStaticTLS;
55622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
557affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  standard symbols  ----- //
558affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // section symbols
559affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pPreInitArrayStart;
560affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pPreInitArrayEnd;
561affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pInitArrayStart;
562affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pInitArrayEnd;
563affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pFiniArrayStart;
564affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pFiniArrayEnd;
565affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pStack;
56622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol* f_pDynamic;
56722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
56822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // section symbols for .tdata and .tbss
56922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol* f_pTDATA;
57022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol* f_pTBSS;
571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // segment symbols
573affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pExecutableStart;
574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pEText;
575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_p_EText;
576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_p__EText;
577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pEData;
578affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_p_EData;
579affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pBSSStart;
580affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pEnd;
581affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_p_End;
5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
5855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
588