Home | History | Annotate | Download | only in Hexagon
      1 //===- HexagonLDBackend.cpp -----------------------------------------------===//
      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 #include "Hexagon.h"
     10 #include "HexagonELFDynamic.h"
     11 #include "HexagonLDBackend.h"
     12 #include "HexagonRelocator.h"
     13 #include "HexagonGNUInfo.h"
     14 
     15 #include <llvm/ADT/Triple.h>
     16 #include <llvm/Support/Casting.h>
     17 
     18 #include <mcld/LinkerConfig.h>
     19 #include <mcld/IRBuilder.h>
     20 #include <mcld/Fragment/FillFragment.h>
     21 #include <mcld/Fragment/RegionFragment.h>
     22 #include <mcld/Support/MemoryRegion.h>
     23 #include <mcld/Support/MsgHandling.h>
     24 #include <mcld/Support/TargetRegistry.h>
     25 #include <mcld/Object/ObjectBuilder.h>
     26 
     27 #include <cstring>
     28 
     29 using namespace mcld;
     30 
     31 //===----------------------------------------------------------------------===//
     32 // HexagonLDBackend
     33 //===----------------------------------------------------------------------===//
     34 HexagonLDBackend::HexagonLDBackend(const LinkerConfig& pConfig,
     35                                    HexagonGNUInfo* pInfo)
     36   : GNULDBackend(pConfig, pInfo),
     37     m_pRelocator(NULL),
     38     m_pGOT(NULL),
     39     m_pPLT(NULL),
     40     m_pRelDyn(NULL),
     41     m_pRelPLT(NULL),
     42     m_pDynamic(NULL),
     43     m_pGOTSymbol(NULL) {
     44 }
     45 
     46 HexagonLDBackend::~HexagonLDBackend()
     47 {
     48   delete m_pRelocator;
     49   delete m_pGOT;
     50   delete m_pPLT;
     51   delete m_pRelDyn;
     52   delete m_pRelPLT;
     53   delete m_pDynamic;
     54 }
     55 
     56 bool HexagonLDBackend::initRelocator()
     57 {
     58   if (NULL == m_pRelocator) {
     59     m_pRelocator = new HexagonRelocator(*this);
     60   }
     61   return true;
     62 }
     63 
     64 Relocator* HexagonLDBackend::getRelocator()
     65 {
     66   assert(NULL != m_pRelocator);
     67   return m_pRelocator;
     68 }
     69 
     70 void HexagonLDBackend::doPreLayout(IRBuilder& pBuilder)
     71 {
     72   // initialize .dynamic data
     73   if (!config().isCodeStatic() && NULL == m_pDynamic)
     74     m_pDynamic = new HexagonELFDynamic(*this, config());
     75 }
     76 
     77 void HexagonLDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder)
     78 {
     79 }
     80 
     81 /// dynamic - the dynamic section of the target machine.
     82 /// Use co-variant return type to return its own dynamic section.
     83 HexagonELFDynamic& HexagonLDBackend::dynamic()
     84 {
     85   assert(NULL != m_pDynamic);
     86   return *m_pDynamic;
     87 }
     88 
     89 /// dynamic - the dynamic section of the target machine.
     90 /// Use co-variant return type to return its own dynamic section.
     91 const HexagonELFDynamic& HexagonLDBackend::dynamic() const
     92 {
     93   assert(NULL != m_pDynamic);
     94   return *m_pDynamic;
     95 }
     96 
     97 void HexagonLDBackend::scanRelocation(Relocation& pReloc,
     98                                       IRBuilder& pBuilder,
     99                                       Module& pModule,
    100                                       LDSection& pSection)
    101 {
    102   pReloc.updateAddend();
    103 }
    104 
    105 uint64_t HexagonLDBackend::emitSectionData(const LDSection& pSection,
    106                                           MemoryRegion& pRegion) const
    107 {
    108   return 0;
    109 }
    110 
    111 HexagonGOT& HexagonLDBackend::getGOT()
    112 {
    113   assert(NULL != m_pGOT);
    114   return *m_pGOT;
    115 }
    116 
    117 const HexagonGOT& HexagonLDBackend::getGOT() const
    118 {
    119   assert(NULL != m_pGOT);
    120   return *m_pGOT;
    121 }
    122 
    123 HexagonPLT& HexagonLDBackend::getPLT()
    124 {
    125   assert(NULL != m_pPLT && "PLT section not exist");
    126   return *m_pPLT;
    127 }
    128 
    129 const HexagonPLT& HexagonLDBackend::getPLT() const
    130 {
    131   assert(NULL != m_pPLT && "PLT section not exist");
    132   return *m_pPLT;
    133 }
    134 
    135 OutputRelocSection& HexagonLDBackend::getRelDyn()
    136 {
    137   assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
    138   return *m_pRelDyn;
    139 }
    140 
    141 const OutputRelocSection& HexagonLDBackend::getRelDyn() const
    142 {
    143   assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
    144   return *m_pRelDyn;
    145 }
    146 
    147 OutputRelocSection& HexagonLDBackend::getRelPLT()
    148 {
    149   assert(NULL != m_pRelPLT && ".rel.plt section not exist");
    150   return *m_pRelPLT;
    151 }
    152 
    153 const OutputRelocSection& HexagonLDBackend::getRelPLT() const
    154 {
    155   assert(NULL != m_pRelPLT && ".rel.plt section not exist");
    156   return *m_pRelPLT;
    157 }
    158 
    159 unsigned int
    160 HexagonLDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const
    161 {
    162   const ELFFileFormat* file_format = getOutputFormat();
    163 
    164   if (&pSectHdr == &file_format->getGOT()) {
    165     if (config().options().hasNow())
    166       return SHO_RELRO;
    167     return SHO_RELRO_LAST;
    168   }
    169 
    170   if (&pSectHdr == &file_format->getPLT())
    171     return SHO_PLT;
    172 
    173   return SHO_UNDEFINED;
    174 }
    175 
    176 void HexagonLDBackend::initTargetSections(Module& pModule,
    177                                           ObjectBuilder& pBuilder)
    178 {
    179   if (LinkerConfig::Object != config().codeGenType()) {
    180     ELFFileFormat* file_format = getOutputFormat();
    181     // initialize .got
    182     LDSection& got = file_format->getGOT();
    183     m_pGOT = new HexagonGOT(got);
    184 
    185     // initialize .plt
    186     LDSection& plt = file_format->getPLT();
    187     m_pPLT = new HexagonPLT(plt,
    188                         *m_pGOT,
    189                         config());
    190 
    191     // initialize .rel.plt
    192     LDSection& relplt = file_format->getRelPlt();
    193     relplt.setLink(&plt);
    194     m_pRelPLT = new OutputRelocSection(pModule, relplt);
    195 
    196     // initialize .rel.dyn
    197     LDSection& reldyn = file_format->getRelDyn();
    198     m_pRelDyn = new OutputRelocSection(pModule, reldyn);
    199 
    200   }
    201 }
    202 
    203 void HexagonLDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule)
    204 {
    205   if (LinkerConfig::Object != config().codeGenType()) {
    206     // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
    207     // same name in input
    208     m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
    209                                                     "_GLOBAL_OFFSET_TABLE_",
    210                                                     ResolveInfo::Object,
    211                                                     ResolveInfo::Define,
    212                                                     ResolveInfo::Local,
    213                                                     0x0,  // size
    214                                                     0x0,  // value
    215                                                     FragmentRef::Null(),
    216                                                     ResolveInfo::Hidden);
    217   }
    218 }
    219 
    220 /// finalizeSymbol - finalize the symbol value
    221 bool HexagonLDBackend::finalizeTargetSymbols()
    222 {
    223   return true;
    224 }
    225 
    226 /// doCreateProgramHdrs - backend can implement this function to create the
    227 /// target-dependent segments
    228 void HexagonLDBackend::doCreateProgramHdrs(Module& pModule)
    229 {
    230   // TODO
    231 }
    232 
    233 namespace mcld {
    234 
    235 //===----------------------------------------------------------------------===//
    236 /// createHexagonLDBackend - the help funtion to create corresponding
    237 /// HexagonLDBackend
    238 TargetLDBackend* createHexagonLDBackend(const llvm::Target& pTarget,
    239                                     const LinkerConfig& pConfig)
    240 {
    241   if (pConfig.targets().triple().isOSDarwin()) {
    242     assert(0 && "MachO linker is not supported yet");
    243     /**
    244     return new HexagonMachOLDBackend(createHexagonMachOArchiveReader,
    245                                createHexagonMachOObjectReader,
    246                                createHexagonMachOObjectWriter);
    247     **/
    248   }
    249   if (pConfig.targets().triple().isOSWindows()) {
    250     assert(0 && "COFF linker is not supported yet");
    251     /**
    252     return new HexagonCOFFLDBackend(createHexagonCOFFArchiveReader,
    253                                createHexagonCOFFObjectReader,
    254                                createHexagonCOFFObjectWriter);
    255     **/
    256   }
    257   return new HexagonLDBackend(pConfig,
    258                               new HexagonGNUInfo(pConfig.targets().triple()));
    259 }
    260 
    261 } // namespace of mcld
    262 
    263 //===----------------------------------------------------------------------===//
    264 // Force static initialization.
    265 //===----------------------------------------------------------------------===//
    266 extern "C" void MCLDInitializeHexagonLDBackend() {
    267   // Register the linker backend
    268   mcld::TargetRegistry::RegisterTargetLDBackend(TheHexagonTarget,
    269                                                 createHexagonLDBackend);
    270 }
    271