Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 1 | //===- GNULDBackend.h -----------------------------------------------------===// |
| 2 | // |
| 3 | // The MCLinker Project |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 9 | #ifndef MCLD_TARGET_GNULDBACKEND_H_ |
| 10 | #define MCLD_TARGET_GNULDBACKEND_H_ |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 11 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 12 | #include "mcld/Module.h" |
| 13 | #include "mcld/LD/ELFBinaryReader.h" |
| 14 | #include "mcld/LD/ELFDynObjReader.h" |
| 15 | #include "mcld/LD/ELFObjectReader.h" |
| 16 | #include "mcld/LD/ELFObjectWriter.h" |
| 17 | #include "mcld/LD/GNUArchiveReader.h" |
| 18 | #include "mcld/Target/TargetLDBackend.h" |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 19 | |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 20 | #include <llvm/Support/ELF.h> |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 21 | |
Stephen Hines | 0dea6bc | 2014-07-15 18:33:32 -0700 | [diff] [blame] | 22 | #include <cstdint> |
| 23 | |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 24 | namespace mcld { |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 25 | |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 26 | class BranchIslandFactory; |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 27 | class EhFrameHdr; |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 28 | class ELFAttribute; |
| 29 | class ELFDynamic; |
| 30 | class ELFDynObjFileFormat; |
| 31 | class ELFExecFileFormat; |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 32 | class ELFFileFormat; |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 33 | class ELFObjectFileFormat; |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 34 | class ELFSegmentFactory; |
| 35 | class GNUInfo; |
| 36 | class IRBuilder; |
| 37 | class Layout; |
| 38 | class LinkerConfig; |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 39 | class LinkerScript; |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 40 | class Module; |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 41 | class Relocation; |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 42 | class StubFactory; |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 43 | |
| 44 | /** \class GNULDBackend |
| 45 | * \brief GNULDBackend provides a common interface for all GNU Unix-OS |
| 46 | * LDBackend. |
| 47 | */ |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 48 | class GNULDBackend : public TargetLDBackend { |
| 49 | protected: |
Shih-wei Liao | d0fbbb2 | 2013-01-03 06:23:31 -0800 | [diff] [blame] | 50 | GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo); |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 51 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 52 | public: |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 53 | virtual ~GNULDBackend(); |
| 54 | |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 55 | // ----- readers/writers ----- // |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 56 | GNUArchiveReader* createArchiveReader(Module& pModule); |
Shih-wei Liao | d0fbbb2 | 2013-01-03 06:23:31 -0800 | [diff] [blame] | 57 | ELFObjectReader* createObjectReader(IRBuilder& pBuilder); |
| 58 | ELFDynObjReader* createDynObjReader(IRBuilder& pBuilder); |
| 59 | ELFBinaryReader* createBinaryReader(IRBuilder& pBuilder); |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 60 | ELFObjectWriter* createWriter(); |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 61 | |
| 62 | // ----- output sections ----- // |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 63 | /// initStdSections - initialize standard sections of the output file. |
| 64 | bool initStdSections(ObjectBuilder& pBuilder); |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 65 | |
| 66 | /// getOutputFormat - get the sections of the output file. |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 67 | const ELFFileFormat* getOutputFormat() const; |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 68 | ELFFileFormat* getOutputFormat(); |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 69 | |
| 70 | // ----- target symbols ----- // |
| 71 | /// initStandardSymbols - initialize standard symbols. |
| 72 | /// Some section symbols is undefined in input object, and linkers must set |
| 73 | /// up its value. Take __init_array_begin for example. This symbol is an |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 74 | /// undefined symbol in input objects. ObjectLinker must finalize its value |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 75 | /// to the begin of the .init_array section, then relocation enties to |
| 76 | /// __init_array_begin can be applied without emission of "undefined |
| 77 | /// reference to `__init_array_begin'". |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 78 | bool initStandardSymbols(IRBuilder& pBuilder, Module& pModule); |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 79 | |
| 80 | /// finalizeSymbol - Linker checks pSymbol.reserved() if it's not zero, |
| 81 | /// then it will ask backend to finalize the symbol value. |
| 82 | /// @return ture - if backend set the symbol value sucessfully |
| 83 | /// @return false - if backend do not recognize the symbol |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 84 | bool finalizeSymbols() { |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 85 | return (finalizeStandardSymbols() && finalizeTargetSymbols()); |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 86 | } |
| 87 | |
| 88 | /// finalizeStandardSymbols - set the value of standard symbols |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 89 | virtual bool finalizeStandardSymbols(); |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 90 | |
| 91 | /// finalizeTargetSymbols - set the value of target symbols |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 92 | virtual bool finalizeTargetSymbols() = 0; |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 93 | |
| 94 | /// finalizeTLSSymbol - set the value of a TLS symbol |
| 95 | virtual bool finalizeTLSSymbol(LDSymbol& pSymbol); |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 96 | |
| 97 | size_t sectionStartOffset() const; |
| 98 | |
Shih-wei Liao | d0fbbb2 | 2013-01-03 06:23:31 -0800 | [diff] [blame] | 99 | const GNUInfo& getInfo() const { return *m_pInfo; } |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 100 | GNUInfo& getInfo() { return *m_pInfo; } |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 101 | |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 102 | bool hasTextRel() const { return m_bHasTextRel; } |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 103 | |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 104 | bool hasStaticTLS() const { return m_bHasStaticTLS; } |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 105 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 106 | /// getSegmentStartAddr - return the start address of the segment |
Stephen Hines | f7ac0f1 | 2013-05-03 19:09:24 -0700 | [diff] [blame] | 107 | uint64_t getSegmentStartAddr(const LinkerScript& pScript) const; |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 108 | |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 109 | /// sizeShstrtab - compute the size of .shstrtab |
| 110 | void sizeShstrtab(Module& pModule); |
| 111 | |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 112 | /// sizeNamePools - compute the size of regular name pools |
| 113 | /// In ELF executable files, regular name pools are .symtab, .strtab., |
| 114 | /// .dynsym, .dynstr, and .hash |
Stephen Hines | f7ac0f1 | 2013-05-03 19:09:24 -0700 | [diff] [blame] | 115 | virtual void sizeNamePools(Module& pModule); |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 116 | |
| 117 | /// emitSectionData - emit target-dependent section data |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 118 | virtual uint64_t emitSectionData(const LDSection& pSection, |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 119 | MemoryRegion& pRegion) const = 0; |
| 120 | |
| 121 | /// emitRegNamePools - emit regular name pools - .symtab, .strtab |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 122 | virtual void emitRegNamePools(const Module& pModule, |
| 123 | FileOutputBuffer& pOutput); |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 124 | |
| 125 | /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 126 | virtual void emitDynNamePools(Module& pModule, FileOutputBuffer& pOutput); |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 127 | |
| 128 | /// emitELFHashTab - emit .hash |
| 129 | virtual void emitELFHashTab(const Module::SymbolTable& pSymtab, |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 130 | FileOutputBuffer& pOutput); |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 131 | |
| 132 | /// emitGNUHashTab - emit .gnu.hash |
| 133 | virtual void emitGNUHashTab(Module::SymbolTable& pSymtab, |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 134 | FileOutputBuffer& pOutput); |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 135 | |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 136 | /// sizeInterp - compute the size of program interpreter's name |
| 137 | /// In ELF executables, this is the length of dynamic linker's path name |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 138 | virtual void sizeInterp(); |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 139 | |
| 140 | /// emitInterp - emit the .interp |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 141 | virtual void emitInterp(FileOutputBuffer& pOutput); |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 142 | |
Stephen Hines | f7ac0f1 | 2013-05-03 19:09:24 -0700 | [diff] [blame] | 143 | /// hasEntryInStrTab - symbol has an entry in a .strtab |
| 144 | virtual bool hasEntryInStrTab(const LDSymbol& pSym) const; |
| 145 | |
| 146 | /// orderSymbolTable - order symbol table before emitting |
| 147 | virtual void orderSymbolTable(Module& pModule); |
| 148 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 149 | void setHasStaticTLS(bool pVal = true) { m_bHasStaticTLS = pVal; } |
Stephen Hines | f7ac0f1 | 2013-05-03 19:09:24 -0700 | [diff] [blame] | 150 | |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 151 | /// getSectionOrder - compute the layout order of the section |
| 152 | /// Layout calls this function to get the default order of the pSectHdr. |
| 153 | /// If the pSectHdr.type() is LDFileFormat::Target, then getSectionOrder() |
| 154 | /// will call getTargetSectionOrder(). |
| 155 | /// |
| 156 | /// If targets favors certain order for general sections, please override |
| 157 | /// this function. |
| 158 | /// |
| 159 | /// @see getTargetSectionOrder |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 160 | virtual unsigned int getSectionOrder(const LDSection& pSectHdr) const; |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 161 | |
| 162 | /// getTargetSectionOrder - compute the layout order of target section |
| 163 | /// If the target favors certain order for the given gSectHdr, please |
| 164 | /// override this function. |
| 165 | /// |
| 166 | /// By default, this function returns the maximun order, and pSectHdr |
| 167 | /// will be the last section to be laid out. |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 168 | virtual unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const { |
| 169 | return (unsigned int)-1; |
| 170 | } |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 171 | |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 172 | /// elfSegmentTable - return the reference of the elf segment table |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 173 | ELFSegmentFactory& elfSegmentTable(); |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 174 | |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 175 | /// elfSegmentTable - return the reference of the elf segment table |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 176 | const ELFSegmentFactory& elfSegmentTable() const; |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 177 | |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 178 | /// commonPageSize - the common page size of the target machine |
| 179 | uint64_t commonPageSize() const; |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 180 | |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 181 | /// abiPageSize - the abi page size of the target machine |
| 182 | uint64_t abiPageSize() const; |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 183 | |
| 184 | /// getSymbolIdx - get the symbol index of ouput symbol table |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 185 | size_t getSymbolIdx(const LDSymbol* pSymbol) const; |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 186 | |
| 187 | /// allocateCommonSymbols - allocate common symbols in the corresponding |
| 188 | /// sections. |
| 189 | /// Different concrete target backend may overlap this function. |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 190 | virtual bool allocateCommonSymbols(Module& pModule); |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 191 | |
Stephen Hines | b0d0eb2 | 2016-03-08 00:18:09 -0800 | [diff] [blame^] | 192 | /// mergeFlags - update set of ELF header flags |
| 193 | virtual void mergeFlags(Input& pInput, const char* ELF_hdr) {} |
| 194 | |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 195 | /// updateSectionFlags - update pTo's flags when merging pFrom |
| 196 | /// update the output section flags based on input section flags. |
| 197 | virtual bool updateSectionFlags(LDSection& pTo, const LDSection& pFrom); |
| 198 | |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 199 | /// readRelocation - read ELF32_Rel entry |
| 200 | virtual bool readRelocation(const llvm::ELF::Elf32_Rel& pRel, |
| 201 | uint32_t& pType, |
| 202 | uint32_t& pSymIdx, |
| 203 | uint32_t& pOffset) const; |
| 204 | |
| 205 | /// readRelocation - read ELF32_Rela entry |
| 206 | virtual bool readRelocation(const llvm::ELF::Elf32_Rela& pRel, |
| 207 | uint32_t& pType, |
| 208 | uint32_t& pSymIdx, |
| 209 | uint32_t& pOffset, |
| 210 | int32_t& pAddend) const; |
| 211 | |
| 212 | /// readRelocation - read ELF64_Rel entry |
| 213 | virtual bool readRelocation(const llvm::ELF::Elf64_Rel& pRel, |
| 214 | uint32_t& pType, |
| 215 | uint32_t& pSymIdx, |
| 216 | uint64_t& pOffset) const; |
| 217 | |
| 218 | /// readRel - read ELF64_Rela entry |
| 219 | virtual bool readRelocation(const llvm::ELF::Elf64_Rela& pRel, |
| 220 | uint32_t& pType, |
| 221 | uint32_t& pSymIdx, |
| 222 | uint64_t& pOffset, |
| 223 | int64_t& pAddend) const; |
| 224 | |
| 225 | /// emitRelocation - write data to the ELF32_Rel entry |
| 226 | virtual void emitRelocation(llvm::ELF::Elf32_Rel& pRel, |
| 227 | uint32_t pType, |
| 228 | uint32_t pSymIdx, |
| 229 | uint32_t pOffset) const; |
| 230 | |
| 231 | /// emitRelocation - write data to the ELF32_Rela entry |
| 232 | virtual void emitRelocation(llvm::ELF::Elf32_Rela& pRel, |
| 233 | uint32_t pType, |
| 234 | uint32_t pSymIdx, |
| 235 | uint32_t pOffset, |
| 236 | int32_t pAddend) const; |
| 237 | |
| 238 | /// emitRelocation - write data to the ELF64_Rel entry |
| 239 | virtual void emitRelocation(llvm::ELF::Elf64_Rel& pRel, |
| 240 | uint32_t pType, |
| 241 | uint32_t pSymIdx, |
| 242 | uint64_t pOffset) const; |
| 243 | |
| 244 | /// emitRelocation - write data to the ELF64_Rela entry |
| 245 | virtual void emitRelocation(llvm::ELF::Elf64_Rela& pRel, |
| 246 | uint32_t pType, |
| 247 | uint32_t pSymIdx, |
| 248 | uint64_t pOffset, |
| 249 | int64_t pAddend) const; |
| 250 | |
Stephen Hines | f7ac0f1 | 2013-05-03 19:09:24 -0700 | [diff] [blame] | 251 | /// symbolNeedsPLT - return whether the symbol needs a PLT entry |
Stephen Hines | f7ac0f1 | 2013-05-03 19:09:24 -0700 | [diff] [blame] | 252 | bool symbolNeedsPLT(const ResolveInfo& pSym) const; |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 253 | |
Stephen Hines | f7ac0f1 | 2013-05-03 19:09:24 -0700 | [diff] [blame] | 254 | /// symbolNeedsCopyReloc - return whether the symbol needs a copy relocation |
| 255 | bool symbolNeedsCopyReloc(const Relocation& pReloc, |
| 256 | const ResolveInfo& pSym) const; |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 257 | |
Shih-wei Liao | 67e37f1 | 2012-07-27 03:50:34 -0700 | [diff] [blame] | 258 | /// symbolNeedsDynRel - return whether the symbol needs a dynamic relocation |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 259 | bool symbolNeedsDynRel(const ResolveInfo& pSym, |
Shih-wei Liao | 67e37f1 | 2012-07-27 03:50:34 -0700 | [diff] [blame] | 260 | bool pSymHasPLT, |
Shih-wei Liao | 67e37f1 | 2012-07-27 03:50:34 -0700 | [diff] [blame] | 261 | bool isAbsReloc) const; |
| 262 | |
Stephen Hines | 0dea6bc | 2014-07-15 18:33:32 -0700 | [diff] [blame] | 263 | /// isSymbolPreemptible - whether the symbol can be preemted by other link |
| 264 | /// units |
Stephen Hines | f7ac0f1 | 2013-05-03 19:09:24 -0700 | [diff] [blame] | 265 | bool isSymbolPreemptible(const ResolveInfo& pSym) const; |
| 266 | |
| 267 | /// symbolHasFinalValue - return true if the symbol's value can be decided at |
| 268 | /// link time |
| 269 | bool symbolFinalValueIsKnown(const ResolveInfo& pSym) const; |
| 270 | |
| 271 | /// isDynamicSymbol |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 272 | bool isDynamicSymbol(const LDSymbol& pSymbol) const; |
Stephen Hines | f7ac0f1 | 2013-05-03 19:09:24 -0700 | [diff] [blame] | 273 | |
| 274 | /// isDynamicSymbol |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 275 | bool isDynamicSymbol(const ResolveInfo& pResolveInfo) const; |
Stephen Hines | f7ac0f1 | 2013-05-03 19:09:24 -0700 | [diff] [blame] | 276 | |
| 277 | virtual ResolveInfo::Desc getSymDesc(uint16_t pShndx) const { |
| 278 | return ResolveInfo::Define; |
| 279 | } |
| 280 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 281 | bool hasTDATASymbol() const { return (f_pTDATA != NULL); } |
| 282 | bool hasTBSSSymbol() const { return (f_pTBSS != NULL); } |
Stephen Hines | f7ac0f1 | 2013-05-03 19:09:24 -0700 | [diff] [blame] | 283 | |
| 284 | void setTDATASymbol(LDSymbol& pTDATA) { f_pTDATA = &pTDATA; } |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 285 | void setTBSSSymbol(LDSymbol& pTBSS) { f_pTBSS = &pTBSS; } |
Stephen Hines | f7ac0f1 | 2013-05-03 19:09:24 -0700 | [diff] [blame] | 286 | |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 287 | // getTDATASymbol - get section symbol of .tdata |
| 288 | LDSymbol& getTDATASymbol(); |
| 289 | const LDSymbol& getTDATASymbol() const; |
| 290 | |
| 291 | /// getTBSSSymbol - get section symbol of .tbss |
| 292 | LDSymbol& getTBSSSymbol(); |
| 293 | const LDSymbol& getTBSSSymbol() const; |
| 294 | |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 295 | /// getEntry - get the entry point name |
| 296 | llvm::StringRef getEntry(const Module& pModule) const; |
| 297 | |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 298 | // ----- relaxation ----- // |
| 299 | /// initBRIslandFactory - initialize the branch island factory for relaxation |
| 300 | bool initBRIslandFactory(); |
| 301 | |
| 302 | /// initStubFactory - initialize the stub factory for relaxation |
| 303 | bool initStubFactory(); |
| 304 | |
| 305 | /// getBRIslandFactory |
| 306 | BranchIslandFactory* getBRIslandFactory() { return m_pBRIslandFactory; } |
| 307 | |
| 308 | /// getStubFactory |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 309 | StubFactory* getStubFactory() { return m_pStubFactory; } |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 310 | |
Stephen Hines | 0dea6bc | 2014-07-15 18:33:32 -0700 | [diff] [blame] | 311 | /// maxFwdBranchOffset - return the max forward branch offset of the backend. |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 312 | /// Target can override this function if needed. |
Stephen Hines | b0d0eb2 | 2016-03-08 00:18:09 -0800 | [diff] [blame^] | 313 | virtual int64_t maxFwdBranchOffset() const { return INT64_MAX; } |
Stephen Hines | 0dea6bc | 2014-07-15 18:33:32 -0700 | [diff] [blame] | 314 | |
| 315 | /// maxBwdBranchOffset - return the max backward branch offset of the backend. |
| 316 | /// Target can override this function if needed. |
Stephen Hines | b0d0eb2 | 2016-03-08 00:18:09 -0800 | [diff] [blame^] | 317 | virtual int64_t maxBwdBranchOffset() const { return 0; } |
| 318 | |
| 319 | /// stubGroupSize - return the group size to place stubs between sections. |
| 320 | virtual unsigned stubGroupSize() const; |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 321 | |
Stephen Hines | f7ac0f1 | 2013-05-03 19:09:24 -0700 | [diff] [blame] | 322 | /// checkAndSetHasTextRel - check pSection flag to set HasTextRel |
| 323 | void checkAndSetHasTextRel(const LDSection& pSection); |
| 324 | |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 325 | /// sortRelocation - sort the dynamic relocations to let dynamic linker |
| 326 | /// process relocations more efficiently |
| 327 | void sortRelocation(LDSection& pSection); |
| 328 | |
| 329 | /// createAndSizeEhFrameHdr - This is seperated since we may add eh_frame |
| 330 | /// entry in the middle |
| 331 | void createAndSizeEhFrameHdr(Module& pModule); |
| 332 | |
| 333 | /// attribute - the attribute section data. |
| 334 | ELFAttribute& attribute() { return *m_pAttribute; } |
| 335 | |
| 336 | /// attribute - the attribute section data. |
| 337 | const ELFAttribute& attribute() const { return *m_pAttribute; } |
| 338 | |
Stephen Hines | 0dea6bc | 2014-07-15 18:33:32 -0700 | [diff] [blame] | 339 | /// mayHaveUnsafeFunctionPointerAccess - check if the section may have unsafe |
| 340 | /// function pointer access |
| 341 | bool mayHaveUnsafeFunctionPointerAccess(const LDSection& pSection) const; |
| 342 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 343 | protected: |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 344 | /// getRelEntrySize - the size in BYTE of rel type relocation |
| 345 | virtual size_t getRelEntrySize() = 0; |
| 346 | |
| 347 | /// getRelEntrySize - the size in BYTE of rela type relocation |
| 348 | virtual size_t getRelaEntrySize() = 0; |
| 349 | |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 350 | uint64_t getSymbolSize(const LDSymbol& pSymbol) const; |
| 351 | |
| 352 | uint64_t getSymbolInfo(const LDSymbol& pSymbol) const; |
| 353 | |
| 354 | uint64_t getSymbolValue(const LDSymbol& pSymbol) const; |
| 355 | |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 356 | uint64_t getSymbolShndx(const LDSymbol& pSymbol) const; |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 357 | |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 358 | /// isTemporary - Whether pSymbol is a local label. |
| 359 | virtual bool isTemporary(const LDSymbol& pSymbol) const; |
| 360 | |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 361 | /// getHashBucketCount - calculate hash bucket count. |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 362 | static unsigned getHashBucketCount(unsigned pNumOfSymbols, bool pIsGNUStyle); |
| 363 | |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 364 | /// getGNUHashMaskbitslog2 - calculate the number of mask bits in log2 |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 365 | unsigned getGNUHashMaskbitslog2(unsigned pNumOfSymbols) const; |
| 366 | |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 367 | /// emitSymbol32 - emit an ELF32 symbol |
| 368 | void emitSymbol32(llvm::ELF::Elf32_Sym& pSym32, |
| 369 | LDSymbol& pSymbol, |
| 370 | char* pStrtab, |
| 371 | size_t pStrtabsize, |
| 372 | size_t pSymtabIdx); |
| 373 | |
| 374 | /// emitSymbol64 - emit an ELF64 symbol |
| 375 | void emitSymbol64(llvm::ELF::Elf64_Sym& pSym64, |
| 376 | LDSymbol& pSymbol, |
| 377 | char* pStrtab, |
| 378 | size_t pStrtabsize, |
| 379 | size_t pSymtabIdx); |
| 380 | |
Stephen Hines | a6c24df | 2015-03-18 14:53:18 -0700 | [diff] [blame] | 381 | protected: |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 382 | /// createProgramHdrs - base on output sections to create the program headers |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 383 | void createProgramHdrs(Module& pModule); |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 384 | |
| 385 | /// doCreateProgramHdrs - backend can implement this function to create the |
| 386 | /// target-dependent segments |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 387 | virtual void doCreateProgramHdrs(Module& pModule) = 0; |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 388 | |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 389 | /// setupProgramHdrs - set up the attributes of segments |
| 390 | /// (i.e., offset, addresses, file/mem size, flag, and alignment) |
Stephen Hines | f7ac0f1 | 2013-05-03 19:09:24 -0700 | [diff] [blame] | 391 | void setupProgramHdrs(const LinkerScript& pScript); |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 392 | |
| 393 | /// getSegmentFlag - give a section flag and return the corresponding segment |
| 394 | /// flag |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 395 | inline uint32_t getSegmentFlag(const uint32_t pSectionFlag); |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 396 | |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 397 | /// setupGNUStackInfo - setup the section flag of .note.GNU-stack in output |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 398 | void setupGNUStackInfo(Module& pModule); |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 399 | |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 400 | /// setOutputSectionOffset - helper function to set output sections' offset. |
| 401 | void setOutputSectionOffset(Module& pModule); |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 402 | |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 403 | /// setOutputSectionAddress - helper function to set output sections' address. |
| 404 | void setOutputSectionAddress(Module& pModule); |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 405 | |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 406 | /// placeOutputSections - place output sections based on SectionMap |
| 407 | void placeOutputSections(Module& pModule); |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 408 | |
Shih-wei Liao | d0fbbb2 | 2013-01-03 06:23:31 -0800 | [diff] [blame] | 409 | /// layout - layout method |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 410 | void layout(Module& pModule); |
Shih-wei Liao | d0fbbb2 | 2013-01-03 06:23:31 -0800 | [diff] [blame] | 411 | |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 412 | /// preLayout - Backend can do any needed modification before layout |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 413 | void preLayout(Module& pModule, IRBuilder& pBuilder); |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 414 | |
| 415 | /// postLayout -Backend can do any needed modification after layout |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 416 | void postLayout(Module& pModule, IRBuilder& pBuilder); |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 417 | |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 418 | /// preLayout - Backend can do any needed modification before layout |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 419 | virtual void doPreLayout(IRBuilder& pBuilder) = 0; |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 420 | |
| 421 | /// postLayout -Backend can do any needed modification after layout |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 422 | virtual void doPostLayout(Module& pModule, IRBuilder& pLinker) = 0; |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 423 | |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 424 | /// postProcessing - Backend can do any needed modification in the final stage |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 425 | void postProcessing(FileOutputBuffer& pOutput); |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 426 | |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 427 | /// dynamic - the dynamic section of the target machine. |
| 428 | virtual ELFDynamic& dynamic() = 0; |
| 429 | |
| 430 | /// dynamic - the dynamic section of the target machine. |
| 431 | virtual const ELFDynamic& dynamic() const = 0; |
| 432 | |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 433 | /// relax - the relaxation pass |
Stephen Hines | a6c24df | 2015-03-18 14:53:18 -0700 | [diff] [blame] | 434 | virtual bool relax(Module& pModule, IRBuilder& pBuilder); |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 435 | |
| 436 | /// mayRelax - Backends should override this function if they need relaxation |
| 437 | virtual bool mayRelax() { return false; } |
| 438 | |
| 439 | /// doRelax - Backend can orevride this function to add its relaxation |
| 440 | /// implementation. Return true if the output (e.g., .text) is "relaxed" |
| 441 | /// (i.e. layout is changed), and set pFinished to true if everything is fit, |
| 442 | /// otherwise set it to false. |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 443 | virtual bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished) { |
| 444 | return false; |
| 445 | } |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 446 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 447 | protected: |
| 448 | // Based on Kind in LDFileFormat to define basic section orders for ELF. |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 449 | enum SectionOrder { |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 450 | SHO_NULL = 0, // NULL |
| 451 | SHO_INTERP, // .interp |
| 452 | SHO_RO_NOTE, // .note.ABI-tag, .note.gnu.build-id |
| 453 | SHO_NAMEPOOL, // *.hash, .dynsym, .dynstr |
| 454 | SHO_RELOCATION, // .rel.*, .rela.* |
| 455 | SHO_REL_PLT, // .rel.plt should come after other .rel.* |
| 456 | SHO_INIT, // .init |
| 457 | SHO_PLT, // .plt |
| 458 | SHO_TEXT, // .text |
| 459 | SHO_FINI, // .fini |
| 460 | SHO_RO, // .rodata |
| 461 | SHO_EXCEPTION, // .eh_frame_hdr, .eh_frame, .gcc_except_table |
| 462 | SHO_TLS_DATA, // .tdata |
| 463 | SHO_TLS_BSS, // .tbss |
| 464 | SHO_RELRO_LOCAL, // .data.rel.ro.local |
| 465 | SHO_RELRO, // .data.rel.ro, |
| 466 | SHO_RELRO_LAST, // for x86 to adjust .got if needed |
| 467 | SHO_NON_RELRO_FIRST, // for x86 to adjust .got.plt if needed |
| 468 | SHO_DATA, // .data |
| 469 | SHO_LARGE_DATA, // .ldata |
| 470 | SHO_RW_NOTE, // |
| 471 | SHO_SMALL_DATA, // .sdata |
| 472 | SHO_SMALL_BSS, // .sbss |
| 473 | SHO_BSS, // .bss |
| 474 | SHO_LARGE_BSS, // .lbss |
| 475 | SHO_UNDEFINED, // default order |
| 476 | SHO_STRTAB // .strtab |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 477 | }; |
| 478 | |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 479 | // for -z combreloc |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 480 | struct RelocCompare { |
| 481 | explicit RelocCompare(const GNULDBackend& pBackend) : m_Backend(pBackend) {} |
Stephen Hines | a6c24df | 2015-03-18 14:53:18 -0700 | [diff] [blame] | 482 | bool operator()(const Relocation& X, const Relocation& Y) const; |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 483 | |
| 484 | private: |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 485 | const GNULDBackend& m_Backend; |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 486 | }; |
| 487 | |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 488 | // for gnu style hash table |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 489 | struct DynsymCompare { |
Stephen Hines | 6f75755 | 2013-03-04 19:51:03 -0800 | [diff] [blame] | 490 | bool needGNUHash(const LDSymbol& X) const; |
| 491 | |
| 492 | bool operator()(const LDSymbol* X, const LDSymbol* Y) const; |
| 493 | }; |
| 494 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 495 | struct SymCompare { |
| 496 | bool operator()(const LDSymbol* X, const LDSymbol* Y) const { |
| 497 | return (X == Y); |
| 498 | } |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 499 | }; |
| 500 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 501 | struct SymPtrHash { |
| 502 | size_t operator()(const LDSymbol* pKey) const { |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 503 | return (unsigned((uintptr_t)pKey) >> 4) ^ |
| 504 | (unsigned((uintptr_t)pKey) >> 9); |
| 505 | } |
| 506 | }; |
| 507 | |
| 508 | typedef HashEntry<LDSymbol*, size_t, SymCompare> SymHashEntryType; |
| 509 | typedef HashTable<SymHashEntryType, |
| 510 | SymPtrHash, |
| 511 | EntryFactory<SymHashEntryType> > HashTableType; |
| 512 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 513 | protected: |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 514 | ELFObjectReader* m_pObjectReader; |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 515 | |
| 516 | // ----- file formats ----- // |
| 517 | ELFDynObjFileFormat* m_pDynObjFileFormat; |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 518 | ELFExecFileFormat* m_pExecFileFormat; |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 519 | ELFObjectFileFormat* m_pObjectFileFormat; |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 520 | |
Shih-wei Liao | d0fbbb2 | 2013-01-03 06:23:31 -0800 | [diff] [blame] | 521 | // GNUInfo |
| 522 | GNUInfo* m_pInfo; |
| 523 | |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 524 | // ELF segment factory |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 525 | ELFSegmentFactory* m_pELFSegmentTable; |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 526 | |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 527 | // branch island factory |
| 528 | BranchIslandFactory* m_pBRIslandFactory; |
| 529 | |
| 530 | // stub factory |
| 531 | StubFactory* m_pStubFactory; |
| 532 | |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 533 | // map the LDSymbol to its index in the output symbol table |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 534 | HashTableType* m_pSymIndexMap; |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 535 | |
| 536 | // section .eh_frame_hdr |
| 537 | EhFrameHdr* m_pEhFrameHdr; |
| 538 | |
Stephen Hines | 87f3465 | 2014-02-14 18:00:16 -0800 | [diff] [blame] | 539 | // attribute section |
| 540 | ELFAttribute* m_pAttribute; |
| 541 | |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 542 | // ----- dynamic flags ----- // |
| 543 | // DF_TEXTREL of DT_FLAGS |
| 544 | bool m_bHasTextRel; |
| 545 | |
| 546 | // DF_STATIC_TLS of DT_FLAGS |
| 547 | bool m_bHasStaticTLS; |
| 548 | |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 549 | // ----- standard symbols ----- // |
| 550 | // section symbols |
| 551 | LDSymbol* f_pPreInitArrayStart; |
| 552 | LDSymbol* f_pPreInitArrayEnd; |
| 553 | LDSymbol* f_pInitArrayStart; |
| 554 | LDSymbol* f_pInitArrayEnd; |
| 555 | LDSymbol* f_pFiniArrayStart; |
| 556 | LDSymbol* f_pFiniArrayEnd; |
| 557 | LDSymbol* f_pStack; |
Shih-wei Liao | 22add6f | 2012-12-15 17:21:00 -0800 | [diff] [blame] | 558 | LDSymbol* f_pDynamic; |
| 559 | |
| 560 | // section symbols for .tdata and .tbss |
| 561 | LDSymbol* f_pTDATA; |
| 562 | LDSymbol* f_pTBSS; |
Zonr Chang | affc150 | 2012-07-16 14:28:23 +0800 | [diff] [blame] | 563 | |
| 564 | // segment symbols |
| 565 | LDSymbol* f_pExecutableStart; |
| 566 | LDSymbol* f_pEText; |
| 567 | LDSymbol* f_p_EText; |
| 568 | LDSymbol* f_p__EText; |
| 569 | LDSymbol* f_pEData; |
| 570 | LDSymbol* f_p_EData; |
| 571 | LDSymbol* f_pBSSStart; |
| 572 | LDSymbol* f_pEnd; |
| 573 | LDSymbol* f_p_End; |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 574 | }; |
| 575 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 576 | } // namespace mcld |
Shih-wei Liao | 5460a1f | 2012-03-16 22:41:16 -0700 | [diff] [blame] | 577 | |
Stephen Hines | 37b74a3 | 2014-11-26 18:48:20 -0800 | [diff] [blame] | 578 | #endif // MCLD_TARGET_GNULDBACKEND_H_ |