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 #include "HexagonAbsoluteStub.h"
     15 
     16 #include "mcld/IRBuilder.h"
     17 #include "mcld/LinkerConfig.h"
     18 #include "mcld/Fragment/AlignFragment.h"
     19 #include "mcld/Fragment/FillFragment.h"
     20 #include "mcld/Fragment/RegionFragment.h"
     21 #include "mcld/Fragment/Stub.h"
     22 #include "mcld/LD/BranchIslandFactory.h"
     23 #include "mcld/LD/ELFFileFormat.h"
     24 #include "mcld/LD/ELFSegmentFactory.h"
     25 #include "mcld/LD/ELFSegment.h"
     26 #include "mcld/LD/LDContext.h"
     27 #include "mcld/LD/StubFactory.h"
     28 #include "mcld/Object/ObjectBuilder.h"
     29 #include "mcld/Support/MemoryArea.h"
     30 #include "mcld/Support/MsgHandling.h"
     31 #include "mcld/Support/TargetRegistry.h"
     32 
     33 #include <llvm/ADT/Triple.h>
     34 #include <llvm/Support/Casting.h>
     35 
     36 #include <cstring>
     37 
     38 namespace mcld {
     39 
     40 //===----------------------------------------------------------------------===//
     41 // HexagonLDBackend
     42 //===----------------------------------------------------------------------===//
     43 HexagonLDBackend::HexagonLDBackend(const LinkerConfig& pConfig,
     44                                    HexagonGNUInfo* pInfo)
     45     : GNULDBackend(pConfig, pInfo),
     46       m_pRelocator(NULL),
     47       m_pGOT(NULL),
     48       m_pGOTPLT(NULL),
     49       m_pPLT(NULL),
     50       m_pRelaDyn(NULL),
     51       m_pRelaPLT(NULL),
     52       m_pDynamic(NULL),
     53       m_pGOTSymbol(NULL),
     54       m_CopyRel(llvm::ELF::R_HEX_COPY) {
     55 }
     56 
     57 HexagonLDBackend::~HexagonLDBackend() {
     58   delete m_pRelocator;
     59   delete m_pGOT;
     60   delete m_pPLT;
     61   delete m_pRelaDyn;
     62   delete m_pRelaPLT;
     63   delete m_pDynamic;
     64 }
     65 
     66 bool HexagonLDBackend::initRelocator() {
     67   if (m_pRelocator == NULL) {
     68     m_pRelocator = new HexagonRelocator(*this, config());
     69   }
     70   return true;
     71 }
     72 
     73 const Relocator* HexagonLDBackend::getRelocator() const {
     74   assert(m_pRelocator != NULL);
     75   return m_pRelocator;
     76 }
     77 
     78 Relocator* HexagonLDBackend::getRelocator() {
     79   assert(m_pRelocator != NULL);
     80   return m_pRelocator;
     81 }
     82 
     83 void HexagonLDBackend::doPreLayout(IRBuilder& pBuilder) {
     84   // initialize .dynamic data
     85   if (!config().isCodeStatic() && m_pDynamic == NULL)
     86     m_pDynamic = new HexagonELFDynamic(*this, config());
     87 
     88   // set .got.plt and .got sizes
     89   // when building shared object, the .got section is must
     90   if ((LinkerConfig::Object != config().codeGenType()) &&
     91       (!config().isCodeStatic())) {
     92     setGOTSectionSize(pBuilder);
     93 
     94     // set .plt size
     95     if (m_pPLT->hasPLT1())
     96       m_pPLT->finalizeSectionSize();
     97 
     98     // set .rela.dyn size
     99     if (!m_pRelaDyn->empty()) {
    100       assert(
    101           !config().isCodeStatic() &&
    102           "static linkage should not result in a dynamic relocation section");
    103       setRelaDynSize();
    104     }
    105     // set .rela.plt size
    106     if (!m_pRelaPLT->empty()) {
    107       assert(
    108           !config().isCodeStatic() &&
    109           "static linkage should not result in a dynamic relocation section");
    110       setRelaPLTSize();
    111     }
    112   }
    113   // Shared libraries are compiled with -G0 so there is no need to set SData.
    114   if (LinkerConfig::Object == config().codeGenType())
    115     SetSDataSection();
    116 }
    117 
    118 void HexagonLDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) {
    119 }
    120 
    121 /// dynamic - the dynamic section of the target machine.
    122 /// Use co-variant return type to return its own dynamic section.
    123 HexagonELFDynamic& HexagonLDBackend::dynamic() {
    124   assert(m_pDynamic != NULL);
    125   return *m_pDynamic;
    126 }
    127 
    128 /// dynamic - the dynamic section of the target machine.
    129 /// Use co-variant return type to return its own dynamic section.
    130 const HexagonELFDynamic& HexagonLDBackend::dynamic() const {
    131   assert(m_pDynamic != NULL);
    132   return *m_pDynamic;
    133 }
    134 
    135 uint64_t HexagonLDBackend::emitSectionData(const LDSection& pSection,
    136                                            MemoryRegion& pRegion) const {
    137   if (!pRegion.size())
    138     return 0;
    139 
    140   const ELFFileFormat* FileFormat = getOutputFormat();
    141   unsigned int EntrySize = 0;
    142   uint64_t RegionSize = 0;
    143 
    144   if ((LinkerConfig::Object != config().codeGenType()) &&
    145       (!config().isCodeStatic())) {
    146     if (FileFormat->hasPLT() && (&pSection == &(FileFormat->getPLT()))) {
    147       unsigned char* buffer = pRegion.begin();
    148 
    149       m_pPLT->applyPLT0();
    150       m_pPLT->applyPLT1();
    151       HexagonPLT::iterator it = m_pPLT->begin();
    152       unsigned int plt0_size = llvm::cast<PLTEntryBase>((*it)).size();
    153 
    154       memcpy(buffer, llvm::cast<PLTEntryBase>((*it)).getValue(), plt0_size);
    155       RegionSize += plt0_size;
    156       ++it;
    157 
    158       PLTEntryBase* plt1 = 0;
    159       HexagonPLT::iterator ie = m_pPLT->end();
    160       while (it != ie) {
    161         plt1 = &(llvm::cast<PLTEntryBase>(*it));
    162         EntrySize = plt1->size();
    163         memcpy(buffer + RegionSize, plt1->getValue(), EntrySize);
    164         RegionSize += EntrySize;
    165         ++it;
    166       }
    167       return RegionSize;
    168     } else if (FileFormat->hasGOT() && (&pSection == &(FileFormat->getGOT()))) {
    169       RegionSize += emitGOTSectionData(pRegion);
    170       return RegionSize;
    171     } else if (FileFormat->hasGOTPLT() &&
    172                (&pSection == &(FileFormat->getGOTPLT()))) {
    173       RegionSize += emitGOTPLTSectionData(pRegion, FileFormat);
    174       return RegionSize;
    175     }
    176   }
    177 
    178   const SectionData* sect_data = pSection.getSectionData();
    179   SectionData::const_iterator frag_iter, frag_end = sect_data->end();
    180   uint8_t* out_offset = pRegion.begin();
    181   for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) {
    182     size_t size = frag_iter->size();
    183     switch (frag_iter->getKind()) {
    184       case Fragment::Fillment: {
    185         const FillFragment& fill_frag = llvm::cast<FillFragment>(*frag_iter);
    186         if (fill_frag.getValueSize() == 0) {
    187           // virtual fillment, ignore it.
    188           break;
    189         }
    190         memset(out_offset, fill_frag.getValue(), fill_frag.size());
    191         break;
    192       }
    193       case Fragment::Region: {
    194         const RegionFragment& region_frag =
    195             llvm::cast<RegionFragment>(*frag_iter);
    196         const char* start = region_frag.getRegion().begin();
    197         memcpy(out_offset, start, size);
    198         break;
    199       }
    200       case Fragment::Alignment: {
    201         const AlignFragment& align_frag = llvm::cast<AlignFragment>(*frag_iter);
    202         uint64_t count = size / align_frag.getValueSize();
    203         switch (align_frag.getValueSize()) {
    204           case 1u:
    205             std::memset(out_offset, align_frag.getValue(), count);
    206             break;
    207           default:
    208             llvm::report_fatal_error(
    209                 "unsupported value size for align fragment emission yet.\n");
    210             break;
    211         }  // end switch
    212         break;
    213       }
    214       case Fragment::Null: {
    215         assert(0x0 == size);
    216         break;
    217       }
    218       default:
    219         llvm::report_fatal_error("unsupported fragment type.\n");
    220         break;
    221     }  // end switch
    222     out_offset += size;
    223   }  // end for
    224 
    225   return pRegion.size();
    226 }
    227 
    228 HexagonGOT& HexagonLDBackend::getGOT() {
    229   assert(m_pGOT != NULL);
    230   return *m_pGOT;
    231 }
    232 
    233 const HexagonGOT& HexagonLDBackend::getGOT() const {
    234   assert(m_pGOT != NULL);
    235   return *m_pGOT;
    236 }
    237 
    238 HexagonPLT& HexagonLDBackend::getPLT() {
    239   assert(m_pPLT != NULL && "PLT section not exist");
    240   return *m_pPLT;
    241 }
    242 
    243 const HexagonPLT& HexagonLDBackend::getPLT() const {
    244   assert(m_pPLT != NULL && "PLT section not exist");
    245   return *m_pPLT;
    246 }
    247 
    248 OutputRelocSection& HexagonLDBackend::getRelaDyn() {
    249   assert(m_pRelaDyn != NULL && ".rela.dyn section not exist");
    250   return *m_pRelaDyn;
    251 }
    252 
    253 const OutputRelocSection& HexagonLDBackend::getRelaDyn() const {
    254   assert(m_pRelaDyn != NULL && ".rela.dyn section not exist");
    255   return *m_pRelaDyn;
    256 }
    257 
    258 OutputRelocSection& HexagonLDBackend::getRelaPLT() {
    259   assert(m_pRelaPLT != NULL && ".rela.plt section not exist");
    260   return *m_pRelaPLT;
    261 }
    262 
    263 const OutputRelocSection& HexagonLDBackend::getRelaPLT() const {
    264   assert(m_pRelaPLT != NULL && ".rela.plt section not exist");
    265   return *m_pRelaPLT;
    266 }
    267 
    268 HexagonGOTPLT& HexagonLDBackend::getGOTPLT() {
    269   assert(m_pGOTPLT != NULL);
    270   return *m_pGOTPLT;
    271 }
    272 
    273 const HexagonGOTPLT& HexagonLDBackend::getGOTPLT() const {
    274   assert(m_pGOTPLT != NULL);
    275   return *m_pGOTPLT;
    276 }
    277 
    278 void HexagonLDBackend::setRelaDynSize() {
    279   ELFFileFormat* file_format = getOutputFormat();
    280   file_format->getRelaDyn().setSize(m_pRelaDyn->numOfRelocs() *
    281                                     getRelaEntrySize());
    282 }
    283 
    284 void HexagonLDBackend::setRelaPLTSize() {
    285   ELFFileFormat* file_format = getOutputFormat();
    286   file_format->getRelaPlt().setSize(m_pRelaPLT->numOfRelocs() *
    287                                     getRelaEntrySize());
    288 }
    289 
    290 void HexagonLDBackend::setGOTSectionSize(IRBuilder& pBuilder) {
    291   // set .got.plt size
    292   if (LinkerConfig::DynObj == config().codeGenType() || m_pGOTPLT->hasGOT1() ||
    293       m_pGOTSymbol != NULL) {
    294     m_pGOTPLT->finalizeSectionSize();
    295     defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin()));
    296   }
    297 
    298   // set .got size
    299   if (!m_pGOT->empty())
    300     m_pGOT->finalizeSectionSize();
    301 }
    302 
    303 uint64_t HexagonLDBackend::emitGOTSectionData(MemoryRegion& pRegion) const {
    304   assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!");
    305 
    306   uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin());
    307 
    308   HexagonGOTEntry* got = 0;
    309   unsigned int EntrySize = HexagonGOTEntry::EntrySize;
    310   uint64_t RegionSize = 0;
    311 
    312   for (HexagonGOT::iterator it = m_pGOT->begin(), ie = m_pGOT->end(); it != ie;
    313        ++it, ++buffer) {
    314     got = &(llvm::cast<HexagonGOTEntry>((*it)));
    315     *buffer = static_cast<uint32_t>(got->getValue());
    316     RegionSize += EntrySize;
    317   }
    318 
    319   return RegionSize;
    320 }
    321 
    322 void HexagonLDBackend::defineGOTSymbol(IRBuilder& pBuilder, Fragment& pFrag) {
    323   // define symbol _GLOBAL_OFFSET_TABLE_
    324   if (m_pGOTSymbol != NULL) {
    325     pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
    326         "_GLOBAL_OFFSET_TABLE_",
    327         ResolveInfo::Object,
    328         ResolveInfo::Define,
    329         ResolveInfo::Local,
    330         0x0,  // size
    331         0x0,  // value
    332         FragmentRef::Create(pFrag, 0x0),
    333         ResolveInfo::Hidden);
    334   } else {
    335     m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
    336         "_GLOBAL_OFFSET_TABLE_",
    337         ResolveInfo::Object,
    338         ResolveInfo::Define,
    339         ResolveInfo::Local,
    340         0x0,  // size
    341         0x0,  // value
    342         FragmentRef::Create(pFrag, 0x0),
    343         ResolveInfo::Hidden);
    344   }
    345 }
    346 
    347 uint64_t HexagonLDBackend::emitGOTPLTSectionData(
    348     MemoryRegion& pRegion,
    349     const ELFFileFormat* FileFormat) const {
    350   assert(m_pGOTPLT != NULL &&
    351          "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!");
    352   m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr());
    353   m_pGOTPLT->applyAllGOTPLT(*m_pPLT);
    354 
    355   uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin());
    356 
    357   HexagonGOTEntry* got = 0;
    358   unsigned int EntrySize = HexagonGOTEntry::EntrySize;
    359   uint64_t RegionSize = 0;
    360 
    361   for (HexagonGOTPLT::iterator it = m_pGOTPLT->begin(), ie = m_pGOTPLT->end();
    362        it != ie;
    363        ++it, ++buffer) {
    364     got = &(llvm::cast<HexagonGOTEntry>((*it)));
    365     *buffer = static_cast<uint32_t>(got->getValue());
    366     RegionSize += EntrySize;
    367   }
    368 
    369   return RegionSize;
    370 }
    371 
    372 unsigned int HexagonLDBackend::getTargetSectionOrder(
    373     const LDSection& pSectHdr) const {
    374   const ELFFileFormat* file_format = getOutputFormat();
    375 
    376   if (LinkerConfig::Object != config().codeGenType()) {
    377     if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT())) {
    378       if (config().options().hasNow())
    379         return SHO_RELRO;
    380       return SHO_RELRO_LAST;
    381     }
    382 
    383     if (file_format->hasGOTPLT() && (&pSectHdr == &file_format->getGOTPLT())) {
    384       if (config().options().hasNow())
    385         return SHO_RELRO;
    386       return SHO_NON_RELRO_FIRST;
    387     }
    388 
    389     if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT()))
    390       return SHO_PLT;
    391   }
    392 
    393   if (&pSectHdr == m_pstart)
    394     return SHO_INIT;
    395 
    396   if (&pSectHdr == m_psdata)
    397     return SHO_SMALL_DATA;
    398 
    399   return SHO_UNDEFINED;
    400 }
    401 
    402 void HexagonLDBackend::initTargetSections(Module& pModule,
    403                                           ObjectBuilder& pBuilder) {
    404   if ((LinkerConfig::Object != config().codeGenType()) &&
    405       (!config().isCodeStatic())) {
    406     ELFFileFormat* file_format = getOutputFormat();
    407     // initialize .got
    408     LDSection& got = file_format->getGOT();
    409     m_pGOT = new HexagonGOT(got);
    410 
    411     // initialize .got.plt
    412     LDSection& gotplt = file_format->getGOTPLT();
    413     m_pGOTPLT = new HexagonGOTPLT(gotplt);
    414 
    415     // initialize .plt
    416     LDSection& plt = file_format->getPLT();
    417     m_pPLT = new HexagonPLT(plt, *m_pGOTPLT, config());
    418 
    419     // initialize .rela.plt
    420     LDSection& relaplt = file_format->getRelaPlt();
    421     relaplt.setLink(&plt);
    422     m_pRelaPLT = new OutputRelocSection(pModule, relaplt);
    423 
    424     // initialize .rela.dyn
    425     LDSection& reladyn = file_format->getRelaDyn();
    426     m_pRelaDyn = new OutputRelocSection(pModule, reladyn);
    427   }
    428   m_psdata = pBuilder.CreateSection(".sdata",
    429                                     LDFileFormat::Target,
    430                                     llvm::ELF::SHT_PROGBITS,
    431                                     llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    432                                     4 * 1024);
    433   m_pscommon_1 =
    434       pBuilder.CreateSection(".scommon.1",
    435                              LDFileFormat::Target,
    436                              llvm::ELF::SHT_PROGBITS,
    437                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    438                              1);
    439   IRBuilder::CreateSectionData(*m_pscommon_1);
    440 
    441   m_pscommon_2 =
    442       pBuilder.CreateSection(".scommon.2",
    443                              LDFileFormat::Target,
    444                              llvm::ELF::SHT_PROGBITS,
    445                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    446                              2);
    447   IRBuilder::CreateSectionData(*m_pscommon_2);
    448 
    449   m_pscommon_4 =
    450       pBuilder.CreateSection(".scommon.4",
    451                              LDFileFormat::Target,
    452                              llvm::ELF::SHT_PROGBITS,
    453                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    454                              4);
    455   IRBuilder::CreateSectionData(*m_pscommon_4);
    456 
    457   m_pscommon_8 =
    458       pBuilder.CreateSection(".scommon.8",
    459                              LDFileFormat::Target,
    460                              llvm::ELF::SHT_PROGBITS,
    461                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    462                              8);
    463   IRBuilder::CreateSectionData(*m_pscommon_8);
    464 
    465   m_pstart = pBuilder.CreateSection(".start",
    466                                     LDFileFormat::Target,
    467                                     llvm::ELF::SHT_PROGBITS,
    468                                     llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    469                                     8);
    470   IRBuilder::CreateSectionData(*m_pstart);
    471 }
    472 
    473 void HexagonLDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) {
    474   if (config().codeGenType() == LinkerConfig::Object)
    475     return;
    476 
    477   // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
    478   // same name in input
    479   m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
    480       "_GLOBAL_OFFSET_TABLE_",
    481       ResolveInfo::Object,
    482       ResolveInfo::Define,
    483       ResolveInfo::Local,
    484       0x0,  // size
    485       0x0,  // value
    486       FragmentRef::Null(),
    487       ResolveInfo::Hidden);
    488 
    489   m_psdabase = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
    490       "_SDA_BASE_",
    491       ResolveInfo::Object,
    492       ResolveInfo::Define,
    493       ResolveInfo::Absolute,
    494       0x0,  // size
    495       0x0,  // value
    496       FragmentRef::Null(),
    497       ResolveInfo::Hidden);
    498 
    499   pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
    500       "__sbss_start",
    501       ResolveInfo::Object,
    502       ResolveInfo::Define,
    503       ResolveInfo::Absolute,
    504       0x0,  // size
    505       0x0,  // value
    506       FragmentRef::Null(),
    507       ResolveInfo::Hidden);
    508 
    509   pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
    510       "__sbss_end",
    511       ResolveInfo::Object,
    512       ResolveInfo::Define,
    513       ResolveInfo::Absolute,
    514       0x0,  // size
    515       0x0,  // value
    516       FragmentRef::Null(),
    517       ResolveInfo::Hidden);
    518 }
    519 
    520 bool HexagonLDBackend::initTargetStubs() {
    521   if (getStubFactory() != NULL) {
    522     getStubFactory()->addPrototype(
    523         new HexagonAbsoluteStub(config().isCodeIndep()));
    524     return true;
    525   }
    526   return false;
    527 }
    528 
    529 bool HexagonLDBackend::initBRIslandFactory() {
    530   if (m_pBRIslandFactory == NULL) {
    531     m_pBRIslandFactory =
    532         new BranchIslandFactory(maxFwdBranchOffset(), maxBwdBranchOffset(), 0);
    533   }
    534   return true;
    535 }
    536 
    537 bool HexagonLDBackend::initStubFactory() {
    538   if (m_pStubFactory == NULL) {
    539     m_pStubFactory = new StubFactory();
    540   }
    541   return true;
    542 }
    543 
    544 bool HexagonLDBackend::doRelax(Module& pModule,
    545                                IRBuilder& pBuilder,
    546                                bool& pFinished) {
    547   assert(getStubFactory() != NULL && getBRIslandFactory() != NULL);
    548   bool isRelaxed = false;
    549   ELFFileFormat* file_format = getOutputFormat();
    550   // check branch relocs and create the related stubs if needed
    551   Module::obj_iterator input, inEnd = pModule.obj_end();
    552   for (input = pModule.obj_begin(); input != inEnd; ++input) {
    553     LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
    554     for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
    555       if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData())
    556         continue;
    557       RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end();
    558       for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) {
    559         switch (reloc->type()) {
    560           case llvm::ELF::R_HEX_B22_PCREL:
    561           case llvm::ELF::R_HEX_B15_PCREL:
    562           case llvm::ELF::R_HEX_B7_PCREL:
    563           case llvm::ELF::R_HEX_B13_PCREL:
    564           case llvm::ELF::R_HEX_B9_PCREL: {
    565             Relocation* relocation = llvm::cast<Relocation>(reloc);
    566             uint64_t sym_value = 0x0;
    567             LDSymbol* symbol = relocation->symInfo()->outSymbol();
    568             if (symbol->hasFragRef()) {
    569               uint64_t value = symbol->fragRef()->getOutputOffset();
    570               uint64_t addr =
    571                   symbol->fragRef()->frag()->getParent()->getSection().addr();
    572               sym_value = addr + value;
    573             }
    574             Stub* stub = getStubFactory()->create(*relocation,  // relocation
    575                                                   sym_value,  // symbol value
    576                                                   pBuilder,
    577                                                   *getBRIslandFactory());
    578             if (stub != NULL) {
    579               assert(stub->symInfo() != NULL);
    580               // increase the size of .symtab and .strtab
    581               LDSection& symtab = file_format->getSymTab();
    582               LDSection& strtab = file_format->getStrTab();
    583               symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym));
    584               strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1);
    585               isRelaxed = true;
    586             }
    587           } break;
    588 
    589           default:
    590             break;
    591         }
    592       }
    593     }
    594   }
    595 
    596   // find the first fragment w/ invalid offset due to stub insertion
    597   Fragment* invalid = NULL;
    598   pFinished = true;
    599   for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(),
    600                                      island_end = getBRIslandFactory()->end();
    601        island != island_end;
    602        ++island) {
    603     if ((*island).end() == file_format->getText().getSectionData()->end())
    604       break;
    605 
    606     Fragment* exit = (*island).end();
    607     if (((*island).offset() + (*island).size()) > exit->getOffset()) {
    608       invalid = exit;
    609       pFinished = false;
    610       break;
    611     }
    612   }
    613 
    614   // reset the offset of invalid fragments
    615   while (invalid != NULL) {
    616     invalid->setOffset(invalid->getPrevNode()->getOffset() +
    617                        invalid->getPrevNode()->size());
    618     invalid = invalid->getNextNode();
    619   }
    620 
    621   // reset the size of .text
    622   if (isRelaxed) {
    623     file_format->getText().setSize(
    624         file_format->getText().getSectionData()->back().getOffset() +
    625         file_format->getText().getSectionData()->back().size());
    626   }
    627   return isRelaxed;
    628 }
    629 
    630 /// finalizeSymbol - finalize the symbol value
    631 bool HexagonLDBackend::finalizeTargetSymbols() {
    632   if (config().codeGenType() == LinkerConfig::Object)
    633     return true;
    634   if (m_psdabase)
    635     m_psdabase->setValue(m_psdata->addr());
    636 
    637   ELFSegmentFactory::const_iterator edata = elfSegmentTable().find(
    638       llvm::ELF::PT_LOAD, llvm::ELF::PF_W, llvm::ELF::PF_X);
    639   if (elfSegmentTable().end() != edata) {
    640     if (f_pEData != NULL && ResolveInfo::ThreadLocal != f_pEData->type()) {
    641       f_pEData->setValue((*edata)->vaddr() + (*edata)->filesz());
    642     }
    643     if (f_p_EData != NULL && ResolveInfo::ThreadLocal != f_p_EData->type()) {
    644       f_p_EData->setValue((*edata)->vaddr() + (*edata)->filesz());
    645     }
    646     if (f_pBSSStart != NULL &&
    647         ResolveInfo::ThreadLocal != f_pBSSStart->type()) {
    648       f_pBSSStart->setValue((*edata)->vaddr() + (*edata)->filesz());
    649     }
    650     if (f_pEnd != NULL && ResolveInfo::ThreadLocal != f_pEnd->type()) {
    651       f_pEnd->setValue((((*edata)->vaddr() + (*edata)->memsz()) + 7) & ~7);
    652     }
    653     if (f_p_End != NULL && ResolveInfo::ThreadLocal != f_p_End->type()) {
    654       f_p_End->setValue((((*edata)->vaddr() + (*edata)->memsz()) + 7) & ~7);
    655     }
    656   }
    657   return true;
    658 }
    659 
    660 /// merge Input Sections
    661 bool HexagonLDBackend::mergeSection(Module& pModule,
    662                                     const Input& pInputFile,
    663                                     LDSection& pInputSection) {
    664   if ((pInputSection.flag() & llvm::ELF::SHF_HEX_GPREL) ||
    665       (pInputSection.kind() == LDFileFormat::LinkOnce) ||
    666       (pInputSection.kind() == LDFileFormat::Target)) {
    667     SectionData* sd = NULL;
    668     if (!m_psdata->hasSectionData()) {
    669       sd = IRBuilder::CreateSectionData(*m_psdata);
    670       m_psdata->setSectionData(sd);
    671     }
    672     sd = m_psdata->getSectionData();
    673     MoveSectionDataAndSort(*pInputSection.getSectionData(), *sd);
    674   } else {
    675     ObjectBuilder builder(pModule);
    676     builder.MergeSection(pInputFile, pInputSection);
    677   }
    678   return true;
    679 }
    680 
    681 bool HexagonLDBackend::SetSDataSection() {
    682   SectionData* pTo = (m_psdata->getSectionData());
    683 
    684   if (pTo) {
    685     MoveCommonData(*m_pscommon_1->getSectionData(), *pTo);
    686     MoveCommonData(*m_pscommon_2->getSectionData(), *pTo);
    687     MoveCommonData(*m_pscommon_4->getSectionData(), *pTo);
    688     MoveCommonData(*m_pscommon_8->getSectionData(), *pTo);
    689 
    690     SectionData::FragmentListType& to_list = pTo->getFragmentList();
    691     SectionData::FragmentListType::iterator fragTo, fragToEnd = to_list.end();
    692     uint32_t offset = 0;
    693     for (fragTo = to_list.begin(); fragTo != fragToEnd; ++fragTo) {
    694       fragTo->setOffset(offset);
    695       offset += fragTo->size();
    696     }
    697 
    698     // set up pTo's header
    699     pTo->getSection().setSize(offset);
    700 
    701     SectionData::FragmentListType& newlist = pTo->getFragmentList();
    702 
    703     for (fragTo = newlist.begin(), fragToEnd = newlist.end();
    704          fragTo != fragToEnd;
    705          ++fragTo) {
    706       fragTo->setParent(pTo);
    707     }
    708   }
    709 
    710   return true;
    711 }
    712 
    713 /// allocateCommonSymbols - allocate common symbols in the corresponding
    714 /// sections. This is called at pre-layout stage.
    715 bool HexagonLDBackend::allocateCommonSymbols(Module& pModule) {
    716   SymbolCategory& symbol_list = pModule.getSymbolTable();
    717 
    718   if (symbol_list.emptyCommons() && symbol_list.emptyLocals()) {
    719     SetSDataSection();
    720     return true;
    721   }
    722 
    723   int8_t maxGPSize = config().options().getGPSize();
    724 
    725   SymbolCategory::iterator com_sym, com_end;
    726 
    727   // get corresponding BSS LDSection
    728   ELFFileFormat* file_format = getOutputFormat();
    729   LDSection& bss_sect = file_format->getBSS();
    730   LDSection& tbss_sect = file_format->getTBSS();
    731 
    732   // get or create corresponding BSS SectionData
    733   SectionData* bss_sect_data = NULL;
    734   if (bss_sect.hasSectionData())
    735     bss_sect_data = bss_sect.getSectionData();
    736   else
    737     bss_sect_data = IRBuilder::CreateSectionData(bss_sect);
    738 
    739   SectionData* tbss_sect_data = NULL;
    740   if (tbss_sect.hasSectionData())
    741     tbss_sect_data = tbss_sect.getSectionData();
    742   else
    743     tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect);
    744 
    745   // remember original BSS size
    746   uint64_t bss_offset = bss_sect.size();
    747   uint64_t tbss_offset = tbss_sect.size();
    748 
    749   // allocate all local common symbols
    750   com_end = symbol_list.localEnd();
    751 
    752   for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) {
    753     if (ResolveInfo::Common == (*com_sym)->desc()) {
    754       // We have to reset the description of the symbol here. When doing
    755       // incremental linking, the output relocatable object may have common
    756       // symbols. Therefore, we can not treat common symbols as normal symbols
    757       // when emitting the regular name pools. We must change the symbols'
    758       // description here.
    759       (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
    760       Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
    761 
    762       switch ((*com_sym)->size()) {
    763         case 1:
    764           if (maxGPSize <= 0)
    765             break;
    766           ObjectBuilder::AppendFragment(
    767               *frag, *(m_pscommon_1->getSectionData()), (*com_sym)->value());
    768           (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
    769           continue;
    770         case 2:
    771           if (maxGPSize <= 1)
    772             break;
    773           ObjectBuilder::AppendFragment(
    774               *frag, *(m_pscommon_2->getSectionData()), (*com_sym)->value());
    775           (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
    776           continue;
    777         case 4:
    778           if (maxGPSize <= 3)
    779             break;
    780           ObjectBuilder::AppendFragment(
    781               *frag, *(m_pscommon_4->getSectionData()), (*com_sym)->value());
    782           (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
    783           continue;
    784         case 8:
    785           if (maxGPSize <= 7)
    786             break;
    787           ObjectBuilder::AppendFragment(
    788               *frag, *(m_pscommon_8->getSectionData()), (*com_sym)->value());
    789           (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
    790           continue;
    791         default:
    792           break;
    793       }
    794 
    795       if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
    796         // allocate TLS common symbol in tbss section
    797         tbss_offset += ObjectBuilder::AppendFragment(
    798             *frag, *tbss_sect_data, (*com_sym)->value());
    799         (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
    800       } else {
    801         // FIXME: how to identify small and large common symbols?
    802         bss_offset += ObjectBuilder::AppendFragment(
    803             *frag, *bss_sect_data, (*com_sym)->value());
    804         (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
    805       }
    806     }
    807   }
    808 
    809   // allocate all global common symbols
    810   com_end = symbol_list.commonEnd();
    811   for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) {
    812     // We have to reset the description of the symbol here. When doing
    813     // incremental linking, the output relocatable object may have common
    814     // symbols. Therefore, we can not treat common symbols as normal symbols
    815     // when emitting the regular name pools. We must change the symbols'
    816     // description here.
    817     (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define);
    818     Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size());
    819 
    820     switch ((*com_sym)->size()) {
    821       case 1:
    822         if (maxGPSize <= 0)
    823           break;
    824         ObjectBuilder::AppendFragment(
    825             *frag, *(m_pscommon_1->getSectionData()), (*com_sym)->value());
    826         (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
    827         continue;
    828       case 2:
    829         if (maxGPSize <= 1)
    830           break;
    831         ObjectBuilder::AppendFragment(
    832             *frag, *(m_pscommon_2->getSectionData()), (*com_sym)->value());
    833         (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
    834         continue;
    835       case 4:
    836         if (maxGPSize <= 3)
    837           break;
    838         ObjectBuilder::AppendFragment(
    839             *frag, *(m_pscommon_4->getSectionData()), (*com_sym)->value());
    840         (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
    841         continue;
    842       case 8:
    843         if (maxGPSize <= 7)
    844           break;
    845         ObjectBuilder::AppendFragment(
    846             *frag, *(m_pscommon_8->getSectionData()), (*com_sym)->value());
    847         (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
    848         continue;
    849       default:
    850         break;
    851     }
    852 
    853     if (ResolveInfo::ThreadLocal == (*com_sym)->type()) {
    854       // allocate TLS common symbol in tbss section
    855       tbss_offset += ObjectBuilder::AppendFragment(
    856           *frag, *tbss_sect_data, (*com_sym)->value());
    857       (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
    858     } else {
    859       // FIXME: how to identify small and large common symbols?
    860       bss_offset += ObjectBuilder::AppendFragment(
    861           *frag, *bss_sect_data, (*com_sym)->value());
    862       (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0));
    863     }
    864   }
    865 
    866   bss_sect.setSize(bss_offset);
    867   tbss_sect.setSize(tbss_offset);
    868   symbol_list.changeCommonsToGlobal();
    869   SetSDataSection();
    870   return true;
    871 }
    872 
    873 bool HexagonLDBackend::MoveCommonData(SectionData& pFrom, SectionData& pTo) {
    874   SectionData::FragmentListType& to_list = pTo.getFragmentList();
    875   SectionData::FragmentListType::iterator frag, fragEnd = to_list.end();
    876 
    877   uint32_t pFromFlag = pFrom.getSection().align();
    878   bool found = false;
    879 
    880   SectionData::FragmentListType::iterator fragInsert;
    881 
    882   for (frag = to_list.begin(); frag != fragEnd; ++frag) {
    883     if (frag->getKind() == mcld::Fragment::Alignment) {
    884       fragInsert = frag;
    885       continue;
    886     }
    887     if ((frag->getKind() != mcld::Fragment::Region) &&
    888         (frag->getKind() != mcld::Fragment::Fillment)) {
    889       continue;
    890     }
    891     uint32_t flag = frag->getParent()->getSection().align();
    892     if (pFromFlag < flag) {
    893       found = true;
    894       break;
    895     }
    896   }
    897   AlignFragment* align = NULL;
    898   if (pFrom.getSection().align() > 1) {
    899     // if the align constraint is larger than 1, append an alignment
    900     unsigned int alignment = pFrom.getSection().align();
    901     align = new AlignFragment(/*alignment*/alignment,
    902                               /*the filled value*/0x0,
    903                               /*the size of filled value*/1u,
    904                               /*max bytes to emit*/alignment - 1);
    905     pFrom.getFragmentList().push_front(align);
    906   }
    907   if (found)
    908     to_list.splice(fragInsert, pFrom.getFragmentList());
    909   else
    910     to_list.splice(frag, pFrom.getFragmentList());
    911 
    912   return true;
    913 }
    914 
    915 bool HexagonLDBackend::readSection(Input& pInput, SectionData& pSD) {
    916   Fragment* frag = NULL;
    917   uint32_t offset = pInput.fileOffset() + pSD.getSection().offset();
    918   uint32_t size = pSD.getSection().size();
    919 
    920   if (pSD.getSection().type() == llvm::ELF::SHT_NOBITS) {
    921     frag = new FillFragment(0x0, 1, size);
    922   } else {
    923     llvm::StringRef region = pInput.memArea()->request(offset, size);
    924     if (region.size() == 0) {
    925       // If the input section's size is zero, we got a NULL region.
    926       // use a virtual fill fragment
    927       frag = new FillFragment(0x0, 0, 0);
    928     } else {
    929       frag = new RegionFragment(region);
    930     }
    931   }
    932 
    933   ObjectBuilder::AppendFragment(*frag, pSD);
    934   return true;
    935 }
    936 
    937 /// MoveSectionData - move the fragments of pTO section data to pTo
    938 bool HexagonLDBackend::MoveSectionDataAndSort(SectionData& pFrom,
    939                                               SectionData& pTo) {
    940   assert(&pFrom != &pTo && "Cannot move section data to itself!");
    941   SectionData::FragmentListType& to_list = pTo.getFragmentList();
    942   SectionData::FragmentListType::iterator frag, fragEnd = to_list.end();
    943 
    944   uint32_t pFromFlag = pFrom.getSection().align();
    945   bool found = false;
    946 
    947   SectionData::FragmentListType::iterator fragInsert;
    948 
    949   for (frag = to_list.begin(); frag != fragEnd; ++frag) {
    950     if (frag->getKind() == mcld::Fragment::Alignment) {
    951       fragInsert = frag;
    952       continue;
    953     }
    954     if ((frag->getKind() != mcld::Fragment::Region) &&
    955         (frag->getKind() != mcld::Fragment::Fillment)) {
    956       continue;
    957     }
    958     uint32_t flag = frag->getParent()->getSection().align();
    959     if (pFromFlag < flag) {
    960       found = true;
    961       break;
    962     }
    963   }
    964   AlignFragment* align = NULL;
    965   if (pFrom.getSection().align() > 1) {
    966     // if the align constraint is larger than 1, append an alignment
    967     unsigned int alignment = pFrom.getSection().align();
    968     align = new AlignFragment(/*alignment*/alignment,
    969                               /*the filled value*/0x0,
    970                               /*the size of filled value*/1u,
    971                               /*max bytes to emit*/alignment - 1);
    972     pFrom.getFragmentList().push_front(align);
    973   }
    974   if (found)
    975     to_list.splice(fragInsert, pFrom.getFragmentList());
    976   else
    977     to_list.splice(frag, pFrom.getFragmentList());
    978 
    979   uint32_t offset = 0;
    980   for (frag = to_list.begin(); frag != fragEnd; ++frag) {
    981     frag->setOffset(offset);
    982     offset += frag->size();
    983   }
    984 
    985   // set up pTo's header
    986   pTo.getSection().setSize(offset);
    987 
    988   if (pFrom.getSection().align() > pTo.getSection().align())
    989     pTo.getSection().setAlign(pFrom.getSection().align());
    990 
    991   if (pFrom.getSection().flag() > pTo.getSection().flag())
    992     pTo.getSection().setFlag(pFrom.getSection().flag());
    993   return true;
    994 }
    995 
    996 /// doCreateProgramHdrs - backend can implement this function to create the
    997 /// target-dependent segments
    998 void HexagonLDBackend::doCreateProgramHdrs(Module& pModule) {
    999   // TODO
   1000 }
   1001 
   1002 //===----------------------------------------------------------------------===//
   1003 /// createHexagonLDBackend - the help funtion to create corresponding
   1004 /// HexagonLDBackend
   1005 TargetLDBackend* createHexagonLDBackend(const LinkerConfig& pConfig) {
   1006   if (pConfig.targets().triple().isOSDarwin()) {
   1007     assert(0 && "MachO linker is not supported yet");
   1008     /**
   1009     return new HexagonMachOLDBackend(createHexagonMachOArchiveReader,
   1010                                createHexagonMachOObjectReader,
   1011                                createHexagonMachOObjectWriter);
   1012     **/
   1013   }
   1014   if (pConfig.targets().triple().isOSWindows()) {
   1015     assert(0 && "COFF linker is not supported yet");
   1016     /**
   1017     return new HexagonCOFFLDBackend(createHexagonCOFFArchiveReader,
   1018                                createHexagonCOFFObjectReader,
   1019                                createHexagonCOFFObjectWriter);
   1020     **/
   1021   }
   1022   return new HexagonLDBackend(pConfig, new HexagonGNUInfo(pConfig.targets()));
   1023 }
   1024 
   1025 }  // namespace mcld
   1026 
   1027 //===----------------------------------------------------------------------===//
   1028 // Force static initialization.
   1029 //===----------------------------------------------------------------------===//
   1030 extern "C" void MCLDInitializeHexagonLDBackend() {
   1031   // Register the linker backend
   1032   mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheHexagonTarget,
   1033                                                 mcld::createHexagonLDBackend);
   1034 }
   1035