Home | History | Annotate | Download | only in Target
      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
     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 
    101   const GNUInfo& getInfo() const { return *m_pInfo; }
    102   GNUInfo&       getInfo()       { return *m_pInfo; }
    103 
    104   bool hasTextRel() const { return m_bHasTextRel; }
    105 
    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.
    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 
    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 
    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
    309   BranchIslandFactory* getBRIslandFactory() { return m_pBRIslandFactory; }
    310 
    311   /// 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.
    316   virtual int64_t maxFwdBranchOffset() { return INT64_MAX; }
    317 
    318   /// maxBwdBranchOffset - return the max backward branch offset of the backend.
    319   /// Target can override this function if needed.
    320   virtual int64_t maxBwdBranchOffset() { return 0; }
    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.
    334   ELFAttribute& attribute() { return *m_pAttribute; }
    335 
    336   /// attribute - the attribute section data.
    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
    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.
    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   {
    484     RelocCompare(const GNULDBackend& pBackend)
    485       : m_Backend(pBackend) {
    486     }
    487     bool operator()(const Relocation* X, const Relocation* Y) const;
    488   private:
    489     const GNULDBackend& m_Backend;
    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   {
    502     bool operator()(const LDSymbol* X, const LDSymbol* Y) const
    503     { return (X==Y); }
    504   };
    505 
    506   struct SymPtrHash
    507   {
    508     size_t operator()(const LDSymbol* pKey) const
    509     {
    510       return (unsigned((uintptr_t)pKey) >> 4) ^
    511              (unsigned((uintptr_t)pKey) >> 9);
    512     }
    513   };
    514 
    515   typedef HashEntry<LDSymbol*, size_t, SymCompare> SymHashEntryType;
    516   typedef HashTable<SymHashEntryType,
    517                     SymPtrHash,
    518                     EntryFactory<SymHashEntryType> > HashTableType;
    519 
    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