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 MCLD_ARM_LDBACKEND_H
     10 #define MCLD_ARM_LDBACKEND_H
     11 
     12 #include "ARMELFDynamic.h"
     13 #include "ARMGOT.h"
     14 #include "ARMPLT.h"
     15 #include <mcld/LD/LDSection.h>
     16 #include <mcld/Target/GNULDBackend.h>
     17 #include <mcld/Target/OutputRelocSection.h>
     18 
     19 namespace mcld {
     20 
     21 class MCLDInfo;
     22 class MCLinker;
     23 class Output;
     24 class SectionMap;
     25 
     26 
     27 //===----------------------------------------------------------------------===//
     28 /// ARMGNULDBackend - linker backend of ARM target of GNU ELF format
     29 ///
     30 class ARMGNULDBackend : public GNULDBackend
     31 {
     32 public:
     33   ARMGNULDBackend();
     34   ~ARMGNULDBackend();
     35 public:
     36   typedef std::vector<llvm::ELF::Elf32_Dyn*> ELF32DynList;
     37 
     38   /** \enum ReservedEntryType
     39    *  \brief The reserved entry type of reserved space in ResolveInfo.
     40    *
     41    *  This is used for sacnRelocation to record what kinds of entries are
     42    *  reserved for this resolved symbol
     43    *
     44    *  In ARM, there are three kinds of entries, GOT, PLT, and dynamic reloction.
     45    *  GOT may needs a corresponding relocation to relocate itself, so we
     46    *  separate GOT to two situations: GOT and GOTRel. Besides, for the same
     47    *  symbol, there might be two kinds of entries reserved for different location.
     48    *  For example, reference to the same symbol, one may use GOT and the other may
     49    *  use dynamic relocation.
     50    *
     51    *  bit:  3       2      1     0
     52    *   | PLT | GOTRel | GOT | Rel |
     53    *
     54    *  value    Name         - Description
     55    *
     56    *  0000     None         - no reserved entry
     57    *  0001     ReserveRel   - reserve an dynamic relocation entry
     58    *  0010     ReserveGOT   - reserve an GOT entry
     59    *  0011     GOTandRel    - For different relocation, we've reserved GOT and
     60    *                          Rel for different location.
     61    *  0100     GOTRel       - reserve an GOT entry and the corresponding Dyncamic
     62    *                          relocation entry which relocate this GOT entry
     63    *  0101     GOTRelandRel - For different relocation, we've reserved GOTRel
     64    *                          and relocation entry for different location.
     65    *  1000     ReservePLT   - reserve an PLT entry and the corresponding GOT,
     66    *                          Dynamic relocation entries
     67    *  1001     PLTandRel    - For different relocation, we've reserved PLT and
     68    *                          Rel for different location.
     69    */
     70   enum ReservedEntryType {
     71     None         = 0,
     72     ReserveRel   = 1,
     73     ReserveGOT   = 2,
     74     GOTandRel    = 3,
     75     GOTRel       = 4,
     76     GOTRelandRel = 5,
     77     ReservePLT   = 8,
     78     PLTandRel    = 9
     79   };
     80 
     81 public:
     82   /// initTargetSectionMap - initialize target dependent section mapping
     83   bool initTargetSectionMap(SectionMap& pSectionMap);
     84 
     85   /// initTargetSections - initialize target dependent sections in output.
     86   void initTargetSections(MCLinker& pLinker);
     87 
     88   /// initTargetSymbols - initialize target dependent symbols in output.
     89   void initTargetSymbols(MCLinker& pLinker);
     90 
     91   /// initRelocFactory - create and initialize RelocationFactory
     92   bool initRelocFactory(const MCLinker& pLinker);
     93 
     94   /// getRelocFactory
     95   RelocationFactory* getRelocFactory();
     96 
     97   /// scanRelocation - determine the empty entries are needed or not and create
     98   /// the empty entries if needed.
     99   /// For ARM, following entries are check to create:
    100   /// - GOT entry (for .got section)
    101   /// - PLT entry (for .plt section)
    102   /// - dynamin relocation entries (for .rel.plt and .rel.dyn sections)
    103   void scanRelocation(Relocation& pReloc,
    104                       const LDSymbol& pInputSym,
    105                       MCLinker& pLinker,
    106                       const MCLDInfo& pLDInfo,
    107                       const Output& pOutput);
    108 
    109   uint32_t machine() const
    110   { return llvm::ELF::EM_ARM; }
    111 
    112   /// OSABI - the value of e_ident[EI_OSABI]
    113   virtual uint8_t OSABI() const
    114   { return llvm::ELF::ELFOSABI_NONE; }
    115 
    116   /// ABIVersion - the value of e_ident[EI_ABIVRESION]
    117   virtual uint8_t ABIVersion() const
    118   { return 0x0; }
    119 
    120   /// flags - the value of ElfXX_Ehdr::e_flags
    121   virtual uint64_t flags() const
    122   { return (llvm::ELF::EF_ARM_EABIMASK & 0x05000000); }
    123 
    124   bool isLittleEndian() const
    125   { return true; }
    126 
    127   unsigned int bitclass() const
    128   { return 32; }
    129 
    130   /// doPreLayout - Backend can do any needed modification before layout
    131   void doPreLayout(const Output& pOutput,
    132                    const MCLDInfo& pInfo,
    133                    MCLinker& pLinker);
    134 
    135   /// doPostLayout -Backend can do any needed modification after layout
    136   void doPostLayout(const Output& pOutput,
    137                     const MCLDInfo& pInfo,
    138                     MCLinker& pLinker);
    139 
    140   /// dynamic - the dynamic section of the target machine.
    141   /// Use co-variant return type to return its own dynamic section.
    142   ARMELFDynamic& dynamic();
    143 
    144   /// dynamic - the dynamic section of the target machine.
    145   /// Use co-variant return type to return its own dynamic section.
    146   const ARMELFDynamic& dynamic() const;
    147 
    148 
    149   /// emitSectionData - write out the section data into the memory region.
    150   /// When writers get a LDSection whose kind is LDFileFormat::Target, writers
    151   /// call back target backend to emit the data.
    152   ///
    153   /// Backends handle the target-special tables (plt, gp,...) by themselves.
    154   /// Backend can put the data of the tables in MCSectionData directly
    155   ///  - LDSection.getSectionData can get the section data.
    156   /// Or, backend can put the data into special data structure
    157   ///  - backend can maintain its own map<LDSection, table> to get the table
    158   /// from given LDSection.
    159   ///
    160   /// @param pOutput - the output file
    161   /// @param pSection - the given LDSection
    162   /// @param pInfo - all options in the command line.
    163   /// @param pRegion - the region to write out data
    164   /// @return the size of the table in the file.
    165   uint64_t emitSectionData(const Output& pOutput,
    166                            const LDSection& pSection,
    167                            const MCLDInfo& pInfo,
    168                            MemoryRegion& pRegion) const;
    169 
    170   ARMGOT& getGOT();
    171 
    172   const ARMGOT& getGOT() const;
    173 
    174   ARMPLT& getPLT();
    175 
    176   const ARMPLT& getPLT() const;
    177 
    178   OutputRelocSection& getRelDyn();
    179 
    180   const OutputRelocSection& getRelDyn() const;
    181 
    182   OutputRelocSection& getRelPLT();
    183 
    184   const OutputRelocSection& getRelPLT() const;
    185 
    186   /// getTargetSectionOrder - compute the layout order of ARM target sections
    187   unsigned int getTargetSectionOrder(const Output& pOutput,
    188                                      const LDSection& pSectHdr) const;
    189 
    190   /// finalizeSymbol - finalize the symbol value
    191   /// If the symbol's reserved field is not zero, MCLinker will call back this
    192   /// function to ask the final value of the symbol
    193   bool finalizeSymbol(LDSymbol& pSymbol) const;
    194 
    195   /// allocateCommonSymbols - allocate common symbols in the corresponding
    196   /// sections.
    197   bool allocateCommonSymbols(const MCLDInfo& pLDInfo, MCLinker& pLinker) const;
    198 
    199   /// readSection - read target dependent sections
    200   bool readSection(Input& pInput,
    201                    MCLinker& pLinker,
    202                    LDSection& pInputSectHdr);
    203 
    204 public:
    205   bool isSymbolPreemptible(const ResolveInfo& pSym,
    206                            const MCLDInfo& pLDInfo,
    207                            const Output& pOutput) const;
    208 
    209   bool isPIC(const MCLDInfo& pLDInfo, const Output& pOutput) const;
    210 
    211 private:
    212   void scanLocalReloc(Relocation& pReloc,
    213                       const LDSymbol& pInputSym,
    214                       MCLinker& pLinker,
    215                       const MCLDInfo& pLDInfo,
    216                       const Output& pOutput);
    217 
    218   void scanGlobalReloc(Relocation& pReloc,
    219                        const LDSymbol& pInputSym,
    220                        MCLinker& pLinker,
    221                        const MCLDInfo& pLDInfo,
    222                        const Output& pOutput);
    223 
    224   bool isSymbolNeedsPLT(const ResolveInfo& pSym,
    225                         const MCLDInfo& pLDInfo,
    226                         const Output& pOutput) const;
    227 
    228   bool isSymbolNeedsDynRel(const ResolveInfo& pSym,
    229                            const Output& pOutput,
    230                            bool isAbsReloc) const;
    231 
    232 
    233   void checkValidReloc(Relocation& pReloc,
    234                        const MCLDInfo& pLDInfo,
    235                        const Output& pOutput) const;
    236 
    237   /// updateAddend - update addend value of the relocation if the
    238   /// the target symbol is a section symbol. Addend is the offset
    239   /// in the section. This value should be updated after section
    240   /// merged.
    241   void updateAddend(Relocation& pReloc,
    242                     const LDSymbol& pInputSym,
    243                     const Layout& pLayout) const;
    244 
    245   void createARMGOT(MCLinker& pLinker, const Output& pOutput);
    246 
    247   /// createARMPLTandRelPLT - create PLT and RELPLT sections.
    248   /// Because in ELF sh_info in .rel.plt is the shndx of .plt, these two
    249   /// sections should be create together.
    250   void createARMPLTandRelPLT(MCLinker& pLinker, const Output& pOutput);
    251 
    252   void createARMRelDyn(MCLinker& pLinker, const Output& pOutput);
    253 
    254   ELFFileFormat* getOutputFormat(const Output& pOutput) const;
    255 
    256 private:
    257   RelocationFactory* m_pRelocFactory;
    258   ARMGOT* m_pGOT;
    259   ARMPLT* m_pPLT;
    260   /// m_RelDyn - dynamic relocation table of .rel.dyn
    261   OutputRelocSection* m_pRelDyn;
    262   /// m_RelPLT - dynamic relocation table of .rel.plt
    263   OutputRelocSection* m_pRelPLT;
    264 
    265   ARMELFDynamic* m_pDynamic;
    266   LDSymbol* m_pGOTSymbol;
    267 
    268   //     variable name           :  ELF
    269   LDSection* m_pEXIDX;           // .ARM.exidx
    270   LDSection* m_pEXTAB;           // .ARM.extab
    271   LDSection* m_pAttributes;      // .ARM.attributes
    272 //  LDSection* m_pPreemptMap;      // .ARM.preemptmap
    273 //  LDSection* m_pDebugOverlay;    // .ARM.debug_overlay
    274 //  LDSection* m_pOverlayTable;    // .ARM.overlay_table
    275 };
    276 
    277 //===----------------------------------------------------------------------===//
    278 /// ARMMachOLDBackend - linker backend of ARM target of MachO format
    279 ///
    280 /**
    281 class ARMMachOLDBackend : public DarwinARMLDBackend
    282 {
    283 public:
    284   ARMMachOLDBackend();
    285   ~ARMMachOLDBackend();
    286 
    287 private:
    288   MCMachOTargetArchiveReader *createTargetArchiveReader() const;
    289   MCMachOTargetObjectReader *createTargetObjectReader() const;
    290   MCMachOTargetObjectWriter *createTargetObjectWriter() const;
    291 
    292 };
    293 **/
    294 } // namespace of mcld
    295 
    296 #endif
    297