Home | History | Annotate | Download | only in ARM
      1 //===- ARMLDBackend.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 TARGET_ARM_ARMLDBACKEND_H_
     10 #define TARGET_ARM_ARMLDBACKEND_H_
     11 
     12 #include "ARMELFDynamic.h"
     13 #include "ARMException.h"
     14 #include "ARMGOT.h"
     15 #include "ARMPLT.h"
     16 #include "mcld/LD/LDSection.h"
     17 #include "mcld/Target/GNULDBackend.h"
     18 #include "mcld/Target/OutputRelocSection.h"
     19 
     20 namespace mcld {
     21 
     22 class ARMELFAttributeData;
     23 class GNUInfo;
     24 class LinkerConfig;
     25 
     26 //===----------------------------------------------------------------------===//
     27 /// ARMGNULDBackend - linker backend of ARM target of GNU ELF format
     28 ///
     29 class ARMGNULDBackend : public GNULDBackend {
     30  public:
     31   // max branch offsets for ARM, THUMB, and THUMB2
     32   static const int32_t ARM_MAX_FWD_BRANCH_OFFSET = ((((1 << 23) - 1) << 2) + 8);
     33   static const int32_t ARM_MAX_BWD_BRANCH_OFFSET = ((-((1 << 23) << 2)) + 8);
     34   static const int32_t THM_MAX_FWD_BRANCH_OFFSET = ((1 << 22) - 2 + 4);
     35   static const int32_t THM_MAX_BWD_BRANCH_OFFSET = (-(1 << 22) + 4);
     36   static const int32_t THM2_MAX_FWD_BRANCH_OFFSET = (((1 << 24) - 2) + 4);
     37   static const int32_t THM2_MAX_BWD_BRANCH_OFFSET = (-(1 << 24) + 4);
     38 
     39  public:
     40   ARMGNULDBackend(const LinkerConfig& pConfig, GNUInfo* pInfo);
     41   ~ARMGNULDBackend();
     42 
     43  public:
     44   typedef std::vector<llvm::ELF::Elf32_Dyn*> ELF32DynList;
     45 
     46  public:
     47   /// initTargetSections - initialize target dependent sections in output.
     48   void initTargetSections(Module& pModule, ObjectBuilder& pBuilder);
     49 
     50   /// initTargetSymbols - initialize target dependent symbols in output.
     51   void initTargetSymbols(IRBuilder& pBuilder, Module& pModule);
     52 
     53   /// initRelocator - create and initialize Relocator.
     54   bool initRelocator();
     55 
     56   /// getRelocator - return relocator.
     57   const Relocator* getRelocator() const;
     58   Relocator* getRelocator();
     59 
     60   /// doPreLayout - Backend can do any needed modification before layout
     61   void doPreLayout(IRBuilder& pBuilder);
     62 
     63   /// doPostLayout -Backend can do any needed modification after layout
     64   void doPostLayout(Module& pModule, IRBuilder& pBuilder);
     65 
     66   /// dynamic - the dynamic section of the target machine.
     67   /// Use co-variant return type to return its own dynamic section.
     68   ARMELFDynamic& dynamic();
     69 
     70   /// dynamic - the dynamic section of the target machine.
     71   /// Use co-variant return type to return its own dynamic section.
     72   const ARMELFDynamic& dynamic() const;
     73 
     74   /// emitSectionData - write out the section data into the memory region.
     75   /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
     76   /// call back target backend to emit the data.
     77   ///
     78   /// Backends handle the target-special tables (plt, gp,...) by themselves.
     79   /// Backend can put the data of the tables in SectionData directly
     80   ///  - LDSection.getSectionData can get the section data.
     81   /// Or, backend can put the data into special data structure
     82   ///  - backend can maintain its own map<LDSection, table> to get the table
     83   /// from given LDSection.
     84   ///
     85   /// @param pSection - the given LDSection
     86   /// @param pConfig - all options in the command line.
     87   /// @param pRegion - the region to write out data
     88   /// @return the size of the table in the file.
     89   uint64_t emitSectionData(const LDSection& pSection,
     90                            MemoryRegion& pRegion) const;
     91 
     92   ARMGOT& getGOT();
     93   const ARMGOT& getGOT() const;
     94 
     95   ARMPLT& getPLT();
     96   const ARMPLT& getPLT() const;
     97 
     98   OutputRelocSection& getRelDyn();
     99   const OutputRelocSection& getRelDyn() const;
    100 
    101   OutputRelocSection& getRelPLT();
    102   const OutputRelocSection& getRelPLT() const;
    103 
    104   ARMELFAttributeData& getAttributeData();
    105   const ARMELFAttributeData& getAttributeData() const;
    106 
    107   LDSymbol* getGOTSymbol() { return m_pGOTSymbol; }
    108   const LDSymbol* getGOTSymbol() const { return m_pGOTSymbol; }
    109 
    110   /// getTargetSectionOrder - compute the layout order of ARM target sections
    111   unsigned int getTargetSectionOrder(const LDSection& pSectHdr) const;
    112 
    113   /// finalizeTargetSymbols - finalize the symbol value
    114   bool finalizeTargetSymbols();
    115 
    116   /// preMergeSections - hooks to be executed before merging sections
    117   virtual void preMergeSections(Module& pModule);
    118 
    119   /// postMergeSections - hooks to be executed after merging sections
    120   virtual void postMergeSections(Module& pModule);
    121 
    122   /// mergeSection - merge target dependent sections
    123   bool mergeSection(Module& pModule, const Input& pInput, LDSection& pSection);
    124 
    125   /// setUpReachedSectionsForGC - set the reference from section XXX to
    126   /// .ARM.exidx.XXX to make sure GC correctly handle section exidx
    127   void setUpReachedSectionsForGC(
    128       const Module& pModule,
    129       GarbageCollection::SectionReachedListMap& pSectReachedListMap) const;
    130 
    131   /// readSection - read target dependent sections
    132   bool readSection(Input& pInput, SectionData& pSD);
    133 
    134   /// mayHaveUnsafeFunctionPointerAccess - check if the section may have unsafe
    135   /// function pointer access
    136   bool mayHaveUnsafeFunctionPointerAccess(const LDSection& pSection) const;
    137 
    138  private:
    139   void defineGOTSymbol(IRBuilder& pBuilder);
    140 
    141   /// maxFwdBranchOffset
    142   int64_t maxFwdBranchOffset();
    143   /// maxBwdBranchOffset
    144   int64_t maxBwdBranchOffset();
    145 
    146   /// mayRelax - Backends should override this function if they need relaxation
    147   bool mayRelax() { return true; }
    148 
    149   /// relax - the relaxation pass
    150   virtual bool relax(Module& pModule, IRBuilder& pBuilder);
    151 
    152   /// doRelax - Backend can orevride this function to add its relaxation
    153   /// implementation. Return true if the output (e.g., .text) is "relaxed"
    154   /// (i.e. layout is changed), and set pFinished to true if everything is fit,
    155   /// otherwise set it to false.
    156   bool doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished);
    157 
    158   /// initTargetStubs
    159   bool initTargetStubs();
    160 
    161   /// getRelEntrySize - the size in BYTE of rel type relocation
    162   size_t getRelEntrySize() { return 8; }
    163 
    164   /// getRelEntrySize - the size in BYTE of rela type relocation
    165   size_t getRelaEntrySize() {
    166     assert(0 && "ARM backend with Rela type relocation\n");
    167     return 12;
    168   }
    169 
    170   /// doCreateProgramHdrs - backend can implement this function to create the
    171   /// target-dependent segments
    172   virtual void doCreateProgramHdrs(Module& pModule);
    173 
    174   /// scanInputExceptionSections - scan exception-related input sections in
    175   /// the Module, build the ARMExData, and reclaim GC'ed sections
    176   void scanInputExceptionSections(Module& pModule);
    177 
    178   /// scanInputExceptionSections - scan exception-related input sections in
    179   /// the Input, build the ARMInputExMap, and reclaim GC'ed sections
    180   void scanInputExceptionSections(Module& pModule, Input& pInput);
    181 
    182   /// rewriteExceptionSection - rewrite the output .ARM.exidx section.
    183   void rewriteARMExIdxSection(Module& pModule);
    184 
    185  private:
    186   Relocator* m_pRelocator;
    187 
    188   ARMGOT* m_pGOT;
    189   ARMPLT* m_pPLT;
    190   /// m_RelDyn - dynamic relocation table of .rel.dyn
    191   OutputRelocSection* m_pRelDyn;
    192   /// m_RelPLT - dynamic relocation table of .rel.plt
    193   OutputRelocSection* m_pRelPLT;
    194 
    195   /// m_pAttrData - attribute data in public ("aeabi") attribute subsection
    196   ARMELFAttributeData* m_pAttrData;
    197 
    198   ARMELFDynamic* m_pDynamic;
    199   LDSymbol* m_pGOTSymbol;
    200   LDSymbol* m_pEXIDXStart;
    201   LDSymbol* m_pEXIDXEnd;
    202 
    203   //     variable name           :  ELF
    204   LDSection* m_pEXIDX;       // .ARM.exidx
    205   LDSection* m_pEXTAB;       // .ARM.extab
    206   LDSection* m_pAttributes;  // .ARM.attributes
    207   //  LDSection* m_pPreemptMap;      // .ARM.preemptmap
    208   //  LDSection* m_pDebugOverlay;    // .ARM.debug_overlay
    209   //  LDSection* m_pOverlayTable;    // .ARM.overlay_table
    210 
    211   // m_ExData - exception handling section data structures
    212   ARMExData m_ExData;
    213 };
    214 }  // namespace mcld
    215 
    216 #endif  // TARGET_ARM_ARMLDBACKEND_H_
    217