GNULDBackend.h revision 87f34658dec9097d987d254a990ea7f311bfc95f
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
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#ifdef ENABLE_UNITTEST
125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <gtest.h>
135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Target/TargetLDBackend.h>
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Module.h>
1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/GNUArchiveReader.h>
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFDynObjReader.h>
19d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LD/ELFBinaryReader.h>
2087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFObjectReader.h>
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFObjectWriter.h>
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/ELF.h>
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaonamespace mcld {
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass Module;
2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass LinkerConfig;
29d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaoclass IRBuilder;
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass Layout;
3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass EhFrameHdr;
3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass BranchIslandFactory;
3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass StubFactory;
34d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaoclass GNUInfo;
3587f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFFileFormat;
3687f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFSegmentFactory;
3787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFAttribute;
3887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFDynamic;
3987f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFDynObjFileFormat;
4087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFExecFileFormat;
4187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFObjectFileFormat;
4287f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass LinkerScript;
4387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass Relocation;
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/** \class GNULDBackend
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  \brief GNULDBackend provides a common interface for all GNU Unix-OS
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  LDBackend.
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass GNULDBackend : public TargetLDBackend
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprotected:
52d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo);
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual ~GNULDBackend();
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
57affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  readers/writers  ----- //
5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  GNUArchiveReader* createArchiveReader(Module& pModule);
59d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  ELFObjectReader* createObjectReader(IRBuilder& pBuilder);
60d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  ELFDynObjReader* createDynObjReader(IRBuilder& pBuilder);
61d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  ELFBinaryReader* createBinaryReader(IRBuilder& pBuilder);
626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFObjectWriter* createWriter();
63affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
64affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  output sections  ----- //
6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// initStdSections - initialize standard sections of the output file.
6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool initStdSections(ObjectBuilder& pBuilder);
67affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
68affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// getOutputFormat - get the sections of the output file.
6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const ELFFileFormat* getOutputFormat() const;
7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat*       getOutputFormat();
71affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
72affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  target symbols ----- //
73affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// initStandardSymbols - initialize standard symbols.
74affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// Some section symbols is undefined in input object, and linkers must set
75affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// up its value. Take __init_array_begin for example. This symbol is an
766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// undefined symbol in input objects. ObjectLinker must finalize its value
77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// to the begin of the .init_array section, then relocation enties to
78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// __init_array_begin can be applied without emission of "undefined
79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// reference to `__init_array_begin'".
806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool initStandardSymbols(IRBuilder& pBuilder, Module& pModule);
81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// finalizeSymbol - Linker checks pSymbol.reserved() if it's not zero,
83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// then it will ask backend to finalize the symbol value.
84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @return ture - if backend set the symbol value sucessfully
85affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @return false - if backend do not recognize the symbol
866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool finalizeSymbols() {
876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return (finalizeStandardSymbols() &&
886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            finalizeTargetSymbols());
89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
91affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// finalizeStandardSymbols - set the value of standard symbols
926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual bool finalizeStandardSymbols();
93affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
94affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// finalizeTargetSymbols - set the value of target symbols
956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual bool finalizeTargetSymbols() = 0;
9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// finalizeTLSSymbol - set the value of a TLS symbol
9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual bool finalizeTLSSymbol(LDSymbol& pSymbol);
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t sectionStartOffset() const;
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
102d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  const GNUInfo& getInfo() const { return *m_pInfo; }
103d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  GNUInfo&       getInfo()       { return *m_pInfo; }
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool hasTextRel() const { return m_bHasTextRel; }
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool hasStaticTLS() const { return m_bHasStaticTLS; }
10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
109f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// getSegmentStartAddr - this function returns the start address of the segment
110f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  uint64_t getSegmentStartAddr(const LinkerScript& pScript) const;
111affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
11287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// sizeShstrtab - compute the size of .shstrtab
11387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void sizeShstrtab(Module& pModule);
11487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// sizeNamePools - compute the size of regular name pools
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// In ELF executable files, regular name pools are .symtab, .strtab.,
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// .dynsym, .dynstr, and .hash
118f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  virtual void sizeNamePools(Module& pModule);
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitSectionData - emit target-dependent section data
12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual uint64_t emitSectionData(const LDSection& pSection,
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   MemoryRegion& pRegion) const = 0;
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitRegNamePools - emit regular name pools - .symtab, .strtab
12587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void emitRegNamePools(const Module& pModule, FileOutputBuffer& pOutput);
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
12887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void emitDynNamePools(Module& pModule, FileOutputBuffer& pOutput);
1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// emitELFHashTab - emit .hash
1316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual void emitELFHashTab(const Module::SymbolTable& pSymtab,
13287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              FileOutputBuffer& pOutput);
1336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// emitGNUHashTab - emit .gnu.hash
1356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual void emitGNUHashTab(Module::SymbolTable& pSymtab,
13687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              FileOutputBuffer& pOutput);
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// sizeInterp - compute the size of program interpreter's name
139affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// In ELF executables, this is the length of dynamic linker's path name
14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual void sizeInterp();
141affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
142affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// emitInterp - emit the .interp
14387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void emitInterp(FileOutputBuffer& pOutput);
144affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
145f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// hasEntryInStrTab - symbol has an entry in a .strtab
146f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  virtual bool hasEntryInStrTab(const LDSymbol& pSym) const;
147f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
148f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// orderSymbolTable - order symbol table before emitting
149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  virtual void orderSymbolTable(Module& pModule);
150f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void setHasStaticTLS(bool pVal = true)
152f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  { m_bHasStaticTLS = pVal; }
153f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getSectionOrder - compute the layout order of the section
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// Layout calls this function to get the default order of the pSectHdr.
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// If the pSectHdr.type() is LDFileFormat::Target, then getSectionOrder()
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// will call getTargetSectionOrder().
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// If targets favors certain order for general sections, please override
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// this function.
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @see getTargetSectionOrder
16322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual unsigned int getSectionOrder(const LDSection& pSectHdr) const;
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getTargetSectionOrder - compute the layout order of target section
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// If the target favors certain order for the given gSectHdr, please
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// override this function.
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// By default, this function returns the maximun order, and pSectHdr
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// will be the last section to be laid out.
17122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return (unsigned int)-1; }
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
174affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// elfSegmentTable - return the reference of the elf segment table
17587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ELFSegmentFactory&       elfSegmentTable();
176affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
177affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// elfSegmentTable - return the reference of the elf segment table
17887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const ELFSegmentFactory& elfSegmentTable() const;
179affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// commonPageSize - the common page size of the target machine
1816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t commonPageSize() const;
182affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// abiPageSize - the abi page size of the target machine
1846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t abiPageSize() const;
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getSymbolIdx - get the symbol index of ouput symbol table
1876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t getSymbolIdx(const LDSymbol* pSymbol) const;
188affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
189affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// allocateCommonSymbols - allocate common symbols in the corresponding
190affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// sections.
191affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// Different concrete target backend may overlap this function.
19222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual bool allocateCommonSymbols(Module& pModule);
193affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// updateSectionFlags - update pTo's flags when merging pFrom
1956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// update the output section flags based on input section flags.
1966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual bool updateSectionFlags(LDSection& pTo, const LDSection& pFrom);
1976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
19887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// readRelocation - read ELF32_Rel entry
19987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual bool readRelocation(const llvm::ELF::Elf32_Rel& pRel,
20087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pType,
20187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pSymIdx,
20287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pOffset) const;
20387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
20487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// readRelocation - read ELF32_Rela entry
20587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual bool readRelocation(const llvm::ELF::Elf32_Rela& pRel,
20687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pType,
20787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pSymIdx,
20887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pOffset,
20987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              int32_t& pAddend) const;
21087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
21187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// readRelocation - read ELF64_Rel entry
21287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual bool readRelocation(const llvm::ELF::Elf64_Rel& pRel,
21387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pType,
21487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pSymIdx,
21587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint64_t& pOffset) const;
21687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
21787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// readRel - read ELF64_Rela entry
21887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual bool readRelocation(const llvm::ELF::Elf64_Rela& pRel,
21987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pType,
22087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t& pSymIdx,
22187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint64_t& pOffset,
22287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              int64_t& pAddend) const;
22387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
22487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// emitRelocation - write data to the ELF32_Rel entry
22587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void emitRelocation(llvm::ELF::Elf32_Rel& pRel,
22687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pType,
22787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pSymIdx,
22887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pOffset) const;
22987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
23087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// emitRelocation - write data to the ELF32_Rela entry
23187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void emitRelocation(llvm::ELF::Elf32_Rela& pRel,
23287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pType,
23387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pSymIdx,
23487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pOffset,
23587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              int32_t pAddend) const;
23687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
23787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// emitRelocation - write data to the ELF64_Rel entry
23887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void emitRelocation(llvm::ELF::Elf64_Rel& pRel,
23987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pType,
24087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pSymIdx,
24187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint64_t pOffset) const;
24287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
24387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// emitRelocation - write data to the ELF64_Rela entry
24487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual void emitRelocation(llvm::ELF::Elf64_Rela& pRel,
24587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pType,
24687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint32_t pSymIdx,
24787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              uint64_t pOffset,
24887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                              int64_t pAddend) const;
24987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
250f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// symbolNeedsPLT - return whether the symbol needs a PLT entry
251f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// @ref Google gold linker, symtab.h:596
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  /// @ref Google gold linker, symtab.h:645
260f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool symbolNeedsDynRel(const ResolveInfo& pSym,
261f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                         bool pSymHasPLT,
262f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                         bool isAbsReloc) const;
263f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
264affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// isSymbolPreemtible - whether the symbol can be preemted by other
265affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// link unit
266affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @ref Google gold linker, symtab.h:551
26722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool isSymbolPreemptible(const ResolveInfo& pSym) const;
268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
269f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// symbolHasFinalValue - return true if the symbol's value can be decided at
270f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// link time
271f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool symbolFinalValueIsKnown(const ResolveInfo& pSym) const;
272f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
273f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// isDynamicSymbol
274f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// @ref Google gold linker: symtab.cc:311
27587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool isDynamicSymbol(const LDSymbol& pSymbol) const;
276f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
277f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// isDynamicSymbol
278f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// @ref Google gold linker: symtab.cc:311
27987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  bool isDynamicSymbol(const ResolveInfo& pResolveInfo) const;
280f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
2816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual ResolveInfo::Desc getSymDesc(uint16_t pShndx) const {
2826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return ResolveInfo::Define;
2836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
285f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool hasTDATASymbol() const { return (NULL != f_pTDATA); }
286f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  bool hasTBSSSymbol()  const { return (NULL != f_pTBSS);  }
287f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
288f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void setTDATASymbol(LDSymbol& pTDATA) { f_pTDATA = &pTDATA; }
289f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void setTBSSSymbol(LDSymbol& pTBSS)   { f_pTBSS  = &pTBSS;  }
29067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // getTDATASymbol - get section symbol of .tdata
29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol& getTDATASymbol();
29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const LDSymbol& getTDATASymbol() const;
29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// getTBSSSymbol - get section symbol of .tbss
29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol& getTBSSSymbol();
29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const LDSymbol& getTBSSSymbol() const;
29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
29987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// getEntry - get the entry point name
30087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  llvm::StringRef getEntry(const Module& pModule) const;
30187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  //  -----  relaxation  -----  //
30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// initBRIslandFactory - initialize the branch island factory for relaxation
30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool initBRIslandFactory();
30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// initStubFactory - initialize the stub factory for relaxation
30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool initStubFactory();
30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// getBRIslandFactory
31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  BranchIslandFactory* getBRIslandFactory() { return m_pBRIslandFactory; }
31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// getStubFactory
31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  StubFactory*         getStubFactory()     { return m_pStubFactory; }
31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// maxBranchOffset - return the max (forward) branch offset of the backend.
31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// Target can override this function if needed.
31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual uint64_t maxBranchOffset() { return (uint64_t)-1; }
31822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
319f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  /// checkAndSetHasTextRel - check pSection flag to set HasTextRel
320f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void checkAndSetHasTextRel(const LDSection& pSection);
321f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
32287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// sortRelocation - sort the dynamic relocations to let dynamic linker
32387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// process relocations more efficiently
32487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void sortRelocation(LDSection& pSection);
32587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
32687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// createAndSizeEhFrameHdr - This is seperated since we may add eh_frame
32787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// entry in the middle
32887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void createAndSizeEhFrameHdr(Module& pModule);
32987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
33087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// attribute - the attribute section data.
33187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ELFAttribute& attribute() { return *m_pAttribute; }
33287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
33387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// attribute - the attribute section data.
33487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const ELFAttribute& attribute() const { return *m_pAttribute; }
33587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
336affc150dc44fab1911775a49636d0ce85333b634Zonr Changprotected:
33787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// getRelEntrySize - the size in BYTE of rel type relocation
33887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual size_t getRelEntrySize() = 0;
33987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
34087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// getRelEntrySize - the size in BYTE of rela type relocation
34187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  virtual size_t getRelaEntrySize() = 0;
34287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
343affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t getSymbolSize(const LDSymbol& pSymbol) const;
344affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
345affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t getSymbolInfo(const LDSymbol& pSymbol) const;
346affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
347affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t getSymbolValue(const LDSymbol& pSymbol) const;
348affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
34922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t getSymbolShndx(const LDSymbol& pSymbol) const;
350affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
3516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// isTemporary - Whether pSymbol is a local label.
3526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual bool isTemporary(const LDSymbol& pSymbol) const;
3536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
354affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// getHashBucketCount - calculate hash bucket count.
355affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @ref Google gold linker, dynobj.cc:791
356affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  static unsigned getHashBucketCount(unsigned pNumOfSymbols, bool pIsGNUStyle);
357affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
3586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// getGNUHashMaskbitslog2 - calculate the number of mask bits in log2
3596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  /// @ref binutils gold, dynobj.cc:1165
3606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned getGNUHashMaskbitslog2(unsigned pNumOfSymbols) const;
3616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// emitSymbol32 - emit an ELF32 symbol
36322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void emitSymbol32(llvm::ELF::Elf32_Sym& pSym32,
36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    LDSymbol& pSymbol,
36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    char* pStrtab,
36622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    size_t pStrtabsize,
36722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    size_t pSymtabIdx);
36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// emitSymbol64 - emit an ELF64 symbol
37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void emitSymbol64(llvm::ELF::Elf64_Sym& pSym64,
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
3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// createProgramHdrs - base on output sections to create the program headers
3786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void createProgramHdrs(Module& pModule);
37922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
38022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// doCreateProgramHdrs - backend can implement this function to create the
38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// target-dependent segments
3826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual void doCreateProgramHdrs(Module& pModule) = 0;
3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
384affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// setupProgramHdrs - set up the attributes of segments
385affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ///  (i.e., offset, addresses, file/mem size, flag,  and alignment)
386f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  void setupProgramHdrs(const LinkerScript& pScript);
3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getSegmentFlag - give a section flag and return the corresponding segment
3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// flag
39087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  inline uint32_t getSegmentFlag(const uint32_t pSectionFlag);
3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
39222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// setupGNUStackInfo - setup the section flag of .note.GNU-stack in output
3936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void setupGNUStackInfo(Module& pModule);
39422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
39587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// setOutputSectionOffset - helper function to set output sections' offset.
39687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void setOutputSectionOffset(Module& pModule);
39722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
39887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// setOutputSectionAddress - helper function to set output sections' address.
39987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void setOutputSectionAddress(Module& pModule);
40022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
40187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  /// placeOutputSections - place output sections based on SectionMap
40287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void placeOutputSections(Module& pModule);
403affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
404d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  /// layout - layout method
4056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void layout(Module& pModule);
406d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// preLayout - Backend can do any needed modification before layout
4086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void preLayout(Module& pModule, IRBuilder& pBuilder);
4095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// postLayout -Backend can do any needed modification after layout
4116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void postLayout(Module& pModule, IRBuilder& pBuilder);
4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// preLayout - Backend can do any needed modification before layout
4146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual void doPreLayout(IRBuilder& pBuilder) = 0;
4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// postLayout -Backend can do any needed modification after layout
4176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual void doPostLayout(Module& pModule, IRBuilder& pLinker) = 0;
4185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
419affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// postProcessing - Backend can do any needed modification in the final stage
42087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void postProcessing(FileOutputBuffer& pOutput);
421affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// dynamic - the dynamic section of the target machine.
4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual ELFDynamic& dynamic() = 0;
4245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// dynamic - the dynamic section of the target machine.
4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual const ELFDynamic& dynamic() const = 0;
4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
42822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// relax - the relaxation pass
4296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool relax(Module& pModule, IRBuilder& pBuilder);
43022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
43122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// mayRelax - Backends should override this function if they need relaxation
43222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual bool mayRelax() { return false; }
43322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
43422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// doRelax - Backend can orevride this function to add its relaxation
43522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// implementation. Return true if the output (e.g., .text) is "relaxed"
43622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// (i.e. layout is changed), and set pFinished to true if everything is fit,
43722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// otherwise set it to false.
4386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  virtual bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished)
43922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  { return false; }
44022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprotected:
442affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Based on Kind in LDFileFormat to define basic section orders for ELF, and
443affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // refer gold linker to add more enumerations to handle Regular and BSS kind
444affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  enum SectionOrder {
44587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_NULL = 0,        // NULL
44687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_INTERP,          // .interp
44787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_RO_NOTE,         // .note.ABI-tag, .note.gnu.build-id
44887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_NAMEPOOL,        // *.hash, .dynsym, .dynstr
44987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_RELOCATION,      // .rel.*, .rela.*
45087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_REL_PLT,         // .rel.plt should come after other .rel.*
45187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_INIT,            // .init
45287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_PLT,             // .plt
45387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_TEXT,            // .text
45487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_FINI,            // .fini
45587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_RO,              // .rodata
45687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_EXCEPTION,       // .eh_frame_hdr, .eh_frame, .gcc_except_table
45787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_TLS_DATA,        // .tdata
45887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_TLS_BSS,         // .tbss
45987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_RELRO_LOCAL,     // .data.rel.ro.local
46087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_RELRO,           // .data.rel.ro,
46187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_RELRO_LAST,      // for x86 to adjust .got if needed
46287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_NON_RELRO_FIRST, // for x86 to adjust .got.plt if needed
46387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_DATA,            // .data
46487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_LARGE_DATA,      // .ldata
46587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_RW_NOTE,         //
46687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_SMALL_DATA,      // .sdata
46787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_SMALL_BSS,       // .sbss
46887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_BSS,             // .bss
46987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_LARGE_BSS,       // .lbss
47087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_UNDEFINED,       // default order
47187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    SHO_STRTAB           // .strtab
472affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  };
473affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
47487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // for -z combreloc
47587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  struct RelocCompare
47622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  {
47787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    RelocCompare(const GNULDBackend& pBackend)
47887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      : m_Backend(pBackend) {
47987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
48087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    bool operator()(const Relocation* X, const Relocation* Y) const;
48187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  private:
48287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    const GNULDBackend& m_Backend;
48322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  };
48422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // for gnu style hash table
4866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  struct DynsymCompare
4876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  {
4886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    bool needGNUHash(const LDSymbol& X) const;
4896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    bool operator()(const LDSymbol* X, const LDSymbol* Y) const;
4916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  };
4926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
49387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  struct SymCompare
49487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  {
49587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    bool operator()(const LDSymbol* X, const LDSymbol* Y) const
49687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    { return (X==Y); }
49787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  };
49887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
49922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  struct SymPtrHash
50022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  {
50122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    size_t operator()(const LDSymbol* pKey) const
50222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    {
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
513affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
514affc150dc44fab1911775a49636d0ce85333b634Zonr Changprotected:
5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFObjectReader* m_pObjectReader;
5165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // -----  file formats  ----- //
5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynObjFileFormat* m_pDynObjFileFormat;
51922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFExecFileFormat*   m_pExecFileFormat;
52022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFObjectFileFormat* m_pObjectFileFormat;
5215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
522d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // GNUInfo
523d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  GNUInfo* m_pInfo;
524d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
525affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // ELF segment factory
52687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ELFSegmentFactory* m_pELFSegmentTable;
5275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
52822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // branch island factory
52922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  BranchIslandFactory* m_pBRIslandFactory;
53022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
53122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // stub factory
53222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  StubFactory* m_pStubFactory;
53322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
534affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // map the LDSymbol to its index in the output symbol table
5355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  HashTableType* m_pSymIndexMap;
536affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
537affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // section .eh_frame_hdr
538affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  EhFrameHdr* m_pEhFrameHdr;
539affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
54087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // attribute section
54187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ELFAttribute* m_pAttribute;
54287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
54322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // ----- dynamic flags ----- //
54422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // DF_TEXTREL of DT_FLAGS
54522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool m_bHasTextRel;
54622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
54722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // DF_STATIC_TLS of DT_FLAGS
54822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool m_bHasStaticTLS;
54922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
550affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  standard symbols  ----- //
551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // section symbols
552affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pPreInitArrayStart;
553affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pPreInitArrayEnd;
554affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pInitArrayStart;
555affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pInitArrayEnd;
556affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pFiniArrayStart;
557affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pFiniArrayEnd;
558affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pStack;
55922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol* f_pDynamic;
56022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
56122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // section symbols for .tdata and .tbss
56222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol* f_pTDATA;
56322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol* f_pTBSS;
564affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
565affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // segment symbols
566affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pExecutableStart;
567affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pEText;
568affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_p_EText;
569affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_p__EText;
570affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pEData;
571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_p_EData;
572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pBSSStart;
573affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pEnd;
574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_p_End;
5755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
5765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
5805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
581