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 
     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
     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 
     99   const GNUInfo& getInfo() const { return *m_pInfo; }
    100   GNUInfo& getInfo() { return *m_pInfo; }
    101 
    102   bool hasTextRel() const { return m_bHasTextRel; }
    103 
    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.
    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
    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 
    277   virtual ResolveInfo::Desc getSymDesc(uint16_t pShndx) const {
    278     return ResolveInfo::Define;
    279   }
    280 
    281   bool hasTDATASymbol() const { return (f_pTDATA != NULL); }
    282   bool hasTBSSSymbol() const { return (f_pTBSS != NULL); }
    283 
    284   void setTDATASymbol(LDSymbol& pTDATA) { f_pTDATA = &pTDATA; }
    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
    306   BranchIslandFactory* getBRIslandFactory() { return m_pBRIslandFactory; }
    307 
    308   /// 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.
    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.
    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.
    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   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
    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.
    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 {
    481     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 {
    496     bool operator()(const LDSymbol* X, const LDSymbol* Y) const {
    497       return (X == Y);
    498     }
    499   };
    500 
    501   struct SymPtrHash {
    502     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