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