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