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