16f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===- HexagonLDBackend.cpp -----------------------------------------------===// 26f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// 36f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// The MCLinker Project 46f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// 56f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// This file is distributed under the University of Illinois Open Source 66f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// License. See LICENSE.TXT for details. 76f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// 86f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 96f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include "Hexagon.h" 106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include "HexagonELFDynamic.h" 116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include "HexagonLDBackend.h" 126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include "HexagonRelocator.h" 136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include "HexagonGNUInfo.h" 14f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include "HexagonAbsoluteStub.h" 156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/IRBuilder.h" 1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerConfig.h" 1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/AlignFragment.h" 1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/FillFragment.h" 2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/RegionFragment.h" 2137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/Stub.h" 2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/BranchIslandFactory.h" 2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFFileFormat.h" 2437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFSegmentFactory.h" 2537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFSegment.h" 2637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDContext.h" 2737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/StubFactory.h" 2837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Object/ObjectBuilder.h" 2937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MemoryArea.h" 3037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h" 3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/TargetRegistry.h" 3237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/ADT/Triple.h> 346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/Support/Casting.h> 356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <cstring> 37cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines#include <vector> 386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// HexagonLDBackend 436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 44f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesHexagonLDBackend::HexagonLDBackend(const LinkerConfig& pConfig, 456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonGNUInfo* pInfo) 4637b74a387bb3993387029859c2d9d051c41c724eStephen Hines : GNULDBackend(pConfig, pInfo), 4737b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pRelocator(NULL), 4837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOT(NULL), 4937b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOTPLT(NULL), 5037b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pPLT(NULL), 5137b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pRelaDyn(NULL), 5237b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pRelaPLT(NULL), 5337b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pDynamic(NULL), 5437b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOTSymbol(NULL), 5537b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_CopyRel(llvm::ELF::R_HEX_COPY) { 566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5837b74a387bb3993387029859c2d9d051c41c724eStephen HinesHexagonLDBackend::~HexagonLDBackend() { 596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pRelocator; 606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pGOT; 616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pPLT; 62f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines delete m_pRelaDyn; 63f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines delete m_pRelaPLT; 646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines delete m_pDynamic; 656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool HexagonLDBackend::initRelocator() { 6837b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pRelocator == NULL) { 69f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pRelocator = new HexagonRelocator(*this, config()); 706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst Relocator* HexagonLDBackend::getRelocator() const { 7537b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelocator != NULL); 760dea6bc96bb52346737966839ac68644f7939f58Stephen Hines return m_pRelocator; 770dea6bc96bb52346737966839ac68644f7939f58Stephen Hines} 780dea6bc96bb52346737966839ac68644f7939f58Stephen Hines 7937b74a387bb3993387029859c2d9d051c41c724eStephen HinesRelocator* HexagonLDBackend::getRelocator() { 8037b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelocator != NULL); 816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return m_pRelocator; 826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid HexagonLDBackend::doPreLayout(IRBuilder& pBuilder) { 856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .dynamic data 8637b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (!config().isCodeStatic() && m_pDynamic == NULL) 876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pDynamic = new HexagonELFDynamic(*this, config()); 88f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 89f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set .got.plt and .got sizes 90f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // when building shared object, the .got section is must 91f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ((LinkerConfig::Object != config().codeGenType()) && 92f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (!config().isCodeStatic())) { 93f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines setGOTSectionSize(pBuilder); 94f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 95f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set .plt size 96f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_pPLT->hasPLT1()) 97f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pPLT->finalizeSectionSize(); 98f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 99f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set .rela.dyn size 100f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!m_pRelaDyn->empty()) { 10137b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert( 10237b74a387bb3993387029859c2d9d051c41c724eStephen Hines !config().isCodeStatic() && 10337b74a387bb3993387029859c2d9d051c41c724eStephen Hines "static linkage should not result in a dynamic relocation section"); 104f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines setRelaDynSize(); 105f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 106f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set .rela.plt size 107f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!m_pRelaPLT->empty()) { 10837b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert( 10937b74a387bb3993387029859c2d9d051c41c724eStephen Hines !config().isCodeStatic() && 11037b74a387bb3993387029859c2d9d051c41c724eStephen Hines "static linkage should not result in a dynamic relocation section"); 111f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines setRelaPLTSize(); 112f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 113f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 114f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // Shared libraries are compiled with -G0 so there is no need to set SData. 115f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (LinkerConfig::Object == config().codeGenType()) 116f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SetSDataSection(); 1176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid HexagonLDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) { 1206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// dynamic - the dynamic section of the target machine. 1236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// Use co-variant return type to return its own dynamic section. 12437b74a387bb3993387029859c2d9d051c41c724eStephen HinesHexagonELFDynamic& HexagonLDBackend::dynamic() { 12537b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pDynamic != NULL); 1266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pDynamic; 1276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// dynamic - the dynamic section of the target machine. 1306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// Use co-variant return type to return its own dynamic section. 13137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst HexagonELFDynamic& HexagonLDBackend::dynamic() const { 13237b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pDynamic != NULL); 1336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pDynamic; 1346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t HexagonLDBackend::emitSectionData(const LDSection& pSection, 13737b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion& pRegion) const { 138f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!pRegion.size()) 139f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return 0; 140f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 141f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const ELFFileFormat* FileFormat = getOutputFormat(); 142f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines unsigned int EntrySize = 0; 143f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t RegionSize = 0; 144f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 145f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ((LinkerConfig::Object != config().codeGenType()) && 146f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (!config().isCodeStatic())) { 14787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (FileFormat->hasPLT() && (&pSection == &(FileFormat->getPLT()))) { 14887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines unsigned char* buffer = pRegion.begin(); 149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 150f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pPLT->applyPLT0(); 151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pPLT->applyPLT1(); 152f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines HexagonPLT::iterator it = m_pPLT->begin(); 153f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines unsigned int plt0_size = llvm::cast<PLTEntryBase>((*it)).size(); 154f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 155f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines memcpy(buffer, llvm::cast<PLTEntryBase>((*it)).getValue(), plt0_size); 156f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines RegionSize += plt0_size; 157f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++it; 158f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 159f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines PLTEntryBase* plt1 = 0; 160f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines HexagonPLT::iterator ie = m_pPLT->end(); 161f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines while (it != ie) { 162f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines plt1 = &(llvm::cast<PLTEntryBase>(*it)); 163f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines EntrySize = plt1->size(); 164f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines memcpy(buffer + RegionSize, plt1->getValue(), EntrySize); 165f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines RegionSize += EntrySize; 166f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++it; 167f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 168f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return RegionSize; 16937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else if (FileFormat->hasGOT() && (&pSection == &(FileFormat->getGOT()))) { 170f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines RegionSize += emitGOTSectionData(pRegion); 171f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return RegionSize; 17237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else if (FileFormat->hasGOTPLT() && 17337b74a387bb3993387029859c2d9d051c41c724eStephen Hines (&pSection == &(FileFormat->getGOTPLT()))) { 174f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines RegionSize += emitGOTPLTSectionData(pRegion, FileFormat); 175f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return RegionSize; 176f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 177f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 178f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 179f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const SectionData* sect_data = pSection.getSectionData(); 180f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData::const_iterator frag_iter, frag_end = sect_data->end(); 18187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint8_t* out_offset = pRegion.begin(); 182f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) { 183f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines size_t size = frag_iter->size(); 18437b74a387bb3993387029859c2d9d051c41c724eStephen Hines switch (frag_iter->getKind()) { 185f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case Fragment::Fillment: { 18637b74a387bb3993387029859c2d9d051c41c724eStephen Hines const FillFragment& fill_frag = llvm::cast<FillFragment>(*frag_iter); 18737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (fill_frag.getValueSize() == 0) { 188f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // virtual fillment, ignore it. 189f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 190f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 191f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines memset(out_offset, fill_frag.getValue(), fill_frag.size()); 192f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 193f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 194f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case Fragment::Region: { 195f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const RegionFragment& region_frag = 19637b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::cast<RegionFragment>(*frag_iter); 19787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const char* start = region_frag.getRegion().begin(); 198f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines memcpy(out_offset, start, size); 199f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 200f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 201f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case Fragment::Alignment: { 202f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const AlignFragment& align_frag = llvm::cast<AlignFragment>(*frag_iter); 203f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t count = size / align_frag.getValueSize(); 204f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines switch (align_frag.getValueSize()) { 205f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case 1u: 206f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::memset(out_offset, align_frag.getValue(), count); 207f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 208f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines default: 209f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::report_fatal_error( 21037b74a387bb3993387029859c2d9d051c41c724eStephen Hines "unsupported value size for align fragment emission yet.\n"); 211f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 21237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end switch 213f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 214f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 215f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case Fragment::Null: { 216f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(0x0 == size); 217f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 218f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 219f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines default: 220f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::report_fatal_error("unsupported fragment type.\n"); 221f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 22237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end switch 223f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines out_offset += size; 22437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end for 225f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 226f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return pRegion.size(); 2276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 22937b74a387bb3993387029859c2d9d051c41c724eStephen HinesHexagonGOT& HexagonLDBackend::getGOT() { 23037b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOT != NULL); 2316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pGOT; 2326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 23437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst HexagonGOT& HexagonLDBackend::getGOT() const { 23537b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOT != NULL); 2366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pGOT; 2376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 23937b74a387bb3993387029859c2d9d051c41c724eStephen HinesHexagonPLT& HexagonLDBackend::getPLT() { 24037b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pPLT != NULL && "PLT section not exist"); 2416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pPLT; 2426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 24437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst HexagonPLT& HexagonLDBackend::getPLT() const { 24537b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pPLT != NULL && "PLT section not exist"); 2466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pPLT; 2476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 24937b74a387bb3993387029859c2d9d051c41c724eStephen HinesOutputRelocSection& HexagonLDBackend::getRelaDyn() { 25037b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelaDyn != NULL && ".rela.dyn section not exist"); 251f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return *m_pRelaDyn; 252f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 253f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 25437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst OutputRelocSection& HexagonLDBackend::getRelaDyn() const { 25537b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelaDyn != NULL && ".rela.dyn section not exist"); 256f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return *m_pRelaDyn; 257f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 258f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 25937b74a387bb3993387029859c2d9d051c41c724eStephen HinesOutputRelocSection& HexagonLDBackend::getRelaPLT() { 26037b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelaPLT != NULL && ".rela.plt section not exist"); 261f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return *m_pRelaPLT; 262f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 263f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 26437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst OutputRelocSection& HexagonLDBackend::getRelaPLT() const { 26537b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pRelaPLT != NULL && ".rela.plt section not exist"); 266f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return *m_pRelaPLT; 267f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 268f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 26937b74a387bb3993387029859c2d9d051c41c724eStephen HinesHexagonGOTPLT& HexagonLDBackend::getGOTPLT() { 27037b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOTPLT != NULL); 271f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return *m_pGOTPLT; 272f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 273f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 27437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst HexagonGOTPLT& HexagonLDBackend::getGOTPLT() const { 27537b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOTPLT != NULL); 276f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return *m_pGOTPLT; 2776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 27937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid HexagonLDBackend::setRelaDynSize() { 280f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 28137b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_format->getRelaDyn().setSize(m_pRelaDyn->numOfRelocs() * 28237b74a387bb3993387029859c2d9d051c41c724eStephen Hines getRelaEntrySize()); 2836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 28537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid HexagonLDBackend::setRelaPLTSize() { 286f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 28737b74a387bb3993387029859c2d9d051c41c724eStephen Hines file_format->getRelaPlt().setSize(m_pRelaPLT->numOfRelocs() * 28837b74a387bb3993387029859c2d9d051c41c724eStephen Hines getRelaEntrySize()); 2896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 29137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid HexagonLDBackend::setGOTSectionSize(IRBuilder& pBuilder) { 292f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set .got.plt size 29337b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (LinkerConfig::DynObj == config().codeGenType() || m_pGOTPLT->hasGOT1() || 29437b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pGOTSymbol != NULL) { 295f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGOTPLT->finalizeSectionSize(); 296f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin())); 297f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 298f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 299f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set .got size 300f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!m_pGOT->empty()) 301f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGOT->finalizeSectionSize(); 302f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 303f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 30437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t HexagonLDBackend::emitGOTSectionData(MemoryRegion& pRegion) const { 305f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!"); 306f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 30787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin()); 308f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 309f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines HexagonGOTEntry* got = 0; 310f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines unsigned int EntrySize = HexagonGOTEntry::EntrySize; 311f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t RegionSize = 0; 312f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 31337b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (HexagonGOT::iterator it = m_pGOT->begin(), ie = m_pGOT->end(); it != ie; 31437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++it, ++buffer) { 315f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines got = &(llvm::cast<HexagonGOTEntry>((*it))); 316f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *buffer = static_cast<uint32_t>(got->getValue()); 317f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines RegionSize += EntrySize; 318f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 319f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 320f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return RegionSize; 321f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 322f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 32337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid HexagonLDBackend::defineGOTSymbol(IRBuilder& pBuilder, Fragment& pFrag) { 324f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // define symbol _GLOBAL_OFFSET_TABLE_ 325f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_pGOTSymbol != NULL) { 326f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 32737b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_GLOBAL_OFFSET_TABLE_", 32837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 32937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 33037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 33137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 33237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 33337b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Create(pFrag, 0x0), 33437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 33537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 336f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 33737b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_GLOBAL_OFFSET_TABLE_", 33837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 33937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 34037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 34137b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 34237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 34337b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Create(pFrag, 0x0), 34437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 345f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 346f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 347f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 34837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t HexagonLDBackend::emitGOTPLTSectionData( 34937b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion& pRegion, 35037b74a387bb3993387029859c2d9d051c41c724eStephen Hines const ELFFileFormat* FileFormat) const { 35137b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(m_pGOTPLT != NULL && 35237b74a387bb3993387029859c2d9d051c41c724eStephen Hines "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!"); 353f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr()); 354f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGOTPLT->applyAllGOTPLT(*m_pPLT); 355f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 35687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin()); 357f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 358f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines HexagonGOTEntry* got = 0; 359f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines unsigned int EntrySize = HexagonGOTEntry::EntrySize; 360f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t RegionSize = 0; 361f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 36237b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (HexagonGOTPLT::iterator it = m_pGOTPLT->begin(), ie = m_pGOTPLT->end(); 36337b74a387bb3993387029859c2d9d051c41c724eStephen Hines it != ie; 36437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++it, ++buffer) { 365f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines got = &(llvm::cast<HexagonGOTEntry>((*it))); 366f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *buffer = static_cast<uint32_t>(got->getValue()); 367f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines RegionSize += EntrySize; 368f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 369f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 370f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return RegionSize; 3716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 37337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesunsigned int HexagonLDBackend::getTargetSectionOrder( 37437b74a387bb3993387029859c2d9d051c41c724eStephen Hines const LDSection& pSectHdr) const { 3756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const ELFFileFormat* file_format = getOutputFormat(); 3766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 377f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (LinkerConfig::Object != config().codeGenType()) { 37887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT())) { 379f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (config().options().hasNow()) 380f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return SHO_RELRO; 381f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return SHO_RELRO_LAST; 382f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 383f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 38487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasGOTPLT() && (&pSectHdr == &file_format->getGOTPLT())) { 385f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (config().options().hasNow()) 386f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return SHO_RELRO; 387f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return SHO_NON_RELRO_FIRST; 388f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 389f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 39087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT())) 391f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return SHO_PLT; 3926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 3936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 394f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (&pSectHdr == m_pstart) 395f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return SHO_INIT; 396f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 397f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (&pSectHdr == m_psdata) 398f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return SHO_SMALL_DATA; 3996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_UNDEFINED; 4016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 403f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid HexagonLDBackend::initTargetSections(Module& pModule, 40437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ObjectBuilder& pBuilder) { 405f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ((LinkerConfig::Object != config().codeGenType()) && 406f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (!config().isCodeStatic())) { 4076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 4086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .got 4096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& got = file_format->getGOT(); 4106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOT = new HexagonGOT(got); 4116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 412f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // initialize .got.plt 413f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSection& gotplt = file_format->getGOTPLT(); 414f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGOTPLT = new HexagonGOTPLT(gotplt); 415f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 4166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .plt 4176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& plt = file_format->getPLT(); 41837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pPLT = new HexagonPLT(plt, *m_pGOTPLT, config()); 4196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 420f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // initialize .rela.plt 421f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSection& relaplt = file_format->getRelaPlt(); 422f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines relaplt.setLink(&plt); 423f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pRelaPLT = new OutputRelocSection(pModule, relaplt); 4246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 425f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // initialize .rela.dyn 426f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSection& reladyn = file_format->getRelaDyn(); 427f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pRelaDyn = new OutputRelocSection(pModule, reladyn); 4286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 429f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_psdata = pBuilder.CreateSection(".sdata", 430f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDFileFormat::Target, 431f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::ELF::SHT_PROGBITS, 432f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 43337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 4 * 1024); 43437b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pscommon_1 = 43537b74a387bb3993387029859c2d9d051c41c724eStephen Hines pBuilder.CreateSection(".scommon.1", 43637b74a387bb3993387029859c2d9d051c41c724eStephen Hines LDFileFormat::Target, 43737b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::ELF::SHT_PROGBITS, 43837b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 43937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1); 440f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines IRBuilder::CreateSectionData(*m_pscommon_1); 441f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 44237b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pscommon_2 = 44337b74a387bb3993387029859c2d9d051c41c724eStephen Hines pBuilder.CreateSection(".scommon.2", 44437b74a387bb3993387029859c2d9d051c41c724eStephen Hines LDFileFormat::Target, 44537b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::ELF::SHT_PROGBITS, 44637b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 44737b74a387bb3993387029859c2d9d051c41c724eStephen Hines 2); 448f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines IRBuilder::CreateSectionData(*m_pscommon_2); 449f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 45037b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pscommon_4 = 45137b74a387bb3993387029859c2d9d051c41c724eStephen Hines pBuilder.CreateSection(".scommon.4", 45237b74a387bb3993387029859c2d9d051c41c724eStephen Hines LDFileFormat::Target, 45337b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::ELF::SHT_PROGBITS, 45437b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 45537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 4); 456f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines IRBuilder::CreateSectionData(*m_pscommon_4); 457f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 45837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pscommon_8 = 45937b74a387bb3993387029859c2d9d051c41c724eStephen Hines pBuilder.CreateSection(".scommon.8", 46037b74a387bb3993387029859c2d9d051c41c724eStephen Hines LDFileFormat::Target, 46137b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::ELF::SHT_PROGBITS, 46237b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 46337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 8); 464f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines IRBuilder::CreateSectionData(*m_pscommon_8); 465f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 466f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pstart = pBuilder.CreateSection(".start", 467f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDFileFormat::Target, 468f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::ELF::SHT_PROGBITS, 469f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 470f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 8); 471f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines IRBuilder::CreateSectionData(*m_pstart); 4726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 47437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid HexagonLDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) { 475f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (config().codeGenType() == LinkerConfig::Object) 476f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return; 477f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 478f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 479f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // same name in input 480f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 48137b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_GLOBAL_OFFSET_TABLE_", 48237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 48337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 48437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Local, 48537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 48637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 48737b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), 48837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 48937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 49037b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_psdabase = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 49137b74a387bb3993387029859c2d9d051c41c724eStephen Hines "_SDA_BASE_", 49237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 49337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 49437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Absolute, 49537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 49637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 49737b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), 49837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 49937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 500f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 50137b74a387bb3993387029859c2d9d051c41c724eStephen Hines "__sbss_start", 50237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 50337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 50437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Absolute, 50537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 50637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 50737b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), 50837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 50937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 510f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 51137b74a387bb3993387029859c2d9d051c41c724eStephen Hines "__sbss_end", 51237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object, 51337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Define, 51437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Absolute, 51537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // size 51637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 0x0, // value 51737b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef::Null(), 51837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Hidden); 519f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 520f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 52137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool HexagonLDBackend::initTargetStubs() { 52237b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (getStubFactory() != NULL) { 52337b74a387bb3993387029859c2d9d051c41c724eStephen Hines getStubFactory()->addPrototype( 52437b74a387bb3993387029859c2d9d051c41c724eStephen Hines new HexagonAbsoluteStub(config().isCodeIndep())); 525f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 526f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 527f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return false; 528f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 529f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 53037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool HexagonLDBackend::initBRIslandFactory() { 53137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pBRIslandFactory == NULL) { 53237b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pBRIslandFactory = 53337b74a387bb3993387029859c2d9d051c41c724eStephen Hines new BranchIslandFactory(maxFwdBranchOffset(), maxBwdBranchOffset(), 0); 534f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 535f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 536f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 537f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 53837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool HexagonLDBackend::initStubFactory() { 53937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pStubFactory == NULL) { 540f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pStubFactory = new StubFactory(); 5416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 542f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 543f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 544f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 54537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool HexagonLDBackend::doRelax(Module& pModule, 54637b74a387bb3993387029859c2d9d051c41c724eStephen Hines IRBuilder& pBuilder, 54737b74a387bb3993387029859c2d9d051c41c724eStephen Hines bool& pFinished) { 54837b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(getStubFactory() != NULL && getBRIslandFactory() != NULL); 549f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool isRelaxed = false; 550f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 551f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // check branch relocs and create the related stubs if needed 552f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Module::obj_iterator input, inEnd = pModule.obj_end(); 553f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (input = pModule.obj_begin(); input != inEnd; ++input) { 554f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); 555f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 556f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData()) 557f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 558f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end(); 559f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) { 560f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines switch (reloc->type()) { 561f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case llvm::ELF::R_HEX_B22_PCREL: 562f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case llvm::ELF::R_HEX_B15_PCREL: 563f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case llvm::ELF::R_HEX_B7_PCREL: 564f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case llvm::ELF::R_HEX_B13_PCREL: 565f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case llvm::ELF::R_HEX_B9_PCREL: { 566f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Relocation* relocation = llvm::cast<Relocation>(reloc); 567f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t sym_value = 0x0; 568f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSymbol* symbol = relocation->symInfo()->outSymbol(); 569f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (symbol->hasFragRef()) { 570f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t value = symbol->fragRef()->getOutputOffset(); 571f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t addr = 57237b74a387bb3993387029859c2d9d051c41c724eStephen Hines symbol->fragRef()->frag()->getParent()->getSection().addr(); 573f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines sym_value = addr + value; 574f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 57537b74a387bb3993387029859c2d9d051c41c724eStephen Hines Stub* stub = getStubFactory()->create(*relocation, // relocation 57637b74a387bb3993387029859c2d9d051c41c724eStephen Hines sym_value, // symbol value 577f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pBuilder, 578f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *getBRIslandFactory()); 57937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (stub != NULL) { 58037b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(stub->symInfo() != NULL); 581cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // reset the branch target of the reloc to this stub instead 582cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines relocation->setSymInfo(stub->symInfo()); 583cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 584f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // increase the size of .symtab and .strtab 585f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSection& symtab = file_format->getSymTab(); 586f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSection& strtab = file_format->getStrTab(); 587f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym)); 588f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1); 589f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines isRelaxed = true; 590f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 59137b74a387bb3993387029859c2d9d051c41c724eStephen Hines } break; 592f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 593f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines default: 594f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 595f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 596f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 597f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 598f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 599f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 600f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // find the first fragment w/ invalid offset due to stub insertion 601cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines std::vector<Fragment*> invalid_frags; 602f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pFinished = true; 603f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(), 60437b74a387bb3993387029859c2d9d051c41c724eStephen Hines island_end = getBRIslandFactory()->end(); 60537b74a387bb3993387029859c2d9d051c41c724eStephen Hines island != island_end; 60637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++island) { 607cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if ((*island).size() > stubGroupSize()) { 608cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines error(diag::err_no_space_to_place_stubs) << stubGroupSize(); 609cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines return false; 610cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 611cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 612cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if ((*island).numOfStubs() == 0) { 613cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines continue; 614cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 615cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines 616cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines Fragment* exit = &*(*island).end(); 617cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (exit == (*island).begin()->getParent()->end()) { 618cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines continue; 619cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 620f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 621f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (((*island).offset() + (*island).size()) > exit->getOffset()) { 622cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (invalid_frags.empty() || 623cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines (invalid_frags.back()->getParent() != (*island).getParent())) { 624cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines invalid_frags.push_back(exit); 625cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines pFinished = false; 626cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 627cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines continue; 628f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 629f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 630f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 631f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // reset the offset of invalid fragments 632cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines for (auto it = invalid_frags.begin(), ie = invalid_frags.end(); it != ie; 633cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines ++it) { 634cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines Fragment* invalid = *it; 635cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines while (invalid != NULL) { 636cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines invalid->setOffset(invalid->getPrevNode()->getOffset() + 637cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines invalid->getPrevNode()->size()); 638cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines invalid = invalid->getNextNode(); 639cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 640f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 641f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 642cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines // reset the size of section that has stubs inserted. 643f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (isRelaxed) { 644cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines SectionData* prev = NULL; 645cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(), 646cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines island_end = getBRIslandFactory()->end(); 647cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines island != island_end; 648cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines ++island) { 649cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines SectionData* sd = (*island).begin()->getParent(); 650cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if ((*island).numOfStubs() != 0) { 651cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines if (sd != prev) { 652cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines sd->getSection().setSize(sd->back().getOffset() + sd->back().size()); 653cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 654cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 655cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines prev = sd; 656cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines } 657f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 658f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return isRelaxed; 6596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 6606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// finalizeSymbol - finalize the symbol value 66237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool HexagonLDBackend::finalizeTargetSymbols() { 663f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (config().codeGenType() == LinkerConfig::Object) 664f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 665f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_psdabase) 666f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_psdabase->setValue(m_psdata->addr()); 667f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 66837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFSegmentFactory::const_iterator edata = elfSegmentTable().find( 66937b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::ELF::PT_LOAD, llvm::ELF::PF_W, llvm::ELF::PF_X); 67087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (elfSegmentTable().end() != edata) { 67137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pEData != NULL && ResolveInfo::ThreadLocal != f_pEData->type()) { 67287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines f_pEData->setValue((*edata)->vaddr() + (*edata)->filesz()); 673f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 67437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_p_EData != NULL && ResolveInfo::ThreadLocal != f_p_EData->type()) { 67587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines f_p_EData->setValue((*edata)->vaddr() + (*edata)->filesz()); 676f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 67737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pBSSStart != NULL && 678f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::ThreadLocal != f_pBSSStart->type()) { 67987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines f_pBSSStart->setValue((*edata)->vaddr() + (*edata)->filesz()); 680f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 68137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_pEnd != NULL && ResolveInfo::ThreadLocal != f_pEnd->type()) { 68237b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_pEnd->setValue((((*edata)->vaddr() + (*edata)->memsz()) + 7) & ~7); 683f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 68437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (f_p_End != NULL && ResolveInfo::ThreadLocal != f_p_End->type()) { 68537b74a387bb3993387029859c2d9d051c41c724eStephen Hines f_p_End->setValue((((*edata)->vaddr() + (*edata)->memsz()) + 7) & ~7); 686f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 687f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 688f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 689f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 690f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 691f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// merge Input Sections 69287f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool HexagonLDBackend::mergeSection(Module& pModule, 69387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const Input& pInputFile, 69437b74a387bb3993387029859c2d9d051c41c724eStephen Hines LDSection& pInputSection) { 695f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ((pInputSection.flag() & llvm::ELF::SHF_HEX_GPREL) || 696f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (pInputSection.kind() == LDFileFormat::LinkOnce) || 697f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (pInputSection.kind() == LDFileFormat::Target)) { 69837b74a387bb3993387029859c2d9d051c41c724eStephen Hines SectionData* sd = NULL; 699f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!m_psdata->hasSectionData()) { 700f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines sd = IRBuilder::CreateSectionData(*m_psdata); 701f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_psdata->setSectionData(sd); 702f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 703f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines sd = m_psdata->getSectionData(); 704f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines MoveSectionDataAndSort(*pInputSection.getSectionData(), *sd); 70537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 706533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines ObjectBuilder builder(pModule); 70787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines builder.MergeSection(pInputFile, pInputSection); 708f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 709f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 710f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 711f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 712f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool HexagonLDBackend::SetSDataSection() { 71337b74a387bb3993387029859c2d9d051c41c724eStephen Hines SectionData* pTo = (m_psdata->getSectionData()); 714f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 715f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pTo) { 716f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines MoveCommonData(*m_pscommon_1->getSectionData(), *pTo); 717f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines MoveCommonData(*m_pscommon_2->getSectionData(), *pTo); 718f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines MoveCommonData(*m_pscommon_4->getSectionData(), *pTo); 719f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines MoveCommonData(*m_pscommon_8->getSectionData(), *pTo); 720f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 721f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData::FragmentListType& to_list = pTo->getFragmentList(); 722f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData::FragmentListType::iterator fragTo, fragToEnd = to_list.end(); 723f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint32_t offset = 0; 724f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (fragTo = to_list.begin(); fragTo != fragToEnd; ++fragTo) { 725f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines fragTo->setOffset(offset); 726f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines offset += fragTo->size(); 727f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 728f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 729f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set up pTo's header 730f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pTo->getSection().setSize(offset); 731f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 732f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData::FragmentListType& newlist = pTo->getFragmentList(); 733f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 734f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (fragTo = newlist.begin(), fragToEnd = newlist.end(); 73537b74a387bb3993387029859c2d9d051c41c724eStephen Hines fragTo != fragToEnd; 73637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++fragTo) { 737f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines fragTo->setParent(pTo); 738f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 739f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 740f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 741f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 742f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 743f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 744f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// allocateCommonSymbols - allocate common symbols in the corresponding 745f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// sections. This is called at pre-layout stage. 74637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool HexagonLDBackend::allocateCommonSymbols(Module& pModule) { 747f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SymbolCategory& symbol_list = pModule.getSymbolTable(); 748f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 749f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (symbol_list.emptyCommons() && symbol_list.emptyLocals()) { 750f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SetSDataSection(); 751f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 752f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 753f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 754cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines int8_t maxGPSize = config().targets().getGPSize(); 755f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 756f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SymbolCategory::iterator com_sym, com_end; 757f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 758f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // get corresponding BSS LDSection 759f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 760f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSection& bss_sect = file_format->getBSS(); 761f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSection& tbss_sect = file_format->getTBSS(); 762f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 763f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // get or create corresponding BSS SectionData 764f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData* bss_sect_data = NULL; 765f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (bss_sect.hasSectionData()) 766f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bss_sect_data = bss_sect.getSectionData(); 767f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines else 768f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bss_sect_data = IRBuilder::CreateSectionData(bss_sect); 769f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 770f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData* tbss_sect_data = NULL; 771f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (tbss_sect.hasSectionData()) 772f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines tbss_sect_data = tbss_sect.getSectionData(); 773f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines else 774f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect); 775f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 776f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // remember original BSS size 77737b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint64_t bss_offset = bss_sect.size(); 778f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t tbss_offset = tbss_sect.size(); 779f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 780f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // allocate all local common symbols 781f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines com_end = symbol_list.localEnd(); 782f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 783f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) { 784f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (ResolveInfo::Common == (*com_sym)->desc()) { 785f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // We have to reset the description of the symbol here. When doing 786f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // incremental linking, the output relocatable object may have common 787f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // symbols. Therefore, we can not treat common symbols as normal symbols 788f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // when emitting the regular name pools. We must change the symbols' 789f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // description here. 790f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 791f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 792f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 79337b74a387bb3993387029859c2d9d051c41c724eStephen Hines switch ((*com_sym)->size()) { 79437b74a387bb3993387029859c2d9d051c41c724eStephen Hines case 1: 79537b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (maxGPSize <= 0) 79637b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 79737b74a387bb3993387029859c2d9d051c41c724eStephen Hines ObjectBuilder::AppendFragment( 79837b74a387bb3993387029859c2d9d051c41c724eStephen Hines *frag, *(m_pscommon_1->getSectionData()), (*com_sym)->value()); 79937b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 80037b74a387bb3993387029859c2d9d051c41c724eStephen Hines continue; 80137b74a387bb3993387029859c2d9d051c41c724eStephen Hines case 2: 80237b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (maxGPSize <= 1) 80337b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 80437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ObjectBuilder::AppendFragment( 80537b74a387bb3993387029859c2d9d051c41c724eStephen Hines *frag, *(m_pscommon_2->getSectionData()), (*com_sym)->value()); 80637b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 80737b74a387bb3993387029859c2d9d051c41c724eStephen Hines continue; 80837b74a387bb3993387029859c2d9d051c41c724eStephen Hines case 4: 80937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (maxGPSize <= 3) 81037b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 81137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ObjectBuilder::AppendFragment( 81237b74a387bb3993387029859c2d9d051c41c724eStephen Hines *frag, *(m_pscommon_4->getSectionData()), (*com_sym)->value()); 81337b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 81437b74a387bb3993387029859c2d9d051c41c724eStephen Hines continue; 81537b74a387bb3993387029859c2d9d051c41c724eStephen Hines case 8: 81637b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (maxGPSize <= 7) 81737b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 81837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ObjectBuilder::AppendFragment( 81937b74a387bb3993387029859c2d9d051c41c724eStephen Hines *frag, *(m_pscommon_8->getSectionData()), (*com_sym)->value()); 82037b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 82137b74a387bb3993387029859c2d9d051c41c724eStephen Hines continue; 82237b74a387bb3993387029859c2d9d051c41c724eStephen Hines default: 823f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 824f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 825f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 826f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 827f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // allocate TLS common symbol in tbss section 82837b74a387bb3993387029859c2d9d051c41c724eStephen Hines tbss_offset += ObjectBuilder::AppendFragment( 82937b74a387bb3993387029859c2d9d051c41c724eStephen Hines *frag, *tbss_sect_data, (*com_sym)->value()); 83087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 83137b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 83237b74a387bb3993387029859c2d9d051c41c724eStephen Hines // FIXME: how to identify small and large common symbols? 83337b74a387bb3993387029859c2d9d051c41c724eStephen Hines bss_offset += ObjectBuilder::AppendFragment( 83437b74a387bb3993387029859c2d9d051c41c724eStephen Hines *frag, *bss_sect_data, (*com_sym)->value()); 83587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 836f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 837f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 838f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 839f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 840f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // allocate all global common symbols 841f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines com_end = symbol_list.commonEnd(); 842f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 843f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // We have to reset the description of the symbol here. When doing 844f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // incremental linking, the output relocatable object may have common 845f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // symbols. Therefore, we can not treat common symbols as normal symbols 846f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // when emitting the regular name pools. We must change the symbols' 847f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // description here. 848f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 849f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 850f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 85137b74a387bb3993387029859c2d9d051c41c724eStephen Hines switch ((*com_sym)->size()) { 85237b74a387bb3993387029859c2d9d051c41c724eStephen Hines case 1: 85337b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (maxGPSize <= 0) 85437b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 85537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ObjectBuilder::AppendFragment( 85637b74a387bb3993387029859c2d9d051c41c724eStephen Hines *frag, *(m_pscommon_1->getSectionData()), (*com_sym)->value()); 85737b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 85837b74a387bb3993387029859c2d9d051c41c724eStephen Hines continue; 85937b74a387bb3993387029859c2d9d051c41c724eStephen Hines case 2: 86037b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (maxGPSize <= 1) 86137b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 86237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ObjectBuilder::AppendFragment( 86337b74a387bb3993387029859c2d9d051c41c724eStephen Hines *frag, *(m_pscommon_2->getSectionData()), (*com_sym)->value()); 86437b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 86537b74a387bb3993387029859c2d9d051c41c724eStephen Hines continue; 86637b74a387bb3993387029859c2d9d051c41c724eStephen Hines case 4: 86737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (maxGPSize <= 3) 86837b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 86937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ObjectBuilder::AppendFragment( 87037b74a387bb3993387029859c2d9d051c41c724eStephen Hines *frag, *(m_pscommon_4->getSectionData()), (*com_sym)->value()); 87137b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 87237b74a387bb3993387029859c2d9d051c41c724eStephen Hines continue; 87337b74a387bb3993387029859c2d9d051c41c724eStephen Hines case 8: 87437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (maxGPSize <= 7) 87537b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 87637b74a387bb3993387029859c2d9d051c41c724eStephen Hines ObjectBuilder::AppendFragment( 87737b74a387bb3993387029859c2d9d051c41c724eStephen Hines *frag, *(m_pscommon_8->getSectionData()), (*com_sym)->value()); 87837b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 87937b74a387bb3993387029859c2d9d051c41c724eStephen Hines continue; 88037b74a387bb3993387029859c2d9d051c41c724eStephen Hines default: 881f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 882f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 883f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 884f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 885f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // allocate TLS common symbol in tbss section 88637b74a387bb3993387029859c2d9d051c41c724eStephen Hines tbss_offset += ObjectBuilder::AppendFragment( 88737b74a387bb3993387029859c2d9d051c41c724eStephen Hines *frag, *tbss_sect_data, (*com_sym)->value()); 88887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 88937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 89037b74a387bb3993387029859c2d9d051c41c724eStephen Hines // FIXME: how to identify small and large common symbols? 89137b74a387bb3993387029859c2d9d051c41c724eStephen Hines bss_offset += ObjectBuilder::AppendFragment( 89237b74a387bb3993387029859c2d9d051c41c724eStephen Hines *frag, *bss_sect_data, (*com_sym)->value()); 89387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 894f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 895f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 896f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 897f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bss_sect.setSize(bss_offset); 898f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines tbss_sect.setSize(tbss_offset); 899f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines symbol_list.changeCommonsToGlobal(); 900f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SetSDataSection(); 901f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 902f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 903f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 90437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool HexagonLDBackend::MoveCommonData(SectionData& pFrom, SectionData& pTo) { 905f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData::FragmentListType& to_list = pTo.getFragmentList(); 906f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData::FragmentListType::iterator frag, fragEnd = to_list.end(); 907f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 908f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint32_t pFromFlag = pFrom.getSection().align(); 909f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool found = false; 910f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 911f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData::FragmentListType::iterator fragInsert; 912f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 913f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (frag = to_list.begin(); frag != fragEnd; ++frag) { 914f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (frag->getKind() == mcld::Fragment::Alignment) { 915f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines fragInsert = frag; 916f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 917f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 918f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ((frag->getKind() != mcld::Fragment::Region) && 919f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (frag->getKind() != mcld::Fragment::Fillment)) { 920f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 921f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 922f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint32_t flag = frag->getParent()->getSection().align(); 923f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pFromFlag < flag) { 924f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines found = true; 925f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 926f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 927f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 928f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines AlignFragment* align = NULL; 929f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pFrom.getSection().align() > 1) { 930f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // if the align constraint is larger than 1, append an alignment 93137b74a387bb3993387029859c2d9d051c41c724eStephen Hines unsigned int alignment = pFrom.getSection().align(); 93237b74a387bb3993387029859c2d9d051c41c724eStephen Hines align = new AlignFragment(/*alignment*/alignment, 93337b74a387bb3993387029859c2d9d051c41c724eStephen Hines /*the filled value*/0x0, 93437b74a387bb3993387029859c2d9d051c41c724eStephen Hines /*the size of filled value*/1u, 93537b74a387bb3993387029859c2d9d051c41c724eStephen Hines /*max bytes to emit*/alignment - 1); 936f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pFrom.getFragmentList().push_front(align); 937f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 938f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (found) 939f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines to_list.splice(fragInsert, pFrom.getFragmentList()); 940f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines else 941f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines to_list.splice(frag, pFrom.getFragmentList()); 942f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 943f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 944f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 945f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 94637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool HexagonLDBackend::readSection(Input& pInput, SectionData& pSD) { 947f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Fragment* frag = NULL; 948f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint32_t offset = pInput.fileOffset() + pSD.getSection().offset(); 949f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint32_t size = pSD.getSection().size(); 950f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 951f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pSD.getSection().type() == llvm::ELF::SHT_NOBITS) { 952f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines frag = new FillFragment(0x0, 1, size); 95337b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 95487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::StringRef region = pInput.memArea()->request(offset, size); 95587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (region.size() == 0) { 956f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // If the input section's size is zero, we got a NULL region. 957f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // use a virtual fill fragment 958f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines frag = new FillFragment(0x0, 0, 0); 95937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 96087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines frag = new RegionFragment(region); 961f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 962f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 963f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 964f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ObjectBuilder::AppendFragment(*frag, pSD); 965f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 966f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 967f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 968f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// MoveSectionData - move the fragments of pTO section data to pTo 96937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool HexagonLDBackend::MoveSectionDataAndSort(SectionData& pFrom, 97037b74a387bb3993387029859c2d9d051c41c724eStephen Hines SectionData& pTo) { 971f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(&pFrom != &pTo && "Cannot move section data to itself!"); 972f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData::FragmentListType& to_list = pTo.getFragmentList(); 973f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData::FragmentListType::iterator frag, fragEnd = to_list.end(); 974f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 975f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint32_t pFromFlag = pFrom.getSection().align(); 976f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool found = false; 977f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 978f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData::FragmentListType::iterator fragInsert; 979f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 980f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (frag = to_list.begin(); frag != fragEnd; ++frag) { 981f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (frag->getKind() == mcld::Fragment::Alignment) { 982f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines fragInsert = frag; 983f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 984f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 985f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ((frag->getKind() != mcld::Fragment::Region) && 986f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (frag->getKind() != mcld::Fragment::Fillment)) { 987f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 988f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 989f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint32_t flag = frag->getParent()->getSection().align(); 990f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pFromFlag < flag) { 991f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines found = true; 992f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 993f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 994f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 995f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines AlignFragment* align = NULL; 996f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pFrom.getSection().align() > 1) { 997f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // if the align constraint is larger than 1, append an alignment 99837b74a387bb3993387029859c2d9d051c41c724eStephen Hines unsigned int alignment = pFrom.getSection().align(); 99937b74a387bb3993387029859c2d9d051c41c724eStephen Hines align = new AlignFragment(/*alignment*/alignment, 100037b74a387bb3993387029859c2d9d051c41c724eStephen Hines /*the filled value*/0x0, 100137b74a387bb3993387029859c2d9d051c41c724eStephen Hines /*the size of filled value*/1u, 100237b74a387bb3993387029859c2d9d051c41c724eStephen Hines /*max bytes to emit*/alignment - 1); 1003f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pFrom.getFragmentList().push_front(align); 1004f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 1005f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (found) 1006f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines to_list.splice(fragInsert, pFrom.getFragmentList()); 1007f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines else 1008f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines to_list.splice(frag, pFrom.getFragmentList()); 1009f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1010f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint32_t offset = 0; 1011f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (frag = to_list.begin(); frag != fragEnd; ++frag) { 1012f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines frag->setOffset(offset); 1013f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines offset += frag->size(); 1014f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 1015f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1016f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set up pTo's header 1017f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pTo.getSection().setSize(offset); 1018f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1019f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pFrom.getSection().align() > pTo.getSection().align()) 1020f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pTo.getSection().setAlign(pFrom.getSection().align()); 1021f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1022f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pFrom.getSection().flag() > pTo.getSection().flag()) 1023f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pTo.getSection().setFlag(pFrom.getSection().flag()); 10246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 10256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 10266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// doCreateProgramHdrs - backend can implement this function to create the 10286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// target-dependent segments 102937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid HexagonLDBackend::doCreateProgramHdrs(Module& pModule) { 10306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // TODO 10316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 10326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 1034f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// createHexagonLDBackend - the help funtion to create corresponding 10356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// HexagonLDBackend 103637b74a387bb3993387029859c2d9d051c41c724eStephen HinesTargetLDBackend* createHexagonLDBackend(const LinkerConfig& pConfig) { 10376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pConfig.targets().triple().isOSDarwin()) { 10386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(0 && "MachO linker is not supported yet"); 10396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines /** 10406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return new HexagonMachOLDBackend(createHexagonMachOArchiveReader, 10416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines createHexagonMachOObjectReader, 10426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines createHexagonMachOObjectWriter); 10436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines **/ 10446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pConfig.targets().triple().isOSWindows()) { 10466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(0 && "COFF linker is not supported yet"); 10476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines /** 10486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return new HexagonCOFFLDBackend(createHexagonCOFFArchiveReader, 10496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines createHexagonCOFFObjectReader, 10506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines createHexagonCOFFObjectWriter); 10516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines **/ 10526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1053f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return new HexagonLDBackend(pConfig, new HexagonGNUInfo(pConfig.targets())); 10546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 10556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 105637b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 10576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 10596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// Force static initialization. 10606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 10616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesextern "C" void MCLDInitializeHexagonLDBackend() { 10626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Register the linker backend 106337b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::TargetRegistry::RegisterTargetLDBackend(mcld::TheHexagonTarget, 106437b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::createHexagonLDBackend); 10656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1066