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 #include <mcld/Target/TargetLDBackend.h>
12 
13 #include <mcld/Module.h>
14 #include <mcld/LD/GNUArchiveReader.h>
15 #include <mcld/LD/ELFDynObjReader.h>
16 #include <mcld/LD/ELFBinaryReader.h>
17 #include <mcld/LD/ELFObjectReader.h>
18 #include <mcld/LD/ELFObjectWriter.h>
19 
20 #include <llvm/Support/ELF.h>
21 
22 #include <cstdint>
23 
24 namespace mcld {
25 
26 class Module;
27 class LinkerConfig;
28 class IRBuilder;
29 class Layout;
30 class EhFrameHdr;
31 class BranchIslandFactory;
32 class StubFactory;
33 class GNUInfo;
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;
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 {
50 protected:
51   GNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo);
52 
53 public:
54   virtual ~GNULDBackend();
55 
56   // -----  readers/writers  ----- //
57   GNUArchiveReader* createArchiveReader(Module& pModule);
58   ELFObjectReader* createObjectReader(IRBuilder& pBuilder);
59   ELFDynObjReader* createDynObjReader(IRBuilder& pBuilder);
60   ELFBinaryReader* createBinaryReader(IRBuilder& pBuilder);
61   ELFObjectWriter* createWriter();
62 
63   // -----  output sections  ----- //
64   /// initStdSections - initialize standard sections of the output file.
65   bool initStdSections(ObjectBuilder& pBuilder);
66 
67   /// getOutputFormat - get the sections of the output file.
68   const ELFFileFormat* getOutputFormat() const;
69   ELFFileFormat*       getOutputFormat();
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
75   /// undefined symbol in input objects. ObjectLinker must finalize its value
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'".
79   bool initStandardSymbols(IRBuilder& pBuilder, Module& pModule);
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
finalizeSymbols()85   bool finalizeSymbols() {
86     return (finalizeStandardSymbols() &&
87             finalizeTargetSymbols());
88   }
89 
90   /// finalizeStandardSymbols - set the value of standard symbols
91   virtual bool finalizeStandardSymbols();
92 
93   /// finalizeTargetSymbols - set the value of target symbols
94   virtual bool finalizeTargetSymbols() = 0;
95 
96   /// finalizeTLSSymbol - set the value of a TLS symbol
97   virtual bool finalizeTLSSymbol(LDSymbol& pSymbol);
98 
99   size_t sectionStartOffset() const;
100 
getInfo()101   const GNUInfo& getInfo() const { return *m_pInfo; }
getInfo()102   GNUInfo&       getInfo()       { return *m_pInfo; }
103 
hasTextRel()104   bool hasTextRel() const { return m_bHasTextRel; }
105 
hasStaticTLS()106   bool hasStaticTLS() const { return m_bHasStaticTLS; }
107 
108   /// getSegmentStartAddr - this function returns the start address of the segment
109   uint64_t getSegmentStartAddr(const LinkerScript& pScript) const;
110 
111   /// sizeShstrtab - compute the size of .shstrtab
112   void sizeShstrtab(Module& pModule);
113 
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
117   virtual void sizeNamePools(Module& pModule);
118 
119   /// emitSectionData - emit target-dependent section data
120   virtual uint64_t emitSectionData(const LDSection& pSection,
121                                    MemoryRegion& pRegion) const = 0;
122 
123   /// emitRegNamePools - emit regular name pools - .symtab, .strtab
124   virtual void emitRegNamePools(const Module& pModule, FileOutputBuffer& pOutput);
125 
126   /// emitNamePools - emit dynamic name pools - .dyntab, .dynstr, .hash
127   virtual void emitDynNamePools(Module& pModule, FileOutputBuffer& pOutput);
128 
129   /// emitELFHashTab - emit .hash
130   virtual void emitELFHashTab(const Module::SymbolTable& pSymtab,
131                               FileOutputBuffer& pOutput);
132 
133   /// emitGNUHashTab - emit .gnu.hash
134   virtual void emitGNUHashTab(Module::SymbolTable& pSymtab,
135                               FileOutputBuffer& pOutput);
136 
137   /// sizeInterp - compute the size of program interpreter's name
138   /// In ELF executables, this is the length of dynamic linker's path name
139   virtual void sizeInterp();
140 
141   /// emitInterp - emit the .interp
142   virtual void emitInterp(FileOutputBuffer& pOutput);
143 
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 
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
162   virtual unsigned int getSectionOrder(const LDSection& pSectHdr) const;
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.
getTargetSectionOrder(const LDSection & pSectHdr)170   virtual unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const
171   { return (unsigned int)-1; }
172 
173   /// elfSegmentTable - return the reference of the elf segment table
174   ELFSegmentFactory&       elfSegmentTable();
175 
176   /// elfSegmentTable - return the reference of the elf segment table
177   const ELFSegmentFactory& elfSegmentTable() const;
178 
179   /// commonPageSize - the common page size of the target machine
180   uint64_t commonPageSize() const;
181 
182   /// abiPageSize - the abi page size of the target machine
183   uint64_t abiPageSize() const;
184 
185   /// getSymbolIdx - get the symbol index of ouput symbol table
186   size_t getSymbolIdx(const LDSymbol* pSymbol) const;
187 
188   /// allocateCommonSymbols - allocate common symbols in the corresponding
189   /// sections.
190   /// Different concrete target backend may overlap this function.
191   virtual bool allocateCommonSymbols(Module& pModule);
192 
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 
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 
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;
252 
253   /// symbolNeedsCopyReloc - return whether the symbol needs a copy relocation
254   bool symbolNeedsCopyReloc(const Relocation& pReloc,
255                             const ResolveInfo& pSym) const;
256 
257   /// symbolNeedsDynRel - return whether the symbol needs a dynamic relocation
258   /// @ref Google gold linker, symtab.h:645
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   /// @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
274   bool isDynamicSymbol(const LDSymbol& pSymbol) const;
275 
276   /// isDynamicSymbol
277   /// @ref Google gold linker: symtab.cc:311
278   bool isDynamicSymbol(const ResolveInfo& pResolveInfo) const;
279 
getSymDesc(uint16_t pShndx)280   virtual ResolveInfo::Desc getSymDesc(uint16_t pShndx) const {
281     return ResolveInfo::Define;
282   }
283 
hasTDATASymbol()284   bool hasTDATASymbol() const { return (NULL != f_pTDATA); }
hasTBSSSymbol()285   bool hasTBSSSymbol()  const { return (NULL != f_pTBSS);  }
286 
setTDATASymbol(LDSymbol & pTDATA)287   void setTDATASymbol(LDSymbol& pTDATA) { f_pTDATA = &pTDATA; }
setTBSSSymbol(LDSymbol & pTBSS)288   void setTBSSSymbol(LDSymbol& pTBSS)   { f_pTBSS  = &pTBSS;  }
289 
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 
298   /// getEntry - get the entry point name
299   llvm::StringRef getEntry(const Module& pModule) const;
300 
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
getBRIslandFactory()309   BranchIslandFactory* getBRIslandFactory() { return m_pBRIslandFactory; }
310 
311   /// getStubFactory
getStubFactory()312   StubFactory*         getStubFactory()     { return m_pStubFactory; }
313 
314   /// maxFwdBranchOffset - return the max forward branch offset of the backend.
315   /// Target can override this function if needed.
maxFwdBranchOffset()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.
maxBwdBranchOffset()320   virtual int64_t maxBwdBranchOffset() { return 0; }
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   /// @ref Google gold linker, dynobj.cc:791
363   static unsigned getHashBucketCount(unsigned pNumOfSymbols, bool pIsGNUStyle);
364 
365   /// getGNUHashMaskbitslog2 - calculate the number of mask bits in log2
366   /// @ref binutils gold, dynobj.cc:1165
367   unsigned getGNUHashMaskbitslog2(unsigned pNumOfSymbols) const;
368 
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 
383 private:
384   /// createProgramHdrs - base on output sections to create the program headers
385   void createProgramHdrs(Module& pModule);
386 
387   /// doCreateProgramHdrs - backend can implement this function to create the
388   /// target-dependent segments
389   virtual void doCreateProgramHdrs(Module& pModule) = 0;
390 
391   /// setupProgramHdrs - set up the attributes of segments
392   ///  (i.e., offset, addresses, file/mem size, flag,  and alignment)
393   void setupProgramHdrs(const LinkerScript& pScript);
394 
395   /// getSegmentFlag - give a section flag and return the corresponding segment
396   /// flag
397   inline uint32_t getSegmentFlag(const uint32_t pSectionFlag);
398 
399   /// setupGNUStackInfo - setup the section flag of .note.GNU-stack in output
400   void setupGNUStackInfo(Module& pModule);
401 
402   /// setOutputSectionOffset - helper function to set output sections' offset.
403   void setOutputSectionOffset(Module& pModule);
404 
405   /// setOutputSectionAddress - helper function to set output sections' address.
406   void setOutputSectionAddress(Module& pModule);
407 
408   /// placeOutputSections - place output sections based on SectionMap
409   void placeOutputSections(Module& pModule);
410 
411   /// layout - layout method
412   void layout(Module& pModule);
413 
414   /// preLayout - Backend can do any needed modification before layout
415   void preLayout(Module& pModule, IRBuilder& pBuilder);
416 
417   /// postLayout -Backend can do any needed modification after layout
418   void postLayout(Module& pModule, IRBuilder& pBuilder);
419 
420   /// preLayout - Backend can do any needed modification before layout
421   virtual void doPreLayout(IRBuilder& pBuilder) = 0;
422 
423   /// postLayout -Backend can do any needed modification after layout
424   virtual void doPostLayout(Module& pModule, IRBuilder& pLinker) = 0;
425 
426   /// postProcessing - Backend can do any needed modification in the final stage
427   void postProcessing(FileOutputBuffer& pOutput);
428 
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 
435   /// relax - the relaxation pass
436   bool relax(Module& pModule, IRBuilder& pBuilder);
437 
438   /// mayRelax - Backends should override this function if they need relaxation
mayRelax()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.
doRelax(Module & pModule,IRBuilder & pBuilder,bool & pFinished)445   virtual bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished)
446   { return false; }
447 
448 protected:
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 {
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
479   };
480 
481   // for -z combreloc
482   struct RelocCompare
483   {
RelocCompareRelocCompare484     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;
490   };
491 
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 
500   struct SymCompare
501   {
operatorSymCompare502     bool operator()(const LDSymbol* X, const LDSymbol* Y) const
503     { return (X==Y); }
504   };
505 
506   struct SymPtrHash
507   {
operatorSymPtrHash508     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 
520 
521 protected:
522   ELFObjectReader* m_pObjectReader;
523 
524   // -----  file formats  ----- //
525   ELFDynObjFileFormat* m_pDynObjFileFormat;
526   ELFExecFileFormat*   m_pExecFileFormat;
527   ELFObjectFileFormat* m_pObjectFileFormat;
528 
529   // GNUInfo
530   GNUInfo* m_pInfo;
531 
532   // ELF segment factory
533   ELFSegmentFactory* m_pELFSegmentTable;
534 
535   // branch island factory
536   BranchIslandFactory* m_pBRIslandFactory;
537 
538   // stub factory
539   StubFactory* m_pStubFactory;
540 
541   // map the LDSymbol to its index in the output symbol table
542   HashTableType* m_pSymIndexMap;
543 
544   // section .eh_frame_hdr
545   EhFrameHdr* m_pEhFrameHdr;
546 
547   // attribute section
548   ELFAttribute* m_pAttribute;
549 
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 
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;
566   LDSymbol* f_pDynamic;
567 
568   // section symbols for .tdata and .tbss
569   LDSymbol* f_pTDATA;
570   LDSymbol* f_pTBSS;
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;
582 };
583 
584 } // namespace of mcld
585 
586 #endif
587 
588