blob: a3960844ce0a9d1d4a89314178f6a8f5bf306905 [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 Hines37b74a32014-11-26 18:48:20 -08009#ifndef MCLD_TARGET_GNULDBACKEND_H_
10#define MCLD_TARGET_GNULDBACKEND_H_
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070011
Stephen Hines37b74a32014-11-26 18:48:20 -080012#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 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 BranchIslandFactory;
Stephen Hines37b74a32014-11-26 18:48:20 -080027class EhFrameHdr;
Stephen Hines87f34652014-02-14 18:00:16 -080028class ELFAttribute;
29class ELFDynamic;
30class ELFDynObjFileFormat;
31class ELFExecFileFormat;
Stephen Hines37b74a32014-11-26 18:48:20 -080032class ELFFileFormat;
Stephen Hines87f34652014-02-14 18:00:16 -080033class ELFObjectFileFormat;
Stephen Hines37b74a32014-11-26 18:48:20 -080034class ELFSegmentFactory;
35class GNUInfo;
36class IRBuilder;
37class Layout;
38class LinkerConfig;
Stephen Hines87f34652014-02-14 18:00:16 -080039class LinkerScript;
Stephen Hines37b74a32014-11-26 18:48:20 -080040class Module;
Stephen Hines87f34652014-02-14 18:00:16 -080041class Relocation;
Stephen Hines37b74a32014-11-26 18:48:20 -080042class StubFactory;
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 */
Stephen Hines37b74a32014-11-26 18:48:20 -080048class GNULDBackend : public TargetLDBackend {
49 protected:
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -080050 GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070051
Stephen Hines37b74a32014-11-26 18:48:20 -080052 public:
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070053 virtual ~GNULDBackend();
54
Zonr Changaffc1502012-07-16 14:28:23 +080055 // ----- readers/writers ----- //
Shih-wei Liao22add6f2012-12-15 17:21:00 -080056 GNUArchiveReader* createArchiveReader(Module& pModule);
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -080057 ELFObjectReader* createObjectReader(IRBuilder& pBuilder);
58 ELFDynObjReader* createDynObjReader(IRBuilder& pBuilder);
59 ELFBinaryReader* createBinaryReader(IRBuilder& pBuilder);
Stephen Hines6f757552013-03-04 19:51:03 -080060 ELFObjectWriter* createWriter();
Zonr Changaffc1502012-07-16 14:28:23 +080061
62 // ----- output sections ----- //
Shih-wei Liao22add6f2012-12-15 17:21:00 -080063 /// initStdSections - initialize standard sections of the output file.
64 bool initStdSections(ObjectBuilder& pBuilder);
Zonr Changaffc1502012-07-16 14:28:23 +080065
66 /// getOutputFormat - get the sections of the output file.
Shih-wei Liao22add6f2012-12-15 17:21:00 -080067 const ELFFileFormat* getOutputFormat() const;
Stephen Hines37b74a32014-11-26 18:48:20 -080068 ELFFileFormat* getOutputFormat();
Zonr Changaffc1502012-07-16 14:28:23 +080069
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 Hines6f757552013-03-04 19:51:03 -080074 /// undefined symbol in input objects. ObjectLinker must finalize its value
Zonr Changaffc1502012-07-16 14:28:23 +080075 /// 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 Hines6f757552013-03-04 19:51:03 -080078 bool initStandardSymbols(IRBuilder& pBuilder, Module& pModule);
Zonr Changaffc1502012-07-16 14:28:23 +080079
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 Hines6f757552013-03-04 19:51:03 -080084 bool finalizeSymbols() {
Stephen Hines37b74a32014-11-26 18:48:20 -080085 return (finalizeStandardSymbols() && finalizeTargetSymbols());
Zonr Changaffc1502012-07-16 14:28:23 +080086 }
87
88 /// finalizeStandardSymbols - set the value of standard symbols
Stephen Hines6f757552013-03-04 19:51:03 -080089 virtual bool finalizeStandardSymbols();
Zonr Changaffc1502012-07-16 14:28:23 +080090
91 /// finalizeTargetSymbols - set the value of target symbols
Stephen Hines6f757552013-03-04 19:51:03 -080092 virtual bool finalizeTargetSymbols() = 0;
Shih-wei Liao22add6f2012-12-15 17:21:00 -080093
94 /// finalizeTLSSymbol - set the value of a TLS symbol
95 virtual bool finalizeTLSSymbol(LDSymbol& pSymbol);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070096
97 size_t sectionStartOffset() const;
98
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -080099 const GNUInfo& getInfo() const { return *m_pInfo; }
Stephen Hines37b74a32014-11-26 18:48:20 -0800100 GNUInfo& getInfo() { return *m_pInfo; }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700101
Stephen Hines6f757552013-03-04 19:51:03 -0800102 bool hasTextRel() const { return m_bHasTextRel; }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700103
Stephen Hines6f757552013-03-04 19:51:03 -0800104 bool hasStaticTLS() const { return m_bHasStaticTLS; }
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800105
Stephen Hines37b74a32014-11-26 18:48:20 -0800106 /// getSegmentStartAddr - return the start address of the segment
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700107 uint64_t getSegmentStartAddr(const LinkerScript& pScript) const;
Zonr Changaffc1502012-07-16 14:28:23 +0800108
Stephen Hines87f34652014-02-14 18:00:16 -0800109 /// sizeShstrtab - compute the size of .shstrtab
110 void sizeShstrtab(Module& pModule);
111
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700112 /// 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 Hinesf7ac0f12013-05-03 19:09:24 -0700115 virtual void sizeNamePools(Module& pModule);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700116
117 /// emitSectionData - emit target-dependent section data
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800118 virtual uint64_t emitSectionData(const LDSection& pSection,
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700119 MemoryRegion& pRegion) const = 0;
120
121 /// emitRegNamePools - emit regular name pools - .symtab, .strtab
Stephen Hines37b74a32014-11-26 18:48:20 -0800122 virtual void emitRegNamePools(const Module& pModule,
123 FileOutputBuffer& pOutput);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700124
125 /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
Stephen Hines87f34652014-02-14 18:00:16 -0800126 virtual void emitDynNamePools(Module& pModule, FileOutputBuffer& pOutput);
Stephen Hines6f757552013-03-04 19:51:03 -0800127
128 /// emitELFHashTab - emit .hash
129 virtual void emitELFHashTab(const Module::SymbolTable& pSymtab,
Stephen Hines87f34652014-02-14 18:00:16 -0800130 FileOutputBuffer& pOutput);
Stephen Hines6f757552013-03-04 19:51:03 -0800131
132 /// emitGNUHashTab - emit .gnu.hash
133 virtual void emitGNUHashTab(Module::SymbolTable& pSymtab,
Stephen Hines87f34652014-02-14 18:00:16 -0800134 FileOutputBuffer& pOutput);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700135
Zonr Changaffc1502012-07-16 14:28:23 +0800136 /// 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 Liao22add6f2012-12-15 17:21:00 -0800138 virtual void sizeInterp();
Zonr Changaffc1502012-07-16 14:28:23 +0800139
140 /// emitInterp - emit the .interp
Stephen Hines87f34652014-02-14 18:00:16 -0800141 virtual void emitInterp(FileOutputBuffer& pOutput);
Zonr Changaffc1502012-07-16 14:28:23 +0800142
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700143 /// 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 Hines37b74a32014-11-26 18:48:20 -0800149 void setHasStaticTLS(bool pVal = true) { m_bHasStaticTLS = pVal; }
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700150
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700151 /// 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 Liao22add6f2012-12-15 17:21:00 -0800160 virtual unsigned int getSectionOrder(const LDSection& pSectHdr) const;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700161
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 Hines37b74a32014-11-26 18:48:20 -0800168 virtual unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const {
169 return (unsigned int)-1;
170 }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700171
Stephen Hines87f34652014-02-14 18:00:16 -0800172 /// elfSegmentTable - return the reference of the elf segment table
Stephen Hines37b74a32014-11-26 18:48:20 -0800173 ELFSegmentFactory& elfSegmentTable();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700174
Zonr Changaffc1502012-07-16 14:28:23 +0800175 /// elfSegmentTable - return the reference of the elf segment table
Stephen Hines87f34652014-02-14 18:00:16 -0800176 const ELFSegmentFactory& elfSegmentTable() const;
Zonr Changaffc1502012-07-16 14:28:23 +0800177
Stephen Hines6f757552013-03-04 19:51:03 -0800178 /// commonPageSize - the common page size of the target machine
179 uint64_t commonPageSize() const;
Zonr Changaffc1502012-07-16 14:28:23 +0800180
Stephen Hines6f757552013-03-04 19:51:03 -0800181 /// abiPageSize - the abi page size of the target machine
182 uint64_t abiPageSize() const;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700183
184 /// getSymbolIdx - get the symbol index of ouput symbol table
Stephen Hines6f757552013-03-04 19:51:03 -0800185 size_t getSymbolIdx(const LDSymbol* pSymbol) const;
Zonr Changaffc1502012-07-16 14:28:23 +0800186
187 /// allocateCommonSymbols - allocate common symbols in the corresponding
188 /// sections.
189 /// Different concrete target backend may overlap this function.
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800190 virtual bool allocateCommonSymbols(Module& pModule);
Zonr Changaffc1502012-07-16 14:28:23 +0800191
Stephen Hinesb0d0eb22016-03-08 00:18:09 -0800192 /// mergeFlags - update set of ELF header flags
193 virtual void mergeFlags(Input& pInput, const char* ELF_hdr) {}
194
Stephen Hines6f757552013-03-04 19:51:03 -0800195 /// 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 Hines87f34652014-02-14 18:00:16 -0800199 /// 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 Hinesf7ac0f12013-05-03 19:09:24 -0700251 /// symbolNeedsPLT - return whether the symbol needs a PLT entry
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700252 bool symbolNeedsPLT(const ResolveInfo& pSym) const;
Zonr Changaffc1502012-07-16 14:28:23 +0800253
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700254 /// symbolNeedsCopyReloc - return whether the symbol needs a copy relocation
255 bool symbolNeedsCopyReloc(const Relocation& pReloc,
256 const ResolveInfo& pSym) const;
Stephen Hines6f757552013-03-04 19:51:03 -0800257
Shih-wei Liao67e37f12012-07-27 03:50:34 -0700258 /// symbolNeedsDynRel - return whether the symbol needs a dynamic relocation
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 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 Hines87f34652014-02-14 18:00:16 -0800272 bool isDynamicSymbol(const LDSymbol& pSymbol) const;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700273
274 /// isDynamicSymbol
Stephen Hines87f34652014-02-14 18:00:16 -0800275 bool isDynamicSymbol(const ResolveInfo& pResolveInfo) const;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700276
277 virtual ResolveInfo::Desc getSymDesc(uint16_t pShndx) const {
278 return ResolveInfo::Define;
279 }
280
Stephen Hines37b74a32014-11-26 18:48:20 -0800281 bool hasTDATASymbol() const { return (f_pTDATA != NULL); }
282 bool hasTBSSSymbol() const { return (f_pTBSS != NULL); }
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700283
284 void setTDATASymbol(LDSymbol& pTDATA) { f_pTDATA = &pTDATA; }
Stephen Hines37b74a32014-11-26 18:48:20 -0800285 void setTBSSSymbol(LDSymbol& pTBSS) { f_pTBSS = &pTBSS; }
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700286
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800287 // 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 Hines87f34652014-02-14 18:00:16 -0800295 /// getEntry - get the entry point name
296 llvm::StringRef getEntry(const Module& pModule) const;
297
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800298 // ----- 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 Hines37b74a32014-11-26 18:48:20 -0800309 StubFactory* getStubFactory() { return m_pStubFactory; }
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800310
Stephen Hines0dea6bc2014-07-15 18:33:32 -0700311 /// maxFwdBranchOffset - return the max forward branch offset of the backend.
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800312 /// Target can override this function if needed.
Stephen Hinesb0d0eb22016-03-08 00:18:09 -0800313 virtual int64_t maxFwdBranchOffset() const { return INT64_MAX; }
Stephen Hines0dea6bc2014-07-15 18:33:32 -0700314
315 /// maxBwdBranchOffset - return the max backward branch offset of the backend.
316 /// Target can override this function if needed.
Stephen Hinesb0d0eb22016-03-08 00:18:09 -0800317 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 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
Stephen Hines37b74a32014-11-26 18:48:20 -0800343 protected:
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.
Zonr Changaffc1502012-07-16 14:28:23 +0800362 static unsigned getHashBucketCount(unsigned pNumOfSymbols, bool pIsGNUStyle);
363
Stephen Hines6f757552013-03-04 19:51:03 -0800364 /// getGNUHashMaskbitslog2 - calculate the number of mask bits in log2
Stephen Hines6f757552013-03-04 19:51:03 -0800365 unsigned getGNUHashMaskbitslog2(unsigned pNumOfSymbols) const;
366
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800367 /// 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 Hinesa6c24df2015-03-18 14:53:18 -0700381 protected:
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700382 /// createProgramHdrs - base on output sections to create the program headers
Stephen Hines6f757552013-03-04 19:51:03 -0800383 void createProgramHdrs(Module& pModule);
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800384
385 /// doCreateProgramHdrs - backend can implement this function to create the
386 /// target-dependent segments
Stephen Hines6f757552013-03-04 19:51:03 -0800387 virtual void doCreateProgramHdrs(Module& pModule) = 0;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700388
Zonr Changaffc1502012-07-16 14:28:23 +0800389 /// setupProgramHdrs - set up the attributes of segments
390 /// (i.e., offset, addresses, file/mem size, flag, and alignment)
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700391 void setupProgramHdrs(const LinkerScript& pScript);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700392
393 /// getSegmentFlag - give a section flag and return the corresponding segment
394 /// flag
Stephen Hines87f34652014-02-14 18:00:16 -0800395 inline uint32_t getSegmentFlag(const uint32_t pSectionFlag);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700396
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800397 /// setupGNUStackInfo - setup the section flag of .note.GNU-stack in output
Stephen Hines6f757552013-03-04 19:51:03 -0800398 void setupGNUStackInfo(Module& pModule);
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800399
Stephen Hines87f34652014-02-14 18:00:16 -0800400 /// setOutputSectionOffset - helper function to set output sections' offset.
401 void setOutputSectionOffset(Module& pModule);
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800402
Stephen Hines87f34652014-02-14 18:00:16 -0800403 /// setOutputSectionAddress - helper function to set output sections' address.
404 void setOutputSectionAddress(Module& pModule);
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800405
Stephen Hines87f34652014-02-14 18:00:16 -0800406 /// placeOutputSections - place output sections based on SectionMap
407 void placeOutputSections(Module& pModule);
Zonr Changaffc1502012-07-16 14:28:23 +0800408
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800409 /// layout - layout method
Stephen Hines6f757552013-03-04 19:51:03 -0800410 void layout(Module& pModule);
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800411
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700412 /// preLayout - Backend can do any needed modification before layout
Stephen Hines6f757552013-03-04 19:51:03 -0800413 void preLayout(Module& pModule, IRBuilder& pBuilder);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700414
415 /// postLayout -Backend can do any needed modification after layout
Stephen Hines6f757552013-03-04 19:51:03 -0800416 void postLayout(Module& pModule, IRBuilder& pBuilder);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700417
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700418 /// preLayout - Backend can do any needed modification before layout
Stephen Hines6f757552013-03-04 19:51:03 -0800419 virtual void doPreLayout(IRBuilder& pBuilder) = 0;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700420
421 /// postLayout -Backend can do any needed modification after layout
Stephen Hines6f757552013-03-04 19:51:03 -0800422 virtual void doPostLayout(Module& pModule, IRBuilder& pLinker) = 0;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700423
Zonr Changaffc1502012-07-16 14:28:23 +0800424 /// postProcessing - Backend can do any needed modification in the final stage
Stephen Hines87f34652014-02-14 18:00:16 -0800425 void postProcessing(FileOutputBuffer& pOutput);
Zonr Changaffc1502012-07-16 14:28:23 +0800426
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700427 /// 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 Liao22add6f2012-12-15 17:21:00 -0800433 /// relax - the relaxation pass
Stephen Hinesa6c24df2015-03-18 14:53:18 -0700434 virtual bool relax(Module& pModule, IRBuilder& pBuilder);
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800435
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 Hines37b74a32014-11-26 18:48:20 -0800443 virtual bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished) {
444 return false;
445 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800446
Stephen Hines37b74a32014-11-26 18:48:20 -0800447 protected:
448 // Based on Kind in LDFileFormat to define basic section orders for ELF.
Zonr Changaffc1502012-07-16 14:28:23 +0800449 enum SectionOrder {
Stephen Hines37b74a32014-11-26 18:48:20 -0800450 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 Changaffc1502012-07-16 14:28:23 +0800477 };
478
Stephen Hines87f34652014-02-14 18:00:16 -0800479 // for -z combreloc
Stephen Hines37b74a32014-11-26 18:48:20 -0800480 struct RelocCompare {
481 explicit RelocCompare(const GNULDBackend& pBackend) : m_Backend(pBackend) {}
Stephen Hinesa6c24df2015-03-18 14:53:18 -0700482 bool operator()(const Relocation& X, const Relocation& Y) const;
Stephen Hines37b74a32014-11-26 18:48:20 -0800483
484 private:
Stephen Hines87f34652014-02-14 18:00:16 -0800485 const GNULDBackend& m_Backend;
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800486 };
487
Stephen Hines6f757552013-03-04 19:51:03 -0800488 // for gnu style hash table
Stephen Hines37b74a32014-11-26 18:48:20 -0800489 struct DynsymCompare {
Stephen Hines6f757552013-03-04 19:51:03 -0800490 bool needGNUHash(const LDSymbol& X) const;
491
492 bool operator()(const LDSymbol* X, const LDSymbol* Y) const;
493 };
494
Stephen Hines37b74a32014-11-26 18:48:20 -0800495 struct SymCompare {
496 bool operator()(const LDSymbol* X, const LDSymbol* Y) const {
497 return (X == Y);
498 }
Stephen Hines87f34652014-02-14 18:00:16 -0800499 };
500
Stephen Hines37b74a32014-11-26 18:48:20 -0800501 struct SymPtrHash {
502 size_t operator()(const LDSymbol* pKey) const {
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800503 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 Hines37b74a32014-11-26 18:48:20 -0800513 protected:
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700514 ELFObjectReader* m_pObjectReader;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700515
516 // ----- file formats ----- //
517 ELFDynObjFileFormat* m_pDynObjFileFormat;
Stephen Hines37b74a32014-11-26 18:48:20 -0800518 ELFExecFileFormat* m_pExecFileFormat;
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800519 ELFObjectFileFormat* m_pObjectFileFormat;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700520
Shih-wei Liaod0fbbb22013-01-03 06:23:31 -0800521 // GNUInfo
522 GNUInfo* m_pInfo;
523
Zonr Changaffc1502012-07-16 14:28:23 +0800524 // ELF segment factory
Stephen Hines87f34652014-02-14 18:00:16 -0800525 ELFSegmentFactory* m_pELFSegmentTable;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700526
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800527 // branch island factory
528 BranchIslandFactory* m_pBRIslandFactory;
529
530 // stub factory
531 StubFactory* m_pStubFactory;
532
Zonr Changaffc1502012-07-16 14:28:23 +0800533 // map the LDSymbol to its index in the output symbol table
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700534 HashTableType* m_pSymIndexMap;
Zonr Changaffc1502012-07-16 14:28:23 +0800535
536 // section .eh_frame_hdr
537 EhFrameHdr* m_pEhFrameHdr;
538
Stephen Hines87f34652014-02-14 18:00:16 -0800539 // attribute section
540 ELFAttribute* m_pAttribute;
541
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800542 // ----- 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 Changaffc1502012-07-16 14:28:23 +0800549 // ----- 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 Liao22add6f2012-12-15 17:21:00 -0800558 LDSymbol* f_pDynamic;
559
560 // section symbols for .tdata and .tbss
561 LDSymbol* f_pTDATA;
562 LDSymbol* f_pTBSS;
Zonr Changaffc1502012-07-16 14:28:23 +0800563
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 Liao5460a1f2012-03-16 22:41:16 -0700574};
575
Stephen Hines37b74a32014-11-26 18:48:20 -0800576} // namespace mcld
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700577
Stephen Hines37b74a32014-11-26 18:48:20 -0800578#endif // MCLD_TARGET_GNULDBACKEND_H_