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