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//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#ifndef MCLD_TARGET_GNULDBACKEND_H_
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define MCLD_TARGET_GNULDBACKEND_H_
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Module.h"
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFBinaryReader.h"
1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFDynObjReader.h"
1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFObjectReader.h"
1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFObjectWriter.h"
1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/GNUArchiveReader.h"
1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/TargetLDBackend.h"
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/ELF.h>
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
220dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <cstdint>
230dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaonamespace mcld {
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass BranchIslandFactory;
2737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass EhFrameHdr;
2887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFAttribute;
2987f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFDynamic;
3087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFDynObjFileFormat;
3187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFExecFileFormat;
3237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass ELFFileFormat;
3387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFObjectFileFormat;
3437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass ELFSegmentFactory;
3537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass GNUInfo;
3637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass IRBuilder;
3737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass Layout;
3837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass LinkerConfig;
3987f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass LinkerScript;
4037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass Module;
4187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass Relocation;
4237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass StubFactory;
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 */
4837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass GNULDBackend : public TargetLDBackend {
4937b74a387bb3993387029859c2d9d051c41c724eStephen Hines protected:
50d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo);
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5237b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual ~GNULDBackend();
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
55affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  readers/writers  ----- //
5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  GNUArchiveReader* createArchiveReader(Module& pModule);
57d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  ELFObjectReader* createObjectReader(IRBuilder& pBuilder);
58d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  ELFDynObjReader* createDynObjReader(IRBuilder& pBuilder);
59d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  ELFBinaryReader* createBinaryReader(IRBuilder& pBuilder);
606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFObjectWriter* createWriter();
61affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
62affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  output sections  ----- //
6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// initStdSections - initialize standard sections of the output file.
6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool initStdSections(ObjectBuilder& pBuilder);
65affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
66affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// getOutputFormat - get the sections of the output file.
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const ELFFileFormat* getOutputFormat() const;
6837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  ELFFileFormat* getOutputFormat();
69affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
70affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  target symbols ----- //
71affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// initStandardSymbols - initialize standard symbols.
72affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// Some section symbols is undefined in input object, and linkers must set
73affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// up its value. Take __init_array_begin for example. This symbol is an
746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// undefined symbol in input objects. ObjectLinker must finalize its value
75affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// to the begin of the .init_array section, then relocation enties to
76affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// __init_array_begin can be applied without emission of "undefined
77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// reference to `__init_array_begin'".
786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool initStandardSymbols(IRBuilder& pBuilder, Module& pModule);
79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// finalizeSymbol - Linker checks pSymbol.reserved() if it's not zero,
81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// then it will ask backend to finalize the symbol value.
82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @return ture - if backend set the symbol value sucessfully
83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @return false - if backend do not recognize the symbol
846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool finalizeSymbols() {
8537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    return (finalizeStandardSymbols() && finalizeTargetSymbols());
86affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
87affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// finalizeStandardSymbols - set the value of standard symbols
896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual bool finalizeStandardSymbols();
90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
91affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// finalizeTargetSymbols - set the value of target symbols
926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual bool finalizeTargetSymbols() = 0;
9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// finalizeTLSSymbol - set the value of a TLS symbol
9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual bool finalizeTLSSymbol(LDSymbol& pSymbol);
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t sectionStartOffset() const;
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
99d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  const GNUInfo& getInfo() const { return *m_pInfo; }
10037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  GNUInfo& getInfo() { return *m_pInfo; }
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool hasTextRel() const { return m_bHasTextRel; }
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool hasStaticTLS() const { return m_bHasStaticTLS; }
10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  /// getSegmentStartAddr - return the start address of the segment
107f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  uint64_t getSegmentStartAddr(const LinkerScript& pScript) const;
108affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
10987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// sizeShstrtab - compute the size of .shstrtab
11087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void sizeShstrtab(Module& pModule);
11187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// sizeNamePools - compute the size of regular name pools
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// In ELF executable files, regular name pools are .symtab, .strtab.,
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// .dynsym, .dynstr, and .hash
115f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  virtual void sizeNamePools(Module& pModule);
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitSectionData - emit target-dependent section data
11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual uint64_t emitSectionData(const LDSection& pSection,
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   MemoryRegion& pRegion) const = 0;
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitRegNamePools - emit regular name pools - .symtab, .strtab
12237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  virtual void emitRegNamePools(const Module& pModule,
12337b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                FileOutputBuffer& pOutput);
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
12687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void emitDynNamePools(Module& pModule, FileOutputBuffer& pOutput);
1276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// emitELFHashTab - emit .hash
1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual void emitELFHashTab(const Module::SymbolTable& pSymtab,
13087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              FileOutputBuffer& pOutput);
1316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// emitGNUHashTab - emit .gnu.hash
1336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual void emitGNUHashTab(Module::SymbolTable& pSymtab,
13487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              FileOutputBuffer& pOutput);
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
136affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// sizeInterp - compute the size of program interpreter's name
137affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// In ELF executables, this is the length of dynamic linker's path name
13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual void sizeInterp();
139affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
140affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// emitInterp - emit the .interp
14187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void emitInterp(FileOutputBuffer& pOutput);
142affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
143f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// hasEntryInStrTab - symbol has an entry in a .strtab
144f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  virtual bool hasEntryInStrTab(const LDSymbol& pSym) const;
145f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
146f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// orderSymbolTable - order symbol table before emitting
147f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  virtual void orderSymbolTable(Module& pModule);
148f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
14937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  void setHasStaticTLS(bool pVal = true) { m_bHasStaticTLS = pVal; }
150f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getSectionOrder - compute the layout order of the section
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// Layout calls this function to get the default order of the pSectHdr.
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// If the pSectHdr.type() is LDFileFormat::Target, then getSectionOrder()
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// will call getTargetSectionOrder().
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// If targets favors certain order for general sections, please override
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// this function.
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @see getTargetSectionOrder
16022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual unsigned int getSectionOrder(const LDSection& pSectHdr) const;
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getTargetSectionOrder - compute the layout order of target section
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// If the target favors certain order for the given gSectHdr, please
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// override this function.
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// By default, this function returns the maximun order, and pSectHdr
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// will be the last section to be laid out.
16837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  virtual unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const {
16937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    return (unsigned int)-1;
17037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
172affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// elfSegmentTable - return the reference of the elf segment table
17337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  ELFSegmentFactory& elfSegmentTable();
174affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
175affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// elfSegmentTable - return the reference of the elf segment table
17687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const ELFSegmentFactory& elfSegmentTable() const;
177affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// commonPageSize - the common page size of the target machine
1796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t commonPageSize() const;
180affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// abiPageSize - the abi page size of the target machine
1826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t abiPageSize() const;
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getSymbolIdx - get the symbol index of ouput symbol table
1856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t getSymbolIdx(const LDSymbol* pSymbol) const;
186affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
187affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// allocateCommonSymbols - allocate common symbols in the corresponding
188affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// sections.
189affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// Different concrete target backend may overlap this function.
19022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual bool allocateCommonSymbols(Module& pModule);
191affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
192cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines  /// mergeFlags - update set of ELF header flags
193cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines  virtual void mergeFlags(Input& pInput, const char* ELF_hdr) {}
194cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines
1956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// updateSectionFlags - update pTo's flags when merging pFrom
1966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// update the output section flags based on input section flags.
1976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual bool updateSectionFlags(LDSection& pTo, const LDSection& pFrom);
1986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
19987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// readRelocation - read ELF32_Rel entry
20087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual bool readRelocation(const llvm::ELF::Elf32_Rel& pRel,
20187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pType,
20287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pSymIdx,
20387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pOffset) const;
20487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
20587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// readRelocation - read ELF32_Rela entry
20687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual bool readRelocation(const llvm::ELF::Elf32_Rela& pRel,
20787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pType,
20887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pSymIdx,
20987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pOffset,
21087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              int32_t& pAddend) const;
21187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
21287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// readRelocation - read ELF64_Rel entry
21387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual bool readRelocation(const llvm::ELF::Elf64_Rel& pRel,
21487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pType,
21587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pSymIdx,
21687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint64_t& pOffset) const;
21787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
21887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// readRel - read ELF64_Rela entry
21987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual bool readRelocation(const llvm::ELF::Elf64_Rela& pRel,
22087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pType,
22187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pSymIdx,
22287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint64_t& pOffset,
22387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              int64_t& pAddend) const;
22487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
22587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// emitRelocation - write data to the ELF32_Rel entry
22687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void emitRelocation(llvm::ELF::Elf32_Rel& pRel,
22787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pType,
22887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pSymIdx,
22987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pOffset) const;
23087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
23187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// emitRelocation - write data to the ELF32_Rela entry
23287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void emitRelocation(llvm::ELF::Elf32_Rela& pRel,
23387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pType,
23487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pSymIdx,
23587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pOffset,
23687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              int32_t pAddend) const;
23787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
23887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// emitRelocation - write data to the ELF64_Rel entry
23987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void emitRelocation(llvm::ELF::Elf64_Rel& pRel,
24087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pType,
24187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pSymIdx,
24287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint64_t pOffset) const;
24387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
24487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// emitRelocation - write data to the ELF64_Rela entry
24587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void emitRelocation(llvm::ELF::Elf64_Rela& pRel,
24687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pType,
24787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pSymIdx,
24887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint64_t pOffset,
24987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              int64_t pAddend) const;
25087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
251f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// symbolNeedsPLT - return whether the symbol needs a PLT entry
252f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool symbolNeedsPLT(const ResolveInfo& pSym) const;
253f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
254f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// symbolNeedsCopyReloc - return whether the symbol needs a copy relocation
255f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool symbolNeedsCopyReloc(const Relocation& pReloc,
256f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                            const ResolveInfo& pSym) const;
257f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
258f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// symbolNeedsDynRel - return whether the symbol needs a dynamic relocation
259f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool symbolNeedsDynRel(const ResolveInfo& pSym,
260f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                         bool pSymHasPLT,
261f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                         bool isAbsReloc) const;
262f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
2630dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  /// isSymbolPreemptible - whether the symbol can be preemted by other link
2640dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  /// units
26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool isSymbolPreemptible(const ResolveInfo& pSym) const;
266affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
267f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// symbolHasFinalValue - return true if the symbol's value can be decided at
268f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// link time
269f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool symbolFinalValueIsKnown(const ResolveInfo& pSym) const;
270f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
271f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// isDynamicSymbol
27287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool isDynamicSymbol(const LDSymbol& pSymbol) const;
273f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
274f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// isDynamicSymbol
27587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool isDynamicSymbol(const ResolveInfo& pResolveInfo) const;
276f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
2776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual ResolveInfo::Desc getSymDesc(uint16_t pShndx) const {
2786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return ResolveInfo::Define;
2796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
28137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  bool hasTDATASymbol() const { return (f_pTDATA != NULL); }
28237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  bool hasTBSSSymbol() const { return (f_pTBSS != NULL); }
283f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
284f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void setTDATASymbol(LDSymbol& pTDATA) { f_pTDATA = &pTDATA; }
28537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  void setTBSSSymbol(LDSymbol& pTBSS) { f_pTBSS = &pTBSS; }
28667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
28722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // getTDATASymbol - get section symbol of .tdata
28822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol& getTDATASymbol();
28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const LDSymbol& getTDATASymbol() const;
29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// getTBSSSymbol - get section symbol of .tbss
29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol& getTBSSSymbol();
29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const LDSymbol& getTBSSSymbol() const;
29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
29587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// getEntry - get the entry point name
29687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  llvm::StringRef getEntry(const Module& pModule) const;
29787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  //  -----  relaxation  -----  //
29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// initBRIslandFactory - initialize the branch island factory for relaxation
30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool initBRIslandFactory();
30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// initStubFactory - initialize the stub factory for relaxation
30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool initStubFactory();
30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// getBRIslandFactory
30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  BranchIslandFactory* getBRIslandFactory() { return m_pBRIslandFactory; }
30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// getStubFactory
30937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  StubFactory* getStubFactory() { return m_pStubFactory; }
31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3110dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  /// maxFwdBranchOffset - return the max forward branch offset of the backend.
3120dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  /// Target can override this function if needed.
313cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines  virtual int64_t maxFwdBranchOffset() const { return INT64_MAX; }
3140dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
3150dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  /// maxBwdBranchOffset - return the max backward branch offset of the backend.
31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// Target can override this function if needed.
317cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines  virtual int64_t maxBwdBranchOffset() const { return 0; }
318cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines
319cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines  /// stubGroupSize - return the group size to place stubs between sections.
320cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines  virtual unsigned stubGroupSize() const;
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
3390dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  /// mayHaveUnsafeFunctionPointerAccess - check if the section may have unsafe
3400dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  /// function pointer access
3410dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  bool mayHaveUnsafeFunctionPointerAccess(const LDSection& pSection) const;
3420dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
34337b74a387bb3993387029859c2d9d051c41c724eStephen Hines protected:
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  static unsigned getHashBucketCount(unsigned pNumOfSymbols, bool pIsGNUStyle);
363affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
3646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// getGNUHashMaskbitslog2 - calculate the number of mask bits in log2
3656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned getGNUHashMaskbitslog2(unsigned pNumOfSymbols) const;
3666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
36722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// emitSymbol32 - emit an ELF32 symbol
36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void emitSymbol32(llvm::ELF::Elf32_Sym& pSym32,
36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    LDSymbol& pSymbol,
37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    char* pStrtab,
37122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    size_t pStrtabsize,
37222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    size_t pSymtabIdx);
37322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
37422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// emitSymbol64 - emit an ELF64 symbol
37522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void emitSymbol64(llvm::ELF::Elf64_Sym& pSym64,
37622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    LDSymbol& pSymbol,
37722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    char* pStrtab,
37822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    size_t pStrtabsize,
37922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    size_t pSymtabIdx);
38022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
381a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines protected:
3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// createProgramHdrs - base on output sections to create the program headers
3836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void createProgramHdrs(Module& pModule);
38422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
38522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// doCreateProgramHdrs - backend can implement this function to create the
38622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// target-dependent segments
3876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual void doCreateProgramHdrs(Module& pModule) = 0;
3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
389affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// setupProgramHdrs - set up the attributes of segments
390affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ///  (i.e., offset, addresses, file/mem size, flag,  and alignment)
391f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void setupProgramHdrs(const LinkerScript& pScript);
3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getSegmentFlag - give a section flag and return the corresponding segment
3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// flag
39587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  inline uint32_t getSegmentFlag(const uint32_t pSectionFlag);
3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
39722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// setupGNUStackInfo - setup the section flag of .note.GNU-stack in output
3986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void setupGNUStackInfo(Module& pModule);
39922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
40087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// setOutputSectionOffset - helper function to set output sections' offset.
40187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void setOutputSectionOffset(Module& pModule);
40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
40387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// setOutputSectionAddress - helper function to set output sections' address.
40487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void setOutputSectionAddress(Module& pModule);
40522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
40687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// placeOutputSections - place output sections based on SectionMap
40787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void placeOutputSections(Module& pModule);
408affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
409d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  /// layout - layout method
4106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void layout(Module& pModule);
411d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// preLayout - Backend can do any needed modification before layout
4136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void preLayout(Module& pModule, IRBuilder& pBuilder);
4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// postLayout -Backend can do any needed modification after layout
4166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void postLayout(Module& pModule, IRBuilder& pBuilder);
4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// preLayout - Backend can do any needed modification before layout
4196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual void doPreLayout(IRBuilder& pBuilder) = 0;
4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// postLayout -Backend can do any needed modification after layout
4226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual void doPostLayout(Module& pModule, IRBuilder& pLinker) = 0;
4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
424affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// postProcessing - Backend can do any needed modification in the final stage
42587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void postProcessing(FileOutputBuffer& pOutput);
426affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// dynamic - the dynamic section of the target machine.
4285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual ELFDynamic& dynamic() = 0;
4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// dynamic - the dynamic section of the target machine.
4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual const ELFDynamic& dynamic() const = 0;
4325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
43322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// relax - the relaxation pass
434a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines  virtual bool relax(Module& pModule, IRBuilder& pBuilder);
43522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
43622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// mayRelax - Backends should override this function if they need relaxation
43722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual bool mayRelax() { return false; }
43822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
43922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// doRelax - Backend can orevride this function to add its relaxation
44022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// implementation. Return true if the output (e.g., .text) is "relaxed"
44122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// (i.e. layout is changed), and set pFinished to true if everything is fit,
44222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// otherwise set it to false.
44337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  virtual bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished) {
44437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    return false;
44537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }
44622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
44737b74a387bb3993387029859c2d9d051c41c724eStephen Hines protected:
44837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  // Based on Kind in LDFileFormat to define basic section orders for ELF.
449affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  enum SectionOrder {
45037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_NULL = 0,         // NULL
45137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_INTERP,           // .interp
45237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_RO_NOTE,          // .note.ABI-tag, .note.gnu.build-id
45337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_NAMEPOOL,         // *.hash, .dynsym, .dynstr
45437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_RELOCATION,       // .rel.*, .rela.*
45537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_REL_PLT,          // .rel.plt should come after other .rel.*
45637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_INIT,             // .init
45737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_PLT,              // .plt
45837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_TEXT,             // .text
45937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_FINI,             // .fini
46037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_RO,               // .rodata
46137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_EXCEPTION,        // .eh_frame_hdr, .eh_frame, .gcc_except_table
46237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_TLS_DATA,         // .tdata
46337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_TLS_BSS,          // .tbss
46437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_RELRO_LOCAL,      // .data.rel.ro.local
46537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_RELRO,            // .data.rel.ro,
46637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_RELRO_LAST,       // for x86 to adjust .got if needed
46737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_NON_RELRO_FIRST,  // for x86 to adjust .got.plt if needed
46837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_DATA,             // .data
46937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_LARGE_DATA,       // .ldata
47037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_RW_NOTE,          //
47137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_SMALL_DATA,       // .sdata
47237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_SMALL_BSS,        // .sbss
47337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_BSS,              // .bss
47437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_LARGE_BSS,        // .lbss
47537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_UNDEFINED,        // default order
47637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    SHO_STRTAB            // .strtab
477affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  };
478affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
47987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // for -z combreloc
48037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  struct RelocCompare {
48137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    explicit RelocCompare(const GNULDBackend& pBackend) : m_Backend(pBackend) {}
482a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines    bool operator()(const Relocation& X, const Relocation& Y) const;
48337b74a387bb3993387029859c2d9d051c41c724eStephen Hines
48437b74a387bb3993387029859c2d9d051c41c724eStephen Hines   private:
48587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    const GNULDBackend& m_Backend;
48622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  };
48722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // for gnu style hash table
48937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  struct DynsymCompare {
4906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    bool needGNUHash(const LDSymbol& X) const;
4916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    bool operator()(const LDSymbol* X, const LDSymbol* Y) const;
4936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  };
4946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
49537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  struct SymCompare {
49637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    bool operator()(const LDSymbol* X, const LDSymbol* Y) const {
49737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      return (X == Y);
49837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    }
49987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  };
50087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
50137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  struct SymPtrHash {
50237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    size_t operator()(const LDSymbol* pKey) const {
50322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return (unsigned((uintptr_t)pKey) >> 4) ^
50422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao             (unsigned((uintptr_t)pKey) >> 9);
50522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
50622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  };
50722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
50822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  typedef HashEntry<LDSymbol*, size_t, SymCompare> SymHashEntryType;
50922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  typedef HashTable<SymHashEntryType,
51022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    SymPtrHash,
51122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    EntryFactory<SymHashEntryType> > HashTableType;
51222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
51337b74a387bb3993387029859c2d9d051c41c724eStephen Hines protected:
5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFObjectReader* m_pObjectReader;
5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // -----  file formats  ----- //
5175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynObjFileFormat* m_pDynObjFileFormat;
51837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  ELFExecFileFormat* m_pExecFileFormat;
51922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFObjectFileFormat* m_pObjectFileFormat;
5205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
521d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // GNUInfo
522d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  GNUInfo* m_pInfo;
523d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
524affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // ELF segment factory
52587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ELFSegmentFactory* m_pELFSegmentTable;
5265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
52722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // branch island factory
52822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  BranchIslandFactory* m_pBRIslandFactory;
52922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
53022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // stub factory
53122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  StubFactory* m_pStubFactory;
53222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
533affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // map the LDSymbol to its index in the output symbol table
5345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  HashTableType* m_pSymIndexMap;
535affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
536affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // section .eh_frame_hdr
537affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  EhFrameHdr* m_pEhFrameHdr;
538affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
53987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // attribute section
54087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ELFAttribute* m_pAttribute;
54187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
54222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // ----- dynamic flags ----- //
54322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // DF_TEXTREL of DT_FLAGS
54422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool m_bHasTextRel;
54522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
54622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // DF_STATIC_TLS of DT_FLAGS
54722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool m_bHasStaticTLS;
54822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
549affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  standard symbols  ----- //
550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // section symbols
551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pPreInitArrayStart;
552affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pPreInitArrayEnd;
553affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pInitArrayStart;
554affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pInitArrayEnd;
555affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pFiniArrayStart;
556affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pFiniArrayEnd;
557affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pStack;
55822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol* f_pDynamic;
55922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
56022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // section symbols for .tdata and .tbss
56122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol* f_pTDATA;
56222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol* f_pTBSS;
563affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
564affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // segment symbols
565affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pExecutableStart;
566affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pEText;
567affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_p_EText;
568affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_p__EText;
569affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pEData;
570affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_p_EData;
571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pBSSStart;
572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pEnd;
573affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_p_End;
5745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
5755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
57637b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
5775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
57837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#endif  // MCLD_TARGET_GNULDBACKEND_H_
579