GNULDBackend.h revision 5460a1f25d9ddecb5c70667267d66d51af177a99
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
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ELF.h>
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/ADT/HashTable.h>
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/ADT/HashEntry.h>
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFDynObjReader.h>
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFDynObjWriter.h>
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFObjectReader.h>
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFObjectWriter.h>
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFDynObjFileFormat.h>
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFExecFileFormat.h>
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFSegment.h>
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/GNUArchiveReader.h>
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/GCFactory.h>
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/ELFDynamic.h>
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/TargetLDBackend.h>
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFSegmentFactory.h>
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostruct SymCompare
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool operator()(const LDSymbol* X, const LDSymbol* Y) const
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return (X==Y); }
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostruct PtrHash
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t operator()(const LDSymbol* pKey) const
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  {
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return (unsigned((uintptr_t)pKey) >> 4) ^
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao           (unsigned((uintptr_t)pKey) >> 9);
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass MCLDInfo;
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass Layout;
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass SymbolCategory;
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/** \class GNULDBackend
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  \brief GNULDBackend provides a common interface for all GNU Unix-OS
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  LDBackend.
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass GNULDBackend : public TargetLDBackend
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // These dynamic section tags are GNU extension.
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  enum {
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    DT_RELACOUNT  = 0x6ffffff9,
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    DT_RELCOUNT   = 0x6ffffffa,
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    DT_FLAGS_1    = 0x6ffffffb,
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    DT_VERDEF     = 0x6ffffffc,
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    DT_VERDEFNUM  = 0x6ffffffd,
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    DT_VERNEED    = 0x6ffffffe,
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    DT_VERNEEDNUM = 0x6fffffff
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  };
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprotected:
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Based on Kind in LDFileFormat to define basic section orders for ELF, and
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // refer gold linker to add more enumerations to handle Regular and BSS kind
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  enum SectionOrder {
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_INTERP = 1,          // .interp
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_RO_NOTE,             // .note.ABI-tag, .note.gnu.build-id
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_NAMEPOOL,            // *.hash, .dynsym, .dynstr
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_RELOCATION,          // .rel.*, .rela.*
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_REL_PLT,             // .rel.plt should come after other .rel.*
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_INIT,                // .init
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_PLT,                 // .plt
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_TEXT,                // .text
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_FINI,                // .fini
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_RO,                  // .rodata
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_EHFRAME,             // .eh_frame_hdr, .eh_frame
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_TLS_DATA,            // .tdata
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_TLS_BSS,             // .tbss
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_RELRO_LOCAL,         // .data.rel.ro.local
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_RELRO,               // .data.rel.ro,
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_RELRO_LAST,          // for x86 to adjust .got if needed
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_NON_RELRO_FIRST,     // for x86 to adjust .got.plt if needed
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_DATA,                // .data
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_LARGE_DATA,          // .ldata
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_RW_NOTE,             //
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_SMALL_DATA,          // .sdata
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_SMALL_BSS,           // .sbss
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_BSS,                 // .bss
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_LARGE_BSS,           // .lbss
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SHO_UNDEFINED = ~(0U)    // default order
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  };
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprotected:
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  GNULDBackend();
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual ~GNULDBackend();
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool initArchiveReader(MCLinker& pLinker, MCLDInfo& pInfo);
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool initObjectReader(MCLinker& pLinker);
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool initDynObjReader(MCLinker& pLinker);
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool initObjectWriter(MCLinker& pLinker);
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool initDynObjWriter(MCLinker& pLinker);
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool initExecSections(MCLinker& pMCLinker);
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool initDynObjSections(MCLinker& pMCLinker);
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool initStandardSymbols(MCLinker& pLinker);
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  GNUArchiveReader *getArchiveReader();
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  GNUArchiveReader *getArchiveReader() const;
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFObjectReader *getObjectReader();
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFObjectReader *getObjectReader() const;
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynObjReader *getDynObjReader();
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynObjReader *getDynObjReader() const;
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFObjectWriter *getObjectWriter();
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFObjectWriter *getObjectWriter() const;
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynObjWriter *getDynObjWriter();
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynObjWriter *getDynObjWriter() const;
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynObjFileFormat* getDynObjFileFormat();
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynObjFileFormat* getDynObjFileFormat() const;
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFExecFileFormat* getExecFileFormat();
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFExecFileFormat* getExecFileFormat() const;
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t sectionStartOffset() const;
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// The return value of machine() it the same as e_machine in the ELF header*/
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual uint32_t machine() const = 0;
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// ELFVersion - the value of e_ident[EI_VERSION]
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual uint8_t ELFVersion() const
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return llvm::ELF::EV_CURRENT; }
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// OSABI - the value of e_ident[EI_OSABI]
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual uint8_t OSABI() const = 0;
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// ABIVersion - the value of e_ident[EI_ABIVRESION]
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual uint8_t ABIVersion() const = 0;
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// flags - the value of ElfXX_Ehdr::e_flags
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual uint64_t flags() const = 0;
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// entry - the symbol name of the entry point
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual const char* entry() const
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return "_start"; }
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// sizeNamePools - compute the size of regular name pools
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// In ELF executable files, regular name pools are .symtab, .strtab.,
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// .dynsym, .dynstr, and .hash
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual void sizeNamePools(const Output& pOutput,
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             const SymbolCategory& pSymbols,
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             const MCLDInfo& pLDInfo);
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitSectionData - emit target-dependent section data
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual uint64_t emitSectionData(const Output& pOutput,
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   const LDSection& pSection,
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   const MCLDInfo& pInfo,
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   MemoryRegion& pRegion) const = 0;
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitRegNamePools - emit regular name pools - .symtab, .strtab
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual void emitRegNamePools(Output& pOutput,
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                SymbolCategory& pSymbols,
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                const Layout& pLayout,
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                const MCLDInfo& pLDInfo);
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual void emitDynNamePools(Output& pOutput,
1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                SymbolCategory& pSymbols,
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                const Layout& pLayout,
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                const MCLDInfo& pLDInfo);
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getSectionOrder - compute the layout order of the section
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// Layout calls this function to get the default order of the pSectHdr.
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// If the pSectHdr.type() is LDFileFormat::Target, then getSectionOrder()
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// will call getTargetSectionOrder().
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// If targets favors certain order for general sections, please override
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// this function.
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @see getTargetSectionOrder
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual unsigned int getSectionOrder(const Output& pOutput,
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                       const LDSection& pSectHdr) const;
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getTargetSectionOrder - compute the layout order of target section
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// If the target favors certain order for the given gSectHdr, please
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// override this function.
2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ///
2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// By default, this function returns the maximun order, and pSectHdr
2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// will be the last section to be laid out.
2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual unsigned int
2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  getTargetSectionOrder(const Output& pOutput, const LDSection& pSectHdr) const
2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return (unsigned int)-1; }
2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// emitProgramHdrs - emit ELF program headers
2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// if the target favors other ways to emit program header, please override
2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// this function
2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual void emitProgramHdrs(Output& pOutput);
2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// numOfSegments - return the number of segments
2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// if the target favors other ways to emit program header, please override
2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// this function
2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual unsigned int numOfSegments() const
2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return m_ELFSegmentTable.size(); }
2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// pagesize - the page size of the target machine, we set it to 4K here.
2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// If target favors tht different size of page, please override this function
2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual unsigned int pagesize() const
2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  { return 0x1000; }
2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getSymbolIdx - get the symbol index of ouput symbol table
2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t getSymbolIdx(LDSymbol* pSymbol) const;
2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// createProgramHdrs - base on output sections to create the program headers
2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void createProgramHdrs(LDContext& pContext);
2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// writeELF32ProgramHdrs - write out the ELF32 program headers
2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void writeELF32ProgramHdrs(Output& pOutput);
2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// writeELF64ProgramHdrs - write out the ELF64 program headers
2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void writeELF64ProgramHdrs(Output& pOutput);
2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getSegmentFlag - give a section flag and return the corresponding segment
2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// flag
2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  inline uint32_t getSegmentFlag(const uint32_t pSectionFlag)
2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  {
2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    uint32_t flag = llvm::ELF::PF_R;
2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (0 != (pSectionFlag & llvm::ELF::SHF_WRITE))
2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      flag |= llvm::ELF::PF_W;
2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (0 != (pSectionFlag & llvm::ELF::SHF_EXECINSTR))
2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      flag |= llvm::ELF::PF_X;
2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return flag;
2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// preLayout - Backend can do any needed modification before layout
2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void preLayout(const Output& pOutput,
2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                 const MCLDInfo& pInfo,
2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                 MCLinker& pLinker);
2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// postLayout -Backend can do any needed modification after layout
2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void postLayout(const Output& pOutput,
2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                 const MCLDInfo& pInfo,
2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                 MCLinker& pLinker);
2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprotected:
2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t getSymbolSize(const LDSymbol& pSymbol) const;
2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t getSymbolInfo(const LDSymbol& pSymbol) const;
2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t getSymbolValue(const LDSymbol& pSymbol) const;
2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t getSymbolShndx(const LDSymbol& pSymbol, const Layout& pLayout) const;
2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// preLayout - Backend can do any needed modification before layout
2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual void doPreLayout(const Output& pOutput,
2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                         const MCLDInfo& pInfo,
2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                         MCLinker& pLinker) = 0;
2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// postLayout -Backend can do any needed modification after layout
2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual void doPostLayout(const Output& pOutput,
2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                          const MCLDInfo& pInfo,
2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                          MCLinker& pLinker) = 0;
2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// dynamic - the dynamic section of the target machine.
2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual ELFDynamic& dynamic() = 0;
2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// dynamic - the dynamic section of the target machine.
2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual const ELFDynamic& dynamic() const = 0;
2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprotected:
2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // ----- readers and writers ----- //
2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  GNUArchiveReader* m_pArchiveReader;
2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFObjectReader* m_pObjectReader;
2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynObjReader* m_pDynObjReader;
2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFObjectWriter* m_pObjectWriter;
2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynObjWriter* m_pDynObjWriter;
2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // -----  file formats  ----- //
2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFDynObjFileFormat* m_pDynObjFileFormat;
2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFExecFileFormat* m_pExecFileFormat;
2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // -----  ELF segment factory  ----- //
2985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ELFSegmentFactory m_ELFSegmentTable;
2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // -----  ELF special sections  ----- //
3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprotected:
3035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// getHashBucketCount - calculate hash bucket count.
3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @ref Google gold linker, dynobj.cc:791
3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  static unsigned getHashBucketCount(unsigned pNumOfSymbols, bool pIsGNUStyle);
3065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// isDynamicSymbol
3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// @ref Google gold linker: symtab.cc:311
3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  static bool isDynamicSymbol(const LDSymbol& pSymbol, const Output& pOutput);
3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprotected:
3125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef HashEntry<LDSymbol*, size_t, SymCompare> HashEntryType;
3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef HashTable<HashEntryType, PtrHash, EntryFactory<HashEntryType> > HashTableType;
3145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// m_pSymIndexMap - Map the LDSymbol to its index in the output symbol table
3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  HashTableType* m_pSymIndexMap;
3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
323