GNULDBackend.h revision 22add6ff3426df1a85089fe6a6e1597ee3b6f300
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//===----------------------------------------------------------------------===//
95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#ifndef MCLD_TARGET_GNU_LDBACKEND_H
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#define MCLD_TARGET_GNU_LDBACKEND_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
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ELF.h>
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/ADT/HashTable.h>
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/ADT/HashEntry.h>
19affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/ELFDynObjFileFormat.h>
2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ELFExecFileFormat.h>
2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ELFObjectFileFormat.h>
2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/GNUArchiveReader.h>
2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ELFObjectReader.h>
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFDynObjReader.h>
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFDynObjWriter.h>
26affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/ELFExecWriter.h>
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFObjectWriter.h>
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFSegment.h>
29affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/ELFSegmentFactory.h>
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/ELFDynamic.h>
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/GCFactory.h>
3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h>
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaonamespace mcld {
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass Module;
3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass LinkerConfig;
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass Layout;
4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass EhFrame;
4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass EhFrameHdr;
4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass BranchIslandFactory;
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass StubFactory;
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:
5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  GNULDBackend(const LinkerConfig& pConfig);
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);
5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFObjectReader* createObjectReader(FragmentLinker& pLinker);
6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFDynObjReader* createDynObjReader(FragmentLinker& pLinker);
6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFObjectWriter* createObjectWriter(FragmentLinker& pLinker);
6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFDynObjWriter* createDynObjWriter(FragmentLinker& pLinker);
6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFExecWriter*   createExecWriter(FragmentLinker& pLinker);
64affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
65affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  output sections  ----- //
6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// initStdSections - initialize standard sections of the output file.
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool initStdSections(ObjectBuilder& pBuilder);
68affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
69affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// getOutputFormat - get the sections of the output file.
7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const ELFFileFormat* getOutputFormat() const;
7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFFileFormat*       getOutputFormat();
72affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
73affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  target symbols ----- //
74affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// initStandardSymbols - initialize standard symbols.
75affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// Some section symbols is undefined in input object, and linkers must set
76affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// up its value. Take __init_array_begin for example. This symbol is an
7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// undefined symbol in input objects. FragmentLinker must finalize its value
78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// to the begin of the .init_array section, then relocation enties to
79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// __init_array_begin can be applied without emission of "undefined
80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// reference to `__init_array_begin'".
8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool initStandardSymbols(FragmentLinker& pLinker, Module& pModule);
82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// finalizeSymbol - Linker checks pSymbol.reserved() if it's not zero,
84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// then it will ask backend to finalize the symbol value.
85affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @return ture - if backend set the symbol value sucessfully
86affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @return false - if backend do not recognize the symbol
8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool finalizeSymbols(FragmentLinker& pLinker) {
8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return (finalizeStandardSymbols(pLinker) &&
8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            finalizeTargetSymbols(pLinker));
90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
91affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
92affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// finalizeStandardSymbols - set the value of standard symbols
9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual bool finalizeStandardSymbols(FragmentLinker& pLinker);
94affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
95affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// finalizeTargetSymbols - set the value of target symbols
9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual bool finalizeTargetSymbols(FragmentLinker& pLinker) = 0;
9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// finalizeTLSSymbol - set the value of a TLS symbol
9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual bool finalizeTLSSymbol(LDSymbol& pSymbol);
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t sectionStartOffset() const;
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// The return value of machine() it the same as e_machine in the ELF header*/
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual uint32_t machine() const = 0;
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// ELFVersion - the value of e_ident[EI_VERSION]
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual uint8_t ELFVersion() const
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return llvm::ELF::EV_CURRENT; }
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// OSABI - the value of e_ident[EI_OSABI]
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual uint8_t OSABI() const = 0;
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// ABIVersion - the value of e_ident[EI_ABIVRESION]
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual uint8_t ABIVersion() const = 0;
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// flags - the value of ElfXX_Ehdr::e_flags
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual uint64_t flags() const = 0;
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// entry - the symbol name of the entry point
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual const char* entry() const
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return "_start"; }
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
123affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// dyld - the name of the default dynamic linker
124affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// target may override this function if needed.
125affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @ref gnu ld, bfd/elf32-i386.c:521
126affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  virtual const char* dyld() const
127affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  { return "/usr/lib/libc.so.1"; }
128affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
129affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// defaultTextSegmentAddr - target should specify its own default start address
130affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// of the text segment. esp. for exec.
131affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  virtual uint64_t defaultTextSegmentAddr() const
132affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  { return 0x0; }
133affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool hasTextRel() const
13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  { return m_bHasTextRel; }
13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool hasStaticTLS() const
13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  { return m_bHasStaticTLS; }
13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
140affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// segmentStartAddr - this function returns the start address of the segment
14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t segmentStartAddr(const FragmentLinker& pLinker) const;
14222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// partialScanRelocation - When doing partial linking, fix the relocation
14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// offset after section merge
14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void partialScanRelocation(Relocation& pReloc,
14622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                             FragmentLinker& pLinker,
14722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                             Module& pModule,
14822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                             const LDSection& pSection);
149affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// sizeNamePools - compute the size of regular name pools
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// In ELF executable files, regular name pools are .symtab, .strtab.,
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// .dynsym, .dynstr, and .hash
15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual void sizeNamePools(const Module& pModule, bool pIsStaticLink);
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitSectionData - emit target-dependent section data
15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual uint64_t emitSectionData(const LDSection& pSection,
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   MemoryRegion& pRegion) const = 0;
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitRegNamePools - emit regular name pools - .symtab, .strtab
16022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual void emitRegNamePools(const Module& pModule,
16122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                MemoryArea& pOutput);
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
16422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual void emitDynNamePools(const Module& pModule,
16522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                MemoryArea& pOutput);
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
167affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// sizeInterp - compute the size of program interpreter's name
168affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// In ELF executables, this is the length of dynamic linker's path name
16922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual void sizeInterp();
170affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
171affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// emitInterp - emit the .interp
17222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual void emitInterp(MemoryArea& pOutput);
173affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getSectionOrder - compute the layout order of the section
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// Layout calls this function to get the default order of the pSectHdr.
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// If the pSectHdr.type() is LDFileFormat::Target, then getSectionOrder()
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// will call getTargetSectionOrder().
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// If targets favors certain order for general sections, please override
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// this function.
1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @see getTargetSectionOrder
18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual unsigned int getSectionOrder(const LDSection& pSectHdr) const;
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getTargetSectionOrder - compute the layout order of target section
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// If the target favors certain order for the given gSectHdr, please
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// override this function.
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// By default, this function returns the maximun order, and pSectHdr
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// will be the last section to be laid out.
19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return (unsigned int)-1; }
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// numOfSegments - return the number of segments
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// if the target favors other ways to emit program header, please override
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// this function
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual unsigned int numOfSegments() const
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return m_ELFSegmentTable.size(); }
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
200affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// elfSegmentTable - return the reference of the elf segment table
201affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ELFSegmentFactory& elfSegmentTable()
202affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  { return m_ELFSegmentTable; }
203affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
204affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// elfSegmentTable - return the reference of the elf segment table
205affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  const ELFSegmentFactory& elfSegmentTable() const
206affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  { return m_ELFSegmentTable; }
207affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
208affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// commonPageSize - the common page size of the target machine, and we set it
209affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// to 4K here. If target favors the different size, please override this
210affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// function
21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual uint64_t commonPageSize() const;
212affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
213affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// abiPageSize - the abi page size of the target machine, and we set it to 4K
214affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// here. If target favors the different size, please override this function
21522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual uint64_t abiPageSize() const;
2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getSymbolIdx - get the symbol index of ouput symbol table
2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t getSymbolIdx(LDSymbol* pSymbol) const;
2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
220affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// isDefaultExecStack - target should specify whether the stack is default
221affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// executable. If target favors another choice, please override this function
222affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  virtual bool isDefaultExecStack() const
223affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  { return true; }
224affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
225affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// allocateCommonSymbols - allocate common symbols in the corresponding
226affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// sections.
227affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// Different concrete target backend may overlap this function.
22822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual bool allocateCommonSymbols(Module& pModule);
229affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
230affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// isSymbolPreemtible - whether the symbol can be preemted by other
231affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// link unit
232affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @ref Google gold linker, symtab.h:551
23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool isSymbolPreemptible(const ResolveInfo& pSym) const;
234affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
23567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  /// symbolNeedsDynRel - return whether the symbol needs a dynamic relocation
23667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  /// @ref Google gold linker, symtab.h:645
23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool symbolNeedsDynRel(const FragmentLinker& pLinker,
23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                         const ResolveInfo& pSym,
23967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                         bool pSymHasPLT,
24067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                         bool isAbsReloc) const;
24167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
24222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // getTDATASymbol - get section symbol of .tdata
24322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol& getTDATASymbol();
24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const LDSymbol& getTDATASymbol() const;
24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// getTBSSSymbol - get section symbol of .tbss
24722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol& getTBSSSymbol();
24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const LDSymbol& getTBSSSymbol() const;
24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  //  -----  relaxation  -----  //
25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// initBRIslandFactory - initialize the branch island factory for relaxation
25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool initBRIslandFactory();
25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// initStubFactory - initialize the stub factory for relaxation
25522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool initStubFactory();
25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// getBRIslandFactory
25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  BranchIslandFactory* getBRIslandFactory() { return m_pBRIslandFactory; }
25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// getStubFactory
26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  StubFactory*         getStubFactory()     { return m_pStubFactory; }
26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// maxBranchOffset - return the max (forward) branch offset of the backend.
26422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// Target can override this function if needed.
26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual uint64_t maxBranchOffset() { return (uint64_t)-1; }
26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
267affc150dc44fab1911775a49636d0ce85333b634Zonr Changprotected:
268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t getSymbolSize(const LDSymbol& pSymbol) const;
269affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
270affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t getSymbolInfo(const LDSymbol& pSymbol) const;
271affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
272affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t getSymbolValue(const LDSymbol& pSymbol) const;
273affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
27422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t getSymbolShndx(const LDSymbol& pSymbol) const;
275affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
276affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// getHashBucketCount - calculate hash bucket count.
277affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @ref Google gold linker, dynobj.cc:791
278affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  static unsigned getHashBucketCount(unsigned pNumOfSymbols, bool pIsGNUStyle);
279affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
280affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// isDynamicSymbol
281affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @ref Google gold linker: symtab.cc:311
28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool isDynamicSymbol(const LDSymbol& pSymbol);
283affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// isDynamicSymbol
28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// @ref Google gold linker: symtab.cc:311
28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool isDynamicSymbol(const ResolveInfo& pResolveInfo);
287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
288affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// symbolNeedsPLT - return whether the symbol needs a PLT entry
289affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// @ref Google gold linker, symtab.h:596
29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool symbolNeedsPLT(const FragmentLinker& pLinker,
29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                      const ResolveInfo& pSym) const;
292affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
293affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// symbolNeedsCopyReloc - return whether the symbol needs a copy relocation
29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool symbolNeedsCopyReloc(const FragmentLinker& pLinker,
295affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            const Relocation& pReloc,
29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                            const ResolveInfo& pSym) const;
29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// symbolHasFinalValue - return true if the symbol's value can be decided at
29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// link time
30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool symbolFinalValueIsKnown(const FragmentLinker& pLinker,
30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                               const ResolveInfo& pSym) const;
30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// emitSymbol32 - emit an ELF32 symbol
30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void emitSymbol32(llvm::ELF::Elf32_Sym& pSym32,
30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    LDSymbol& pSymbol,
30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    char* pStrtab,
30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    size_t pStrtabsize,
30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    size_t pSymtabIdx);
30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// emitSymbol64 - emit an ELF64 symbol
31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void emitSymbol64(llvm::ELF::Elf64_Sym& pSym64,
31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    LDSymbol& pSymbol,
31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    char* pStrtab,
31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    size_t pStrtabsize,
31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    size_t pSymtabIdx);
31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// checkAndSetHasTextRel - check pSection flag to set HasTextRel
31822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void checkAndSetHasTextRel(const LDSection& pSection);
31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void setHasStaticTLS(bool pVal = true)
32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  { m_bHasStaticTLS = pVal; }
322affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
3235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// createProgramHdrs - base on output sections to create the program headers
32522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void createProgramHdrs(Module& pModule, const FragmentLinker& pLinker);
32622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// doCreateProgramHdrs - backend can implement this function to create the
32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// target-dependent segments
32922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual void doCreateProgramHdrs(Module& pModule,
33022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                   const FragmentLinker& pLinker) = 0;
3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
332affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// setupProgramHdrs - set up the attributes of segments
333affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ///  (i.e., offset, addresses, file/mem size, flag,  and alignment)
33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void setupProgramHdrs(const FragmentLinker& pLinker);
3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getSegmentFlag - give a section flag and return the corresponding segment
3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// flag
3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  inline uint32_t getSegmentFlag(const uint32_t pSectionFlag)
3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  {
3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    uint32_t flag = llvm::ELF::PF_R;
3415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (0 != (pSectionFlag & llvm::ELF::SHF_WRITE))
3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      flag |= llvm::ELF::PF_W;
3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (0 != (pSectionFlag & llvm::ELF::SHF_EXECINSTR))
3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      flag |= llvm::ELF::PF_X;
3455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return flag;
3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// setupGNUStackInfo - setup the section flag of .note.GNU-stack in output
34922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void setupGNUStackInfo(Module& pModule, FragmentLinker& pLinker);
35022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
35122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// setupRelro - setup the offset constraint of PT_RELRO
35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void setupRelro(Module& pModule);
35322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
35422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// setOutputSectionOffset - helper function to set a group of output sections'
35522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// offset, and set pSectBegin to pStartOffset if pStartOffset is not -1U.
35622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void setOutputSectionOffset(Module& pModule,
35722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                              Module::iterator pSectBegin,
35822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                              Module::iterator pSectEnd,
35922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                              uint64_t pStartOffset = -1U);
36022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
36122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// setOutputSectionOffset - helper function to set output sections' address.
36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void setOutputSectionAddress(FragmentLinker& pLinker,
36322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                               Module& pModule,
36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                               Module::iterator pSectBegin,
36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                               Module::iterator pSectEnd);
366affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
3675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// preLayout - Backend can do any needed modification before layout
36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void preLayout(Module& pModule, FragmentLinker& pLinker);
3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// postLayout -Backend can do any needed modification after layout
37122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void postLayout(Module& pModule, FragmentLinker& pLinker);
3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// preLayout - Backend can do any needed modification before layout
37422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual void doPreLayout(FragmentLinker& pLinker) = 0;
3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// postLayout -Backend can do any needed modification after layout
37722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual void doPostLayout(Module& pModule, FragmentLinker& pLinker) = 0;
3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
379affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  /// postProcessing - Backend can do any needed modification in the final stage
38022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void postProcessing(FragmentLinker& pLinker, MemoryArea& pOutput);
381affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// dynamic - the dynamic section of the target machine.
3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual ELFDynamic& dynamic() = 0;
3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// dynamic - the dynamic section of the target machine.
3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual const ELFDynamic& dynamic() const = 0;
3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
38822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// relax - the relaxation pass
38922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool relax(Module& pModule, FragmentLinker& pLinker);
39022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
39122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// mayRelax - Backends should override this function if they need relaxation
39222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual bool mayRelax() { return false; }
39322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
39422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// doRelax - Backend can orevride this function to add its relaxation
39522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// implementation. Return true if the output (e.g., .text) is "relaxed"
39622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// (i.e. layout is changed), and set pFinished to true if everything is fit,
39722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// otherwise set it to false.
39822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual bool doRelax(Module& pModule, FragmentLinker& pLinker, bool& pFinished)
39922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  { return false; }
40022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// getRelEntrySize - the size in BYTE of rel type relocation
40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual size_t getRelEntrySize() = 0;
40322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
40422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// getRelEntrySize - the size in BYTE of rela type relocation
40522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual size_t getRelaEntrySize() = 0;
40622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprotected:
408affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Based on Kind in LDFileFormat to define basic section orders for ELF, and
409affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // refer gold linker to add more enumerations to handle Regular and BSS kind
410affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  enum SectionOrder {
411affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_INTERP = 1,          // .interp
412affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_RO_NOTE,             // .note.ABI-tag, .note.gnu.build-id
413affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_NAMEPOOL,            // *.hash, .dynsym, .dynstr
414affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_RELOCATION,          // .rel.*, .rela.*
415affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_REL_PLT,             // .rel.plt should come after other .rel.*
416affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_INIT,                // .init
417affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_PLT,                 // .plt
418affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_TEXT,                // .text
419affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_FINI,                // .fini
420affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_RO,                  // .rodata
421affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_EXCEPTION,           // .eh_frame_hdr, .eh_frame, .gcc_except_table
422affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_TLS_DATA,            // .tdata
423affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_TLS_BSS,             // .tbss
424affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_RELRO_LOCAL,         // .data.rel.ro.local
425affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_RELRO,               // .data.rel.ro,
426affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_RELRO_LAST,          // for x86 to adjust .got if needed
427affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_NON_RELRO_FIRST,     // for x86 to adjust .got.plt if needed
428affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_DATA,                // .data
429affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_LARGE_DATA,          // .ldata
430affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_RW_NOTE,             //
431affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_SMALL_DATA,          // .sdata
432affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_SMALL_BSS,           // .sbss
433affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_BSS,                 // .bss
434affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    SHO_LARGE_BSS,           // .lbss
43522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    SHO_UNDEFINED,           // default order
43622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    SHO_STRTAB               // .strtab
437affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  };
438affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
43922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  struct SymCompare
44022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  {
44122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    bool operator()(const LDSymbol* X, const LDSymbol* Y) const
44222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    { return (X==Y); }
44322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  };
44422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
44522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  struct SymPtrHash
44622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  {
44722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    size_t operator()(const LDSymbol* pKey) const
44822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    {
44922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return (unsigned((uintptr_t)pKey) >> 4) ^
45022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao             (unsigned((uintptr_t)pKey) >> 9);
45122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
45222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  };
45322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
45422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  typedef HashEntry<LDSymbol*, size_t, SymCompare> SymHashEntryType;
45522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  typedef HashTable<SymHashEntryType,
45622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    SymPtrHash,
45722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                    EntryFactory<SymHashEntryType> > HashTableType;
45822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
459affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
460affc150dc44fab1911775a49636d0ce85333b634Zonr Changprotected:
4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFObjectReader* m_pObjectReader;
4625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // -----  file formats  ----- //
4645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynObjFileFormat* m_pDynObjFileFormat;
46522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFExecFileFormat*   m_pExecFileFormat;
46622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ELFObjectFileFormat* m_pObjectFileFormat;
4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
468affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // ELF segment factory
4695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFSegmentFactory m_ELFSegmentTable;
4705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
47122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // branch island factory
47222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  BranchIslandFactory* m_pBRIslandFactory;
47322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
47422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // stub factory
47522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  StubFactory* m_pStubFactory;
47622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
477affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // map the LDSymbol to its index in the output symbol table
4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  HashTableType* m_pSymIndexMap;
479affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
48022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// m_pEhFrame - section .eh_frame
48122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  EhFrame* m_pEhFrame;
48222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
483affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // section .eh_frame_hdr
484affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  EhFrameHdr* m_pEhFrameHdr;
485affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
48622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // ----- dynamic flags ----- //
48722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // DF_TEXTREL of DT_FLAGS
48822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool m_bHasTextRel;
48922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
49022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // DF_STATIC_TLS of DT_FLAGS
49122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool m_bHasStaticTLS;
49222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
493affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // -----  standard symbols  ----- //
494affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // section symbols
495affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pPreInitArrayStart;
496affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pPreInitArrayEnd;
497affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pInitArrayStart;
498affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pInitArrayEnd;
499affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pFiniArrayStart;
500affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pFiniArrayEnd;
501affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pStack;
50222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol* f_pDynamic;
50322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
50422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // section symbols for .tdata and .tbss
50522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol* f_pTDATA;
50622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSymbol* f_pTBSS;
507affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
508affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // segment symbols
509affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pExecutableStart;
510affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pEText;
511affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_p_EText;
512affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_p__EText;
513affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pEData;
514affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_p_EData;
515affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pBSSStart;
516affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_pEnd;
517affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSymbol* f_p_End;
5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
5215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
5235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
524