15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- GNULDBackend.h -----------------------------------------------------===// 25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// The MCLinker Project 45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source 65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details. 75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#ifndef MCLD_TARGET_GNULDBACKEND_H 1087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#define MCLD_TARGET_GNULDBACKEND_H 1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Target/TargetLDBackend.h> 125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Module.h> 1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/GNUArchiveReader.h> 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFDynObjReader.h> 16d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LD/ELFBinaryReader.h> 1787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFObjectReader.h> 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFObjectWriter.h> 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/ELF.h> 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 22a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines#include <cstdint> 23a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines 2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaonamespace mcld { 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass Module; 2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass LinkerConfig; 28d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaoclass IRBuilder; 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass Layout; 3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass EhFrameHdr; 3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass BranchIslandFactory; 3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass StubFactory; 33d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaoclass GNUInfo; 3487f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFFileFormat; 3587f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFSegmentFactory; 3687f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFAttribute; 3787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFDynamic; 3887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFDynObjFileFormat; 3987f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFExecFileFormat; 4087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass ELFObjectFileFormat; 4187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass LinkerScript; 4287f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass Relocation; 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 */ 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass GNULDBackend : public TargetLDBackend 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprotected: 51d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo); 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic: 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao virtual ~GNULDBackend(); 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 56affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- readers/writers ----- // 5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao GNUArchiveReader* createArchiveReader(Module& pModule); 58d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ELFObjectReader* createObjectReader(IRBuilder& pBuilder); 59d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ELFDynObjReader* createDynObjReader(IRBuilder& pBuilder); 60d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ELFBinaryReader* createBinaryReader(IRBuilder& pBuilder); 616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFObjectWriter* createWriter(); 62affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 63affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- output sections ----- // 6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// initStdSections - initialize standard sections of the output file. 6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool initStdSections(ObjectBuilder& pBuilder); 66affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 67affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// getOutputFormat - get the sections of the output file. 6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const ELFFileFormat* getOutputFormat() const; 6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFFileFormat* getOutputFormat(); 70affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 71affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- target symbols ----- // 72affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// initStandardSymbols - initialize standard symbols. 73affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// Some section symbols is undefined in input object, and linkers must set 74affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// up its value. Take __init_array_begin for example. This symbol is an 756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines /// undefined symbol in input objects. ObjectLinker must finalize its value 76affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// to the begin of the .init_array section, then relocation enties to 77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// __init_array_begin can be applied without emission of "undefined 78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// reference to `__init_array_begin'". 796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool initStandardSymbols(IRBuilder& pBuilder, Module& pModule); 80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// finalizeSymbol - Linker checks pSymbol.reserved() if it's not zero, 82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// then it will ask backend to finalize the symbol value. 83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// @return ture - if backend set the symbol value sucessfully 84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// @return false - if backend do not recognize the symbol 856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool finalizeSymbols() { 866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return (finalizeStandardSymbols() && 876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines finalizeTargetSymbols()); 88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// finalizeStandardSymbols - set the value of standard symbols 916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines virtual bool finalizeStandardSymbols(); 92affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 93affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// finalizeTargetSymbols - set the value of target symbols 946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines virtual bool finalizeTargetSymbols() = 0; 9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// finalizeTLSSymbol - set the value of a TLS symbol 9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao virtual bool finalizeTLSSymbol(LDSymbol& pSymbol); 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t sectionStartOffset() const; 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 101d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao const GNUInfo& getInfo() const { return *m_pInfo; } 102d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao GNUInfo& getInfo() { return *m_pInfo; } 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool hasTextRel() const { return m_bHasTextRel; } 1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool hasStaticTLS() const { return m_bHasStaticTLS; } 10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 108f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// getSegmentStartAddr - this function returns the start address of the segment 109f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t getSegmentStartAddr(const LinkerScript& pScript) const; 110affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 11187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines /// sizeShstrtab - compute the size of .shstrtab 11287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines void sizeShstrtab(Module& pModule); 11387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// sizeNamePools - compute the size of regular name pools 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// In ELF executable files, regular name pools are .symtab, .strtab., 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// .dynsym, .dynstr, and .hash 117f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines virtual void sizeNamePools(Module& pModule); 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// emitSectionData - emit target-dependent section data 12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao virtual uint64_t emitSectionData(const LDSection& pSection, 1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion& pRegion) const = 0; 1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// emitRegNamePools - emit regular name pools - .symtab, .strtab 12487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines virtual void emitRegNamePools(const Module& pModule, FileOutputBuffer& pOutput); 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash 12787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines virtual void emitDynNamePools(Module& pModule, FileOutputBuffer& pOutput); 1286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines /// emitELFHashTab - emit .hash 1306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines virtual void emitELFHashTab(const Module::SymbolTable& pSymtab, 13187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines FileOutputBuffer& pOutput); 1326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines /// emitGNUHashTab - emit .gnu.hash 1346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines virtual void emitGNUHashTab(Module::SymbolTable& pSymtab, 13587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines FileOutputBuffer& pOutput); 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 137affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// sizeInterp - compute the size of program interpreter's name 138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// In ELF executables, this is the length of dynamic linker's path name 13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao virtual void sizeInterp(); 140affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 141affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// emitInterp - emit the .interp 14287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines virtual void emitInterp(FileOutputBuffer& pOutput); 143affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 144f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// hasEntryInStrTab - symbol has an entry in a .strtab 145f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines virtual bool hasEntryInStrTab(const LDSymbol& pSym) const; 146f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 147f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// orderSymbolTable - order symbol table before emitting 148f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines virtual void orderSymbolTable(Module& pModule); 149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 150f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines void setHasStaticTLS(bool pVal = true) 151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines { m_bHasStaticTLS = pVal; } 152f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// getSectionOrder - compute the layout order of the section 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// Layout calls this function to get the default order of the pSectHdr. 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// If the pSectHdr.type() is LDFileFormat::Target, then getSectionOrder() 1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// will call getTargetSectionOrder(). 1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// 1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// If targets favors certain order for general sections, please override 1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// this function. 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// 1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// @see getTargetSectionOrder 16222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao virtual unsigned int getSectionOrder(const LDSection& pSectHdr) const; 1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// getTargetSectionOrder - compute the layout order of target section 1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// If the target favors certain order for the given gSectHdr, please 1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// override this function. 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// By default, this function returns the maximun order, and pSectHdr 1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// will be the last section to be laid out. 17022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao virtual unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const 1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao { return (unsigned int)-1; } 1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 173affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// elfSegmentTable - return the reference of the elf segment table 17487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegmentFactory& elfSegmentTable(); 175affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 176affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// elfSegmentTable - return the reference of the elf segment table 17787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const ELFSegmentFactory& elfSegmentTable() const; 178affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines /// commonPageSize - the common page size of the target machine 1806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t commonPageSize() const; 181affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines /// abiPageSize - the abi page size of the target machine 1836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t abiPageSize() const; 1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// getSymbolIdx - get the symbol index of ouput symbol table 1866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t getSymbolIdx(const LDSymbol* pSymbol) const; 187affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 188affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// allocateCommonSymbols - allocate common symbols in the corresponding 189affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// sections. 190affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// Different concrete target backend may overlap this function. 19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao virtual bool allocateCommonSymbols(Module& pModule); 192affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines /// updateSectionFlags - update pTo's flags when merging pFrom 1946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines /// update the output section flags based on input section flags. 1956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines virtual bool updateSectionFlags(LDSection& pTo, const LDSection& pFrom); 1966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 19787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines /// readRelocation - read ELF32_Rel entry 19887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines virtual bool readRelocation(const llvm::ELF::Elf32_Rel& pRel, 19987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pType, 20087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pSymIdx, 20187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pOffset) const; 20287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 20387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines /// readRelocation - read ELF32_Rela entry 20487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines virtual bool readRelocation(const llvm::ELF::Elf32_Rela& pRel, 20587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pType, 20687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pSymIdx, 20787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pOffset, 20887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int32_t& pAddend) const; 20987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 21087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines /// readRelocation - read ELF64_Rel entry 21187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines virtual bool readRelocation(const llvm::ELF::Elf64_Rel& pRel, 21287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pType, 21387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pSymIdx, 21487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t& pOffset) const; 21587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 21687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines /// readRel - read ELF64_Rela entry 21787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines virtual bool readRelocation(const llvm::ELF::Elf64_Rela& pRel, 21887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pType, 21987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t& pSymIdx, 22087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t& pOffset, 22187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int64_t& pAddend) const; 22287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 22387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines /// emitRelocation - write data to the ELF32_Rel entry 22487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines virtual void emitRelocation(llvm::ELF::Elf32_Rel& pRel, 22587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pType, 22687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pSymIdx, 22787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pOffset) const; 22887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 22987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines /// emitRelocation - write data to the ELF32_Rela entry 23087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines virtual void emitRelocation(llvm::ELF::Elf32_Rela& pRel, 23187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pType, 23287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pSymIdx, 23387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pOffset, 23487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int32_t pAddend) const; 23587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 23687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines /// emitRelocation - write data to the ELF64_Rel entry 23787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines virtual void emitRelocation(llvm::ELF::Elf64_Rel& pRel, 23887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pType, 23987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pSymIdx, 24087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t pOffset) const; 24187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 24287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines /// emitRelocation - write data to the ELF64_Rela entry 24387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines virtual void emitRelocation(llvm::ELF::Elf64_Rela& pRel, 24487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pType, 24587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t pSymIdx, 24687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t pOffset, 24787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int64_t pAddend) const; 24887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 249f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// symbolNeedsPLT - return whether the symbol needs a PLT entry 250f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// @ref Google gold linker, symtab.h:596 251f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool symbolNeedsPLT(const ResolveInfo& pSym) const; 252f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 253f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// symbolNeedsCopyReloc - return whether the symbol needs a copy relocation 254f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool symbolNeedsCopyReloc(const Relocation& pReloc, 255f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const ResolveInfo& pSym) const; 256f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 257f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// symbolNeedsDynRel - return whether the symbol needs a dynamic relocation 258f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// @ref Google gold linker, symtab.h:645 259f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool symbolNeedsDynRel(const ResolveInfo& pSym, 260f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool pSymHasPLT, 261f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool isAbsReloc) const; 262f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 263a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines /// isSymbolPreemptible - whether the symbol can be preemted by other link 264a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines /// units 265affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// @ref Google gold linker, symtab.h:551 26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool isSymbolPreemptible(const ResolveInfo& pSym) const; 267affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 268f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// symbolHasFinalValue - return true if the symbol's value can be decided at 269f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// link time 270f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool symbolFinalValueIsKnown(const ResolveInfo& pSym) const; 271f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 272f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// isDynamicSymbol 273f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// @ref Google gold linker: symtab.cc:311 27487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines bool isDynamicSymbol(const LDSymbol& pSymbol) const; 275f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 276f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// isDynamicSymbol 277f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// @ref Google gold linker: symtab.cc:311 27887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines bool isDynamicSymbol(const ResolveInfo& pResolveInfo) const; 279f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 2806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines virtual ResolveInfo::Desc getSymDesc(uint16_t pShndx) const { 2816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return ResolveInfo::Define; 2826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 284f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool hasTDATASymbol() const { return (NULL != f_pTDATA); } 285f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool hasTBSSSymbol() const { return (NULL != f_pTBSS); } 286f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 287f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines void setTDATASymbol(LDSymbol& pTDATA) { f_pTDATA = &pTDATA; } 288f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines void setTBSSSymbol(LDSymbol& pTBSS) { f_pTBSS = &pTBSS; } 28967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao 29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // getTDATASymbol - get section symbol of .tdata 29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol& getTDATASymbol(); 29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSymbol& getTDATASymbol() const; 29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// getTBSSSymbol - get section symbol of .tbss 29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol& getTBSSSymbol(); 29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSymbol& getTBSSSymbol() const; 29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 29887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines /// getEntry - get the entry point name 29987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::StringRef getEntry(const Module& pModule) const; 30087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // ----- relaxation ----- // 30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// initBRIslandFactory - initialize the branch island factory for relaxation 30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool initBRIslandFactory(); 30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// initStubFactory - initialize the stub factory for relaxation 30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool initStubFactory(); 30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// getBRIslandFactory 30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao BranchIslandFactory* getBRIslandFactory() { return m_pBRIslandFactory; } 31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// getStubFactory 31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao StubFactory* getStubFactory() { return m_pStubFactory; } 31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 314a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines /// maxFwdBranchOffset - return the max forward branch offset of the backend. 315a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines /// Target can override this function if needed. 316a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines virtual int64_t maxFwdBranchOffset() { return INT64_MAX; } 317a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines 318a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines /// maxBwdBranchOffset - return the max backward branch offset of the backend. 31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// Target can override this function if needed. 320a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines virtual int64_t maxBwdBranchOffset() { return 0; } 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 339a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines /// mayHaveUnsafeFunctionPointerAccess - check if the section may have unsafe 340a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines /// function pointer access 341a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines bool mayHaveUnsafeFunctionPointerAccess(const LDSection& pSection) const; 342a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines 343affc150dc44fab1911775a49636d0ce85333b634Zonr Changprotected: 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 /// @ref Google gold linker, dynobj.cc:791 363affc150dc44fab1911775a49636d0ce85333b634Zonr Chang static unsigned getHashBucketCount(unsigned pNumOfSymbols, bool pIsGNUStyle); 364affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 3656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines /// getGNUHashMaskbitslog2 - calculate the number of mask bits in log2 3666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines /// @ref binutils gold, dynobj.cc:1165 3676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned getGNUHashMaskbitslog2(unsigned pNumOfSymbols) const; 3686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// emitSymbol32 - emit an ELF32 symbol 37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao void emitSymbol32(llvm::ELF::Elf32_Sym& pSym32, 37122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol& pSymbol, 37222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao char* pStrtab, 37322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t pStrtabsize, 37422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t pSymtabIdx); 37522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 37622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// emitSymbol64 - emit an ELF64 symbol 37722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao void emitSymbol64(llvm::ELF::Elf64_Sym& pSym64, 37822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol& pSymbol, 37922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao char* pStrtab, 38022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t pStrtabsize, 38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t pSymtabIdx); 38222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate: 3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// createProgramHdrs - base on output sections to create the program headers 3856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines void createProgramHdrs(Module& pModule); 38622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 38722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// doCreateProgramHdrs - backend can implement this function to create the 38822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// target-dependent segments 3896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines virtual void doCreateProgramHdrs(Module& pModule) = 0; 3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 391affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// setupProgramHdrs - set up the attributes of segments 392affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// (i.e., offset, addresses, file/mem size, flag, and alignment) 393f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines void setupProgramHdrs(const LinkerScript& pScript); 3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// getSegmentFlag - give a section flag and return the corresponding segment 3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// flag 39787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines inline uint32_t getSegmentFlag(const uint32_t pSectionFlag); 3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 39922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// setupGNUStackInfo - setup the section flag of .note.GNU-stack in output 4006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines void setupGNUStackInfo(Module& pModule); 40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 40287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines /// setOutputSectionOffset - helper function to set output sections' offset. 40387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines void setOutputSectionOffset(Module& pModule); 40422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 40587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines /// setOutputSectionAddress - helper function to set output sections' address. 40687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines void setOutputSectionAddress(Module& pModule); 40722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 40887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines /// placeOutputSections - place output sections based on SectionMap 40987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines void placeOutputSections(Module& pModule); 410affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 411d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao /// layout - layout method 4126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines void layout(Module& pModule); 413d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// preLayout - Backend can do any needed modification before layout 4156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines void preLayout(Module& pModule, IRBuilder& pBuilder); 4165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// postLayout -Backend can do any needed modification after layout 4186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines void postLayout(Module& pModule, IRBuilder& pBuilder); 4195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// preLayout - Backend can do any needed modification before layout 4216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines virtual void doPreLayout(IRBuilder& pBuilder) = 0; 4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// postLayout -Backend can do any needed modification after layout 4246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines virtual void doPostLayout(Module& pModule, IRBuilder& pLinker) = 0; 4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 426affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// postProcessing - Backend can do any needed modification in the final stage 42787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines void postProcessing(FileOutputBuffer& pOutput); 428affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// dynamic - the dynamic section of the target machine. 4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao virtual ELFDynamic& dynamic() = 0; 4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// dynamic - the dynamic section of the target machine. 4335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao virtual const ELFDynamic& dynamic() const = 0; 4345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 43522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// relax - the relaxation pass 4366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool relax(Module& pModule, IRBuilder& pBuilder); 43722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 43822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// mayRelax - Backends should override this function if they need relaxation 43922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao virtual bool mayRelax() { return false; } 44022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 44122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// doRelax - Backend can orevride this function to add its relaxation 44222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// implementation. Return true if the output (e.g., .text) is "relaxed" 44322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// (i.e. layout is changed), and set pFinished to true if everything is fit, 44422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// otherwise set it to false. 4456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines virtual bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished) 44622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao { return false; } 44722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprotected: 449affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Based on Kind in LDFileFormat to define basic section orders for ELF, and 450affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // refer gold linker to add more enumerations to handle Regular and BSS kind 451affc150dc44fab1911775a49636d0ce85333b634Zonr Chang enum SectionOrder { 45287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_NULL = 0, // NULL 45387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_INTERP, // .interp 45487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_RO_NOTE, // .note.ABI-tag, .note.gnu.build-id 45587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_NAMEPOOL, // *.hash, .dynsym, .dynstr 45687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_RELOCATION, // .rel.*, .rela.* 45787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_REL_PLT, // .rel.plt should come after other .rel.* 45887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_INIT, // .init 45987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_PLT, // .plt 46087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_TEXT, // .text 46187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_FINI, // .fini 46287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_RO, // .rodata 46387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_EXCEPTION, // .eh_frame_hdr, .eh_frame, .gcc_except_table 46487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_TLS_DATA, // .tdata 46587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_TLS_BSS, // .tbss 46687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_RELRO_LOCAL, // .data.rel.ro.local 46787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_RELRO, // .data.rel.ro, 46887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_RELRO_LAST, // for x86 to adjust .got if needed 46987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_NON_RELRO_FIRST, // for x86 to adjust .got.plt if needed 47087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_DATA, // .data 47187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_LARGE_DATA, // .ldata 47287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_RW_NOTE, // 47387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_SMALL_DATA, // .sdata 47487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_SMALL_BSS, // .sbss 47587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_BSS, // .bss 47687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_LARGE_BSS, // .lbss 47787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_UNDEFINED, // default order 47887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SHO_STRTAB // .strtab 479affc150dc44fab1911775a49636d0ce85333b634Zonr Chang }; 480affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 48187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // for -z combreloc 48287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines struct RelocCompare 48322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao { 48487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines RelocCompare(const GNULDBackend& pBackend) 48587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines : m_Backend(pBackend) { 48687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 48787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines bool operator()(const Relocation* X, const Relocation* Y) const; 48887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines private: 48987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const GNULDBackend& m_Backend; 49022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao }; 49122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // for gnu style hash table 4936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines struct DynsymCompare 4946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines { 4956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool needGNUHash(const LDSymbol& X) const; 4966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool operator()(const LDSymbol* X, const LDSymbol* Y) const; 4986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines }; 4996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 50087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines struct SymCompare 50187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines { 50287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines bool operator()(const LDSymbol* X, const LDSymbol* Y) const 50387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines { return (X==Y); } 50487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines }; 50587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 50622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao struct SymPtrHash 50722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao { 50822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t operator()(const LDSymbol* pKey) const 50922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao { 51022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return (unsigned((uintptr_t)pKey) >> 4) ^ 51122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (unsigned((uintptr_t)pKey) >> 9); 51222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 51322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao }; 51422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 51522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao typedef HashEntry<LDSymbol*, size_t, SymCompare> SymHashEntryType; 51622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao typedef HashTable<SymHashEntryType, 51722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SymPtrHash, 51822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao EntryFactory<SymHashEntryType> > HashTableType; 51922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 520affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 521affc150dc44fab1911775a49636d0ce85333b634Zonr Changprotected: 5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFObjectReader* m_pObjectReader; 5235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // ----- file formats ----- // 5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFDynObjFileFormat* m_pDynObjFileFormat; 52622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFExecFileFormat* m_pExecFileFormat; 52722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ELFObjectFileFormat* m_pObjectFileFormat; 5285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 529d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // GNUInfo 530d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao GNUInfo* m_pInfo; 531d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 532affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ELF segment factory 53387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegmentFactory* m_pELFSegmentTable; 5345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 53522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // branch island factory 53622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao BranchIslandFactory* m_pBRIslandFactory; 53722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 53822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // stub factory 53922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao StubFactory* m_pStubFactory; 54022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 541affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // map the LDSymbol to its index in the output symbol table 5425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao HashTableType* m_pSymIndexMap; 543affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 544affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // section .eh_frame_hdr 545affc150dc44fab1911775a49636d0ce85333b634Zonr Chang EhFrameHdr* m_pEhFrameHdr; 546affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 54787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // attribute section 54887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFAttribute* m_pAttribute; 54987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 55022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // ----- dynamic flags ----- // 55122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // DF_TEXTREL of DT_FLAGS 55222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool m_bHasTextRel; 55322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 55422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // DF_STATIC_TLS of DT_FLAGS 55522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool m_bHasStaticTLS; 55622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 557affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- standard symbols ----- // 558affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // section symbols 559affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol* f_pPreInitArrayStart; 560affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol* f_pPreInitArrayEnd; 561affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol* f_pInitArrayStart; 562affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol* f_pInitArrayEnd; 563affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol* f_pFiniArrayStart; 564affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol* f_pFiniArrayEnd; 565affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol* f_pStack; 56622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol* f_pDynamic; 56722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 56822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // section symbols for .tdata and .tbss 56922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol* f_pTDATA; 57022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol* f_pTBSS; 571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 572affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // segment symbols 573affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol* f_pExecutableStart; 574affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol* f_pEText; 575affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol* f_p_EText; 576affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol* f_p__EText; 577affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol* f_pEData; 578affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol* f_p_EData; 579affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol* f_pBSSStart; 580affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol* f_pEnd; 581affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSymbol* f_p_End; 5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}; 5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld 5855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif 5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 588