blob: 351111dda35557280d59a86024a92f0155c21796 [file] [log] [blame]
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001//===- 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 Hines87f34652014-02-14 18:00:16 -08009#ifndef MCLD_TARGET_GNULDBACKEND_H
10#define MCLD_TARGET_GNULDBACKEND_H
Shih-wei Liao22add6f2012-12-15 17:21:00 -080011#include <mcld/Target/TargetLDBackend.h>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070012
Stephen Hines87f34652014-02-14 18:00:16 -080013#include <mcld/Module.h>
Shih-wei Liao22add6f2012-12-15 17:21:00 -080014#include <mcld/LD/GNUArchiveReader.h>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070015#include <mcld/LD/ELFDynObjReader.h>
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -080016#include <mcld/LD/ELFBinaryReader.h>
Stephen Hines87f34652014-02-14 18:00:16 -080017#include <mcld/LD/ELFObjectReader.h>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070018#include <mcld/LD/ELFObjectWriter.h>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070019
Stephen Hines87f34652014-02-14 18:00:16 -080020#include <llvm/Support/ELF.h>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070021
Stephen Hines0dea6bc2014-07-15 18:33:32 -070022#include <cstdint>
23
Shih-wei Liao22add6f2012-12-15 17:21:00 -080024namespace mcld {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070025
Shih-wei Liao22add6f2012-12-15 17:21:00 -080026class Module;
27class LinkerConfig;
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -080028class IRBuilder;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070029class Layout;
Shih-wei Liao22add6f2012-12-15 17:21:00 -080030class EhFrameHdr;
31class BranchIslandFactory;
32class StubFactory;
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -080033class GNUInfo;
Stephen Hines87f34652014-02-14 18:00:16 -080034class ELFFileFormat;
35class ELFSegmentFactory;
36class ELFAttribute;
37class ELFDynamic;
38class ELFDynObjFileFormat;
39class ELFExecFileFormat;
40class ELFObjectFileFormat;
41class LinkerScript;
42class Relocation;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070043
44/** \class GNULDBackend
45 * \brief GNULDBackend provides a common interface for all GNU Unix-OS
46 * LDBackend.
47 */
48class GNULDBackend : public TargetLDBackend
49{
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070050protected:
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -080051 GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070052
53public:
54 virtual ~GNULDBackend();
55
Zonr Changaffc1502012-07-16 14:28:23 +080056 // ----- readers/writers ----- //
Shih-wei Liao22add6f2012-12-15 17:21:00 -080057 GNUArchiveReader* createArchiveReader(Module& pModule);
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -080058 ELFObjectReader* createObjectReader(IRBuilder& pBuilder);
59 ELFDynObjReader* createDynObjReader(IRBuilder& pBuilder);
60 ELFBinaryReader* createBinaryReader(IRBuilder& pBuilder);
Stephen Hines6f757552013-03-04 19:51:03 -080061 ELFObjectWriter* createWriter();
Zonr Changaffc1502012-07-16 14:28:23 +080062
63 // ----- output sections ----- //
Shih-wei Liao22add6f2012-12-15 17:21:00 -080064 /// initStdSections - initialize standard sections of the output file.
65 bool initStdSections(ObjectBuilder& pBuilder);
Zonr Changaffc1502012-07-16 14:28:23 +080066
67 /// getOutputFormat - get the sections of the output file.
Shih-wei Liao22add6f2012-12-15 17:21:00 -080068 const ELFFileFormat* getOutputFormat() const;
69 ELFFileFormat* getOutputFormat();
Zonr Changaffc1502012-07-16 14:28:23 +080070
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 Hines6f757552013-03-04 19:51:03 -080075 /// undefined symbol in input objects. ObjectLinker must finalize its value
Zonr Changaffc1502012-07-16 14:28:23 +080076 /// 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 Hines6f757552013-03-04 19:51:03 -080079 bool initStandardSymbols(IRBuilder& pBuilder, Module& pModule);
Zonr Changaffc1502012-07-16 14:28:23 +080080
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 Hines6f757552013-03-04 19:51:03 -080085 bool finalizeSymbols() {
86 return (finalizeStandardSymbols() &&
87 finalizeTargetSymbols());
Zonr Changaffc1502012-07-16 14:28:23 +080088 }
89
90 /// finalizeStandardSymbols - set the value of standard symbols
Stephen Hines6f757552013-03-04 19:51:03 -080091 virtual bool finalizeStandardSymbols();
Zonr Changaffc1502012-07-16 14:28:23 +080092
93 /// finalizeTargetSymbols - set the value of target symbols
Stephen Hines6f757552013-03-04 19:51:03 -080094 virtual bool finalizeTargetSymbols() = 0;
Shih-wei Liao22add6f2012-12-15 17:21:00 -080095
96 /// finalizeTLSSymbol - set the value of a TLS symbol
97 virtual bool finalizeTLSSymbol(LDSymbol& pSymbol);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070098
99 size_t sectionStartOffset() const;
100
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800101 const GNUInfo& getInfo() const { return *m_pInfo; }
102 GNUInfo& getInfo() { return *m_pInfo; }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700103
Stephen Hines6f757552013-03-04 19:51:03 -0800104 bool hasTextRel() const { return m_bHasTextRel; }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700105
Stephen Hines6f757552013-03-04 19:51:03 -0800106 bool hasStaticTLS() const { return m_bHasStaticTLS; }
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800107
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700108 /// getSegmentStartAddr - this function returns the start address of the segment
109 uint64_t getSegmentStartAddr(const LinkerScript& pScript) const;
Zonr Changaffc1502012-07-16 14:28:23 +0800110
Stephen Hines87f34652014-02-14 18:00:16 -0800111 /// sizeShstrtab - compute the size of .shstrtab
112 void sizeShstrtab(Module& pModule);
113
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700114 /// 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 Hinesf7ac0f12013-05-03 19:09:24 -0700117 virtual void sizeNamePools(Module& pModule);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700118
119 /// emitSectionData - emit target-dependent section data
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800120 virtual uint64_t emitSectionData(const LDSection& pSection,
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700121 MemoryRegion& pRegion) const = 0;
122
123 /// emitRegNamePools - emit regular name pools - .symtab, .strtab
Stephen Hines87f34652014-02-14 18:00:16 -0800124 virtual void emitRegNamePools(const Module& pModule, FileOutputBuffer& pOutput);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700125
126 /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
Stephen Hines87f34652014-02-14 18:00:16 -0800127 virtual void emitDynNamePools(Module& pModule, FileOutputBuffer& pOutput);
Stephen Hines6f757552013-03-04 19:51:03 -0800128
129 /// emitELFHashTab - emit .hash
130 virtual void emitELFHashTab(const Module::SymbolTable& pSymtab,
Stephen Hines87f34652014-02-14 18:00:16 -0800131 FileOutputBuffer& pOutput);
Stephen Hines6f757552013-03-04 19:51:03 -0800132
133 /// emitGNUHashTab - emit .gnu.hash
134 virtual void emitGNUHashTab(Module::SymbolTable& pSymtab,
Stephen Hines87f34652014-02-14 18:00:16 -0800135 FileOutputBuffer& pOutput);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700136
Zonr Changaffc1502012-07-16 14:28:23 +0800137 /// 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 Liao22add6f2012-12-15 17:21:00 -0800139 virtual void sizeInterp();
Zonr Changaffc1502012-07-16 14:28:23 +0800140
141 /// emitInterp - emit the .interp
Stephen Hines87f34652014-02-14 18:00:16 -0800142 virtual void emitInterp(FileOutputBuffer& pOutput);
Zonr Changaffc1502012-07-16 14:28:23 +0800143
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700144 /// 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 Liao5460a1f2012-03-16 22:41:16 -0700153 /// 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 Liao22add6f2012-12-15 17:21:00 -0800162 virtual unsigned int getSectionOrder(const LDSection& pSectHdr) const;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700163
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 Liao22add6f2012-12-15 17:21:00 -0800170 virtual unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700171 { return (unsigned int)-1; }
172
Stephen Hines87f34652014-02-14 18:00:16 -0800173 /// elfSegmentTable - return the reference of the elf segment table
174 ELFSegmentFactory& elfSegmentTable();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700175
Zonr Changaffc1502012-07-16 14:28:23 +0800176 /// elfSegmentTable - return the reference of the elf segment table
Stephen Hines87f34652014-02-14 18:00:16 -0800177 const ELFSegmentFactory& elfSegmentTable() const;
Zonr Changaffc1502012-07-16 14:28:23 +0800178
Stephen Hines6f757552013-03-04 19:51:03 -0800179 /// commonPageSize - the common page size of the target machine
180 uint64_t commonPageSize() const;
Zonr Changaffc1502012-07-16 14:28:23 +0800181
Stephen Hines6f757552013-03-04 19:51:03 -0800182 /// abiPageSize - the abi page size of the target machine
183 uint64_t abiPageSize() const;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700184
185 /// getSymbolIdx - get the symbol index of ouput symbol table
Stephen Hines6f757552013-03-04 19:51:03 -0800186 size_t getSymbolIdx(const LDSymbol* pSymbol) const;
Zonr Changaffc1502012-07-16 14:28:23 +0800187
188 /// allocateCommonSymbols - allocate common symbols in the corresponding
189 /// sections.
190 /// Different concrete target backend may overlap this function.
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800191 virtual bool allocateCommonSymbols(Module& pModule);
Zonr Changaffc1502012-07-16 14:28:23 +0800192
Stephen Hines6f757552013-03-04 19:51:03 -0800193 /// 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 Hines87f34652014-02-14 18:00:16 -0800197 /// 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 Hinesf7ac0f12013-05-03 19:09:24 -0700249 /// 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 Changaffc1502012-07-16 14:28:23 +0800252
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700253 /// symbolNeedsCopyReloc - return whether the symbol needs a copy relocation
254 bool symbolNeedsCopyReloc(const Relocation& pReloc,
255 const ResolveInfo& pSym) const;
Stephen Hines6f757552013-03-04 19:51:03 -0800256
Shih-wei Liao67e37f12012-07-27 03:50:34 -0700257 /// symbolNeedsDynRel - return whether the symbol needs a dynamic relocation
258 /// @ref Google gold linker, symtab.h:645
Stephen Hines6f757552013-03-04 19:51:03 -0800259 bool symbolNeedsDynRel(const ResolveInfo& pSym,
Shih-wei Liao67e37f12012-07-27 03:50:34 -0700260 bool pSymHasPLT,
Shih-wei Liao67e37f12012-07-27 03:50:34 -0700261 bool isAbsReloc) const;
262
Stephen Hines0dea6bc2014-07-15 18:33:32 -0700263 /// isSymbolPreemptible - whether the symbol can be preemted by other link
264 /// units
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700265 /// @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 Hines87f34652014-02-14 18:00:16 -0800274 bool isDynamicSymbol(const LDSymbol& pSymbol) const;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700275
276 /// isDynamicSymbol
277 /// @ref Google gold linker: symtab.cc:311
Stephen Hines87f34652014-02-14 18:00:16 -0800278 bool isDynamicSymbol(const ResolveInfo& pResolveInfo) const;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700279
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 Liao22add6f2012-12-15 17:21:00 -0800290 // 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 Hines87f34652014-02-14 18:00:16 -0800298 /// getEntry - get the entry point name
299 llvm::StringRef getEntry(const Module& pModule) const;
300
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800301 // ----- 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 Hines0dea6bc2014-07-15 18:33:32 -0700314 /// maxFwdBranchOffset - return the max forward branch offset of the backend.
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800315 /// Target can override this function if needed.
Stephen Hines0dea6bc2014-07-15 18:33:32 -0700316 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 Liao22add6f2012-12-15 17:21:00 -0800321
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700322 /// checkAndSetHasTextRel - check pSection flag to set HasTextRel
323 void checkAndSetHasTextRel(const LDSection& pSection);
324
Stephen Hines87f34652014-02-14 18:00:16 -0800325 /// 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 Hines0dea6bc2014-07-15 18:33:32 -0700339 /// mayHaveUnsafeFunctionPointerAccess - check if the section may have unsafe
340 /// function pointer access
341 bool mayHaveUnsafeFunctionPointerAccess(const LDSection& pSection) const;
342
Zonr Changaffc1502012-07-16 14:28:23 +0800343protected:
Stephen Hines87f34652014-02-14 18:00:16 -0800344 /// 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 Changaffc1502012-07-16 14:28:23 +0800350 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 Liao22add6f2012-12-15 17:21:00 -0800356 uint64_t getSymbolShndx(const LDSymbol& pSymbol) const;
Zonr Changaffc1502012-07-16 14:28:23 +0800357
Stephen Hines6f757552013-03-04 19:51:03 -0800358 /// isTemporary - Whether pSymbol is a local label.
359 virtual bool isTemporary(const LDSymbol& pSymbol) const;
360
Zonr Changaffc1502012-07-16 14:28:23 +0800361 /// getHashBucketCount - calculate hash bucket count.
362 /// @ref Google gold linker, dynobj.cc:791
363 static unsigned getHashBucketCount(unsigned pNumOfSymbols, bool pIsGNUStyle);
364
Stephen Hines6f757552013-03-04 19:51:03 -0800365 /// 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 Liao22add6f2012-12-15 17:21:00 -0800369 /// 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 Liao5460a1f2012-03-16 22:41:16 -0700383private:
384 /// createProgramHdrs - base on output sections to create the program headers
Stephen Hines6f757552013-03-04 19:51:03 -0800385 void createProgramHdrs(Module& pModule);
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800386
387 /// doCreateProgramHdrs - backend can implement this function to create the
388 /// target-dependent segments
Stephen Hines6f757552013-03-04 19:51:03 -0800389 virtual void doCreateProgramHdrs(Module& pModule) = 0;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700390
Zonr Changaffc1502012-07-16 14:28:23 +0800391 /// setupProgramHdrs - set up the attributes of segments
392 /// (i.e., offset, addresses, file/mem size, flag, and alignment)
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700393 void setupProgramHdrs(const LinkerScript& pScript);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700394
395 /// getSegmentFlag - give a section flag and return the corresponding segment
396 /// flag
Stephen Hines87f34652014-02-14 18:00:16 -0800397 inline uint32_t getSegmentFlag(const uint32_t pSectionFlag);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700398
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800399 /// setupGNUStackInfo - setup the section flag of .note.GNU-stack in output
Stephen Hines6f757552013-03-04 19:51:03 -0800400 void setupGNUStackInfo(Module& pModule);
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800401
Stephen Hines87f34652014-02-14 18:00:16 -0800402 /// setOutputSectionOffset - helper function to set output sections' offset.
403 void setOutputSectionOffset(Module& pModule);
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800404
Stephen Hines87f34652014-02-14 18:00:16 -0800405 /// setOutputSectionAddress - helper function to set output sections' address.
406 void setOutputSectionAddress(Module& pModule);
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800407
Stephen Hines87f34652014-02-14 18:00:16 -0800408 /// placeOutputSections - place output sections based on SectionMap
409 void placeOutputSections(Module& pModule);
Zonr Changaffc1502012-07-16 14:28:23 +0800410
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800411 /// layout - layout method
Stephen Hines6f757552013-03-04 19:51:03 -0800412 void layout(Module& pModule);
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800413
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700414 /// preLayout - Backend can do any needed modification before layout
Stephen Hines6f757552013-03-04 19:51:03 -0800415 void preLayout(Module& pModule, IRBuilder& pBuilder);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700416
417 /// postLayout -Backend can do any needed modification after layout
Stephen Hines6f757552013-03-04 19:51:03 -0800418 void postLayout(Module& pModule, IRBuilder& pBuilder);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700419
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700420 /// preLayout - Backend can do any needed modification before layout
Stephen Hines6f757552013-03-04 19:51:03 -0800421 virtual void doPreLayout(IRBuilder& pBuilder) = 0;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700422
423 /// postLayout -Backend can do any needed modification after layout
Stephen Hines6f757552013-03-04 19:51:03 -0800424 virtual void doPostLayout(Module& pModule, IRBuilder& pLinker) = 0;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700425
Zonr Changaffc1502012-07-16 14:28:23 +0800426 /// postProcessing - Backend can do any needed modification in the final stage
Stephen Hines87f34652014-02-14 18:00:16 -0800427 void postProcessing(FileOutputBuffer& pOutput);
Zonr Changaffc1502012-07-16 14:28:23 +0800428
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700429 /// 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 Liao22add6f2012-12-15 17:21:00 -0800435 /// relax - the relaxation pass
Stephen Hines6f757552013-03-04 19:51:03 -0800436 bool relax(Module& pModule, IRBuilder& pBuilder);
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800437
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 Hines6f757552013-03-04 19:51:03 -0800445 virtual bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished)
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800446 { return false; }
447
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700448protected:
Zonr Changaffc1502012-07-16 14:28:23 +0800449 // 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 Hines87f34652014-02-14 18:00:16 -0800452 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 Changaffc1502012-07-16 14:28:23 +0800479 };
480
Stephen Hines87f34652014-02-14 18:00:16 -0800481 // for -z combreloc
482 struct RelocCompare
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800483 {
Stephen Hines87f34652014-02-14 18:00:16 -0800484 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 Liao22add6f2012-12-15 17:21:00 -0800490 };
491
Stephen Hines6f757552013-03-04 19:51:03 -0800492 // 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 Hines87f34652014-02-14 18:00:16 -0800500 struct SymCompare
501 {
502 bool operator()(const LDSymbol* X, const LDSymbol* Y) const
503 { return (X==Y); }
504 };
505
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800506 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 Changaffc1502012-07-16 14:28:23 +0800520
521protected:
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700522 ELFObjectReader* m_pObjectReader;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700523
524 // ----- file formats ----- //
525 ELFDynObjFileFormat* m_pDynObjFileFormat;
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800526 ELFExecFileFormat* m_pExecFileFormat;
527 ELFObjectFileFormat* m_pObjectFileFormat;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700528
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800529 // GNUInfo
530 GNUInfo* m_pInfo;
531
Zonr Changaffc1502012-07-16 14:28:23 +0800532 // ELF segment factory
Stephen Hines87f34652014-02-14 18:00:16 -0800533 ELFSegmentFactory* m_pELFSegmentTable;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700534
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800535 // branch island factory
536 BranchIslandFactory* m_pBRIslandFactory;
537
538 // stub factory
539 StubFactory* m_pStubFactory;
540
Zonr Changaffc1502012-07-16 14:28:23 +0800541 // map the LDSymbol to its index in the output symbol table
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700542 HashTableType* m_pSymIndexMap;
Zonr Changaffc1502012-07-16 14:28:23 +0800543
544 // section .eh_frame_hdr
545 EhFrameHdr* m_pEhFrameHdr;
546
Stephen Hines87f34652014-02-14 18:00:16 -0800547 // attribute section
548 ELFAttribute* m_pAttribute;
549
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800550 // ----- 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 Changaffc1502012-07-16 14:28:23 +0800557 // ----- 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 Liao22add6f2012-12-15 17:21:00 -0800566 LDSymbol* f_pDynamic;
567
568 // section symbols for .tdata and .tbss
569 LDSymbol* f_pTDATA;
570 LDSymbol* f_pTBSS;
Zonr Changaffc1502012-07-16 14:28:23 +0800571
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 Liao5460a1f2012-03-16 22:41:16 -0700582};
583
584} // namespace of mcld
585
586#endif
587