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 166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/ADT/Triple.h> 176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/Support/Casting.h> 186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/LinkerConfig.h> 206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/IRBuilder.h> 21f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/Fragment/AlignFragment.h> 226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Fragment/FillFragment.h> 236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Fragment/RegionFragment.h> 24f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/Support/MemoryArea.h> 256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Support/MsgHandling.h> 266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Support/TargetRegistry.h> 276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Object/ObjectBuilder.h> 28f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/Fragment/Stub.h> 29f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/LD/BranchIslandFactory.h> 30f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/LD/StubFactory.h> 31f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/LD/LDContext.h> 3287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFFileFormat.h> 3387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFSegmentFactory.h> 3487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LD/ELFSegment.h> 356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <cstring> 376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesusing namespace mcld; 396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// HexagonLDBackend 426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 43f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesHexagonLDBackend::HexagonLDBackend(const LinkerConfig& pConfig, 446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonGNUInfo* pInfo) 456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines : GNULDBackend(pConfig, pInfo), 466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pRelocator(NULL), 476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOT(NULL), 48f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGOTPLT(NULL), 496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pPLT(NULL), 50f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pRelaDyn(NULL), 51f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pRelaPLT(NULL), 526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pDynamic(NULL), 53f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGOTSymbol(NULL), 54f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_CopyRel(llvm::ELF::R_HEX_COPY) { 556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesHexagonLDBackend::~HexagonLDBackend() 586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 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 676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool HexagonLDBackend::initRelocator() 686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == m_pRelocator) { 70f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pRelocator = new HexagonRelocator(*this, config()); 716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 75a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hinesconst Relocator* HexagonLDBackend::getRelocator() const 76a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines{ 77a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines assert(NULL != m_pRelocator); 78a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines return m_pRelocator; 79a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines} 80a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines 816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesRelocator* HexagonLDBackend::getRelocator() 826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pRelocator); 846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return m_pRelocator; 856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid HexagonLDBackend::doPreLayout(IRBuilder& pBuilder) 886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .dynamic data 906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!config().isCodeStatic() && NULL == m_pDynamic) 916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pDynamic = new HexagonELFDynamic(*this, config()); 92f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 93f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set .got.plt and .got sizes 94f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // when building shared object, the .got section is must 95f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ((LinkerConfig::Object != config().codeGenType()) && 96f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (!config().isCodeStatic())) { 97f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines setGOTSectionSize(pBuilder); 98f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 99f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set .plt size 100f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_pPLT->hasPLT1()) 101f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pPLT->finalizeSectionSize(); 102f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 103f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set .rela.dyn size 104f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!m_pRelaDyn->empty()) { 105f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(!config().isCodeStatic() && 106f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "static linkage should not result in a dynamic relocation section"); 107f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines setRelaDynSize(); 108f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 109f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set .rela.plt size 110f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!m_pRelaPLT->empty()) { 111f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(!config().isCodeStatic() && 112f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "static linkage should not result in a dynamic relocation section"); 113f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines setRelaPLTSize(); 114f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 115f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 116f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // Shared libraries are compiled with -G0 so there is no need to set SData. 117f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (LinkerConfig::Object == config().codeGenType()) 118f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SetSDataSection(); 1196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid HexagonLDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder) 1226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 1236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// dynamic - the dynamic section of the target machine. 1266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// Use co-variant return type to return its own dynamic section. 1276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesHexagonELFDynamic& HexagonLDBackend::dynamic() 1286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pDynamic); 1306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pDynamic; 1316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// dynamic - the dynamic section of the target machine. 1346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// Use co-variant return type to return its own dynamic section. 1356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst HexagonELFDynamic& HexagonLDBackend::dynamic() const 1366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 1376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pDynamic); 1386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pDynamic; 1396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t HexagonLDBackend::emitSectionData(const LDSection& pSection, 14287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MemoryRegion& pRegion) const 1436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 144f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!pRegion.size()) 145f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return 0; 146f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 147f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const ELFFileFormat* FileFormat = getOutputFormat(); 148f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines unsigned int EntrySize = 0; 149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t RegionSize = 0; 150f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ((LinkerConfig::Object != config().codeGenType()) && 152f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (!config().isCodeStatic())) { 15387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (FileFormat->hasPLT() && (&pSection == &(FileFormat->getPLT()))) { 154f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 15587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines unsigned char* buffer = pRegion.begin(); 156f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 157f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pPLT->applyPLT0(); 158f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pPLT->applyPLT1(); 159f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines HexagonPLT::iterator it = m_pPLT->begin(); 160f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines unsigned int plt0_size = llvm::cast<PLTEntryBase>((*it)).size(); 161f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 162f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines memcpy(buffer, llvm::cast<PLTEntryBase>((*it)).getValue(), plt0_size); 163f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines RegionSize += plt0_size; 164f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++it; 165f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 166f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines PLTEntryBase* plt1 = 0; 167f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines HexagonPLT::iterator ie = m_pPLT->end(); 168f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines while (it != ie) { 169f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines plt1 = &(llvm::cast<PLTEntryBase>(*it)); 170f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines EntrySize = plt1->size(); 171f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines memcpy(buffer + RegionSize, plt1->getValue(), EntrySize); 172f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines RegionSize += EntrySize; 173f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++it; 174f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 175f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return RegionSize; 176f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 17787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else if (FileFormat->hasGOT() && (&pSection == &(FileFormat->getGOT()))) { 178f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines RegionSize += emitGOTSectionData(pRegion); 179f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return RegionSize; 180f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 18187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else if (FileFormat->hasGOTPLT() && 18287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (&pSection == &(FileFormat->getGOTPLT()))) { 183f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines RegionSize += emitGOTPLTSectionData(pRegion, FileFormat); 184f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return RegionSize; 185f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 186f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 187f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 188f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const SectionData* sect_data = pSection.getSectionData(); 189f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData::const_iterator frag_iter, frag_end = sect_data->end(); 19087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint8_t* out_offset = pRegion.begin(); 191f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) { 192f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines size_t size = frag_iter->size(); 193f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines switch(frag_iter->getKind()) { 194f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case Fragment::Fillment: { 195f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const FillFragment& fill_frag = 196f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::cast<FillFragment>(*frag_iter); 197f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (0 == fill_frag.getValueSize()) { 198f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // virtual fillment, ignore it. 199f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 200f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 201f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines memset(out_offset, fill_frag.getValue(), fill_frag.size()); 202f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 203f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 204f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case Fragment::Region: { 205f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const RegionFragment& region_frag = 206f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::cast<RegionFragment>(*frag_iter); 20787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const char* start = region_frag.getRegion().begin(); 208f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines memcpy(out_offset, start, size); 209f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 210f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 211f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case Fragment::Alignment: { 212f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const AlignFragment& align_frag = llvm::cast<AlignFragment>(*frag_iter); 213f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t count = size / align_frag.getValueSize(); 214f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines switch (align_frag.getValueSize()) { 215f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case 1u: 216f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::memset(out_offset, align_frag.getValue(), count); 217f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 218f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines default: 219f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::report_fatal_error( 220f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "unsupported value size for align fragment emission yet.\n"); 221f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 222f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } // end switch 223f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 224f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 225f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case Fragment::Null: { 226f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(0x0 == size); 227f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 228f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 229f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines default: 230f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::report_fatal_error("unsupported fragment type.\n"); 231f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 232f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } // end switch 233f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines out_offset += size; 234f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } // end for 235f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 236f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return pRegion.size(); 2376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesHexagonGOT& HexagonLDBackend::getGOT() 2406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pGOT); 2426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pGOT; 2436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst HexagonGOT& HexagonLDBackend::getGOT() const 2466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pGOT); 2486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pGOT; 2496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesHexagonPLT& HexagonLDBackend::getPLT() 2526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pPLT && "PLT section not exist"); 2546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pPLT; 2556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst HexagonPLT& HexagonLDBackend::getPLT() const 2586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != m_pPLT && "PLT section not exist"); 2606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return *m_pPLT; 2616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 263f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesOutputRelocSection& HexagonLDBackend::getRelaDyn() 264f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 265f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(NULL != m_pRelaDyn && ".rela.dyn section not exist"); 266f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return *m_pRelaDyn; 267f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 268f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 269f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesconst OutputRelocSection& HexagonLDBackend::getRelaDyn() const 270f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 271f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(NULL != m_pRelaDyn && ".rela.dyn section not exist"); 272f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return *m_pRelaDyn; 273f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 274f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 275f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesOutputRelocSection& HexagonLDBackend::getRelaPLT() 276f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 277f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(NULL != m_pRelaPLT && ".rela.plt section not exist"); 278f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return *m_pRelaPLT; 279f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 280f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 281f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesconst OutputRelocSection& HexagonLDBackend::getRelaPLT() const 282f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 283f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(NULL != m_pRelaPLT && ".rela.plt section not exist"); 284f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return *m_pRelaPLT; 285f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 286f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 287f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesHexagonGOTPLT& HexagonLDBackend::getGOTPLT() 288f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 289f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(NULL != m_pGOTPLT); 290f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return *m_pGOTPLT; 291f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 292f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 293f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesconst HexagonGOTPLT& HexagonLDBackend::getGOTPLT() const 2946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 295f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(NULL != m_pGOTPLT); 296f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return *m_pGOTPLT; 2976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 299f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid HexagonLDBackend::setRelaDynSize() 3006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 301f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 302f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines file_format->getRelaDyn().setSize 303f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (m_pRelaDyn->numOfRelocs() * getRelaEntrySize()); 3046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 306f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid HexagonLDBackend::setRelaPLTSize() 3076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 308f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 309f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines file_format->getRelaPlt().setSize 310f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (m_pRelaPLT->numOfRelocs() * getRelaEntrySize()); 3116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 313f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid HexagonLDBackend::setGOTSectionSize(IRBuilder& pBuilder) 3146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 315f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set .got.plt size 316f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (LinkerConfig::DynObj == config().codeGenType() || 317f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGOTPLT->hasGOT1() || 318f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines NULL != m_pGOTSymbol) { 319f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGOTPLT->finalizeSectionSize(); 320f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines defineGOTSymbol(pBuilder, *(m_pGOTPLT->begin())); 321f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 322f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 323f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set .got size 324f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!m_pGOT->empty()) 325f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGOT->finalizeSectionSize(); 326f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 327f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 32887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesuint64_t 32987f34658dec9097d987d254a990ea7f311bfc95fStephen HinesHexagonLDBackend::emitGOTSectionData(MemoryRegion& pRegion) const 330f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 331f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!"); 332f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 33387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin()); 334f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 335f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines HexagonGOTEntry* got = 0; 336f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines unsigned int EntrySize = HexagonGOTEntry::EntrySize; 337f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t RegionSize = 0; 338f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 339f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (HexagonGOT::iterator it = m_pGOT->begin(), 340f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ie = m_pGOT->end(); it != ie; ++it, ++buffer) { 341f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines got = &(llvm::cast<HexagonGOTEntry>((*it))); 342f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *buffer = static_cast<uint32_t>(got->getValue()); 343f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines RegionSize += EntrySize; 344f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 345f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 346f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return RegionSize; 347f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 348f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 349f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid HexagonLDBackend::defineGOTSymbol(IRBuilder& pBuilder, 350f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Fragment& pFrag) 351f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 352f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // define symbol _GLOBAL_OFFSET_TABLE_ 353f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_pGOTSymbol != NULL) { 354f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( 355f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "_GLOBAL_OFFSET_TABLE_", 356f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Object, 357f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Define, 358f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Local, 359f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 0x0, // size 360f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 0x0, // value 361f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines FragmentRef::Create(pFrag, 0x0), 362f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Hidden); 363f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 364f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines else { 365f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( 366f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "_GLOBAL_OFFSET_TABLE_", 367f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Object, 368f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Define, 369f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Local, 370f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 0x0, // size 371f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 0x0, // value 372f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines FragmentRef::Create(pFrag, 0x0), 373f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Hidden); 374f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 375f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 376f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 377f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesuint64_t HexagonLDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion, 37887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const ELFFileFormat* FileFormat) const 379f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 380f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!"); 381f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr()); 382f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGOTPLT->applyAllGOTPLT(*m_pPLT); 383f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 38487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin()); 385f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 386f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines HexagonGOTEntry* got = 0; 387f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines unsigned int EntrySize = HexagonGOTEntry::EntrySize; 388f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t RegionSize = 0; 389f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 390f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (HexagonGOTPLT::iterator it = m_pGOTPLT->begin(), 391f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) { 392f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines got = &(llvm::cast<HexagonGOTEntry>((*it))); 393f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *buffer = static_cast<uint32_t>(got->getValue()); 394f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines RegionSize += EntrySize; 395f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 396f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 397f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return RegionSize; 3986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesunsigned int 4016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesHexagonLDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const 4026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 4036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const ELFFileFormat* file_format = getOutputFormat(); 4046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 405f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (LinkerConfig::Object != config().codeGenType()) { 40687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasGOT() && (&pSectHdr == &file_format->getGOT())) { 407f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (config().options().hasNow()) 408f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return SHO_RELRO; 409f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return SHO_RELRO_LAST; 410f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 411f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 41287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasGOTPLT() && (&pSectHdr == &file_format->getGOTPLT())) { 413f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (config().options().hasNow()) 414f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return SHO_RELRO; 415f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return SHO_NON_RELRO_FIRST; 416f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 417f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 41887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (file_format->hasPLT() && (&pSectHdr == &file_format->getPLT())) 419f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return SHO_PLT; 4206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 4216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 422f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (&pSectHdr == m_pstart) 423f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return SHO_INIT; 424f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 425f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (&pSectHdr == m_psdata) 426f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return SHO_SMALL_DATA; 4276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return SHO_UNDEFINED; 4296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 431f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid HexagonLDBackend::initTargetSections(Module& pModule, 4326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ObjectBuilder& pBuilder) 4336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 434f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 435f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ((LinkerConfig::Object != config().codeGenType()) && 436f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (!config().isCodeStatic())) { 4376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 4386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .got 4396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& got = file_format->getGOT(); 4406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pGOT = new HexagonGOT(got); 4416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 442f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // initialize .got.plt 443f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSection& gotplt = file_format->getGOTPLT(); 444f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGOTPLT = new HexagonGOTPLT(gotplt); 445f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 4466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // initialize .plt 4476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& plt = file_format->getPLT(); 4486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pPLT = new HexagonPLT(plt, 449f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *m_pGOTPLT, 4506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines config()); 4516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 452f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // initialize .rela.plt 453f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSection& relaplt = file_format->getRelaPlt(); 454f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines relaplt.setLink(&plt); 455f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pRelaPLT = new OutputRelocSection(pModule, relaplt); 4566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 457f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // initialize .rela.dyn 458f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSection& reladyn = file_format->getRelaDyn(); 459f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pRelaDyn = new OutputRelocSection(pModule, reladyn); 4606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 462f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_psdata = pBuilder.CreateSection(".sdata", 463f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDFileFormat::Target, 464f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::ELF::SHT_PROGBITS, 465f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 466f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 4*1024); 467f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pscommon_1 = pBuilder.CreateSection(".scommon.1", 468f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDFileFormat::Target, 469f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::ELF::SHT_PROGBITS, 470f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 471f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1); 472f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines IRBuilder::CreateSectionData(*m_pscommon_1); 473f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 474f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pscommon_2 = pBuilder.CreateSection(".scommon.2", 475f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDFileFormat::Target, 476f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::ELF::SHT_PROGBITS, 477f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 478f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 2); 479f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines IRBuilder::CreateSectionData(*m_pscommon_2); 480f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 481f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pscommon_4 = pBuilder.CreateSection(".scommon.4", 482f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDFileFormat::Target, 483f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::ELF::SHT_PROGBITS, 484f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 485f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 4); 486f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines IRBuilder::CreateSectionData(*m_pscommon_4); 487f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 488f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pscommon_8 = pBuilder.CreateSection(".scommon.8", 489f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDFileFormat::Target, 490f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::ELF::SHT_PROGBITS, 491f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 492f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 8); 493f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines IRBuilder::CreateSectionData(*m_pscommon_8); 494f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 495f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pstart = pBuilder.CreateSection(".start", 496f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDFileFormat::Target, 497f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::ELF::SHT_PROGBITS, 498f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE, 499f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 8); 500f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines IRBuilder::CreateSectionData(*m_pstart); 5016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid HexagonLDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule) 5046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 505f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (config().codeGenType() == LinkerConfig::Object) 506f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return; 507f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 508f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the 509f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // same name in input 510f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 511f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "_GLOBAL_OFFSET_TABLE_", 512f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Object, 513f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Define, 514f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Local, 515f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 0x0, // size 516f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 0x0, // value 517f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines FragmentRef::Null(), 518f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Hidden); 519f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_psdabase = 520f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 521f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "_SDA_BASE_", 522f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Object, 523f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Define, 524f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Absolute, 525f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 0x0, // size 526f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 0x0, // value 527f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines FragmentRef::Null(), 528f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Hidden); 529f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 530f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "__sbss_start", 531f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Object, 532f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Define, 533f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Absolute, 534f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 0x0, // size 535f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 0x0, // value 536f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines FragmentRef::Null(), 537f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Hidden); 538f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>( 539f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines "__sbss_end", 540f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Object, 541f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Define, 542f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Absolute, 543f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 0x0, // size 544f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 0x0, // value 545f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines FragmentRef::Null(), 546f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Hidden); 547f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 548f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 549f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool HexagonLDBackend::initTargetStubs() 550f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 551f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (NULL != getStubFactory()) { 552f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines getStubFactory()->addPrototype 553f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (new HexagonAbsoluteStub(config().isCodeIndep())); 554f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 555f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 556f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return false; 557f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 558f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 559f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool HexagonLDBackend::initBRIslandFactory() 560f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 561f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (NULL == m_pBRIslandFactory) { 562a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines m_pBRIslandFactory = new BranchIslandFactory(maxFwdBranchOffset(), 563a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines maxBwdBranchOffset(), 564a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines 0); 565f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 566f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 567f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 568f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 569f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool HexagonLDBackend::initStubFactory() 570f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 571f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (NULL == m_pStubFactory) { 572f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_pStubFactory = new StubFactory(); 5736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 574f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 575f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 576f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 577f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool HexagonLDBackend::doRelax(Module& pModule, IRBuilder& pBuilder, 578f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool& pFinished) 579f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 580f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(NULL != getStubFactory() && NULL != getBRIslandFactory()); 581f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool isRelaxed = false; 582f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 583f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // check branch relocs and create the related stubs if needed 584f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Module::obj_iterator input, inEnd = pModule.obj_end(); 585f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (input = pModule.obj_begin(); input != inEnd; ++input) { 586f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); 587f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 588f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData()) 589f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 590f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end(); 591f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) { 592f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines switch (reloc->type()) { 593f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case llvm::ELF::R_HEX_B22_PCREL: 594f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case llvm::ELF::R_HEX_B15_PCREL: 595f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case llvm::ELF::R_HEX_B7_PCREL: 596f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case llvm::ELF::R_HEX_B13_PCREL: 597f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case llvm::ELF::R_HEX_B9_PCREL: { 598f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Relocation* relocation = llvm::cast<Relocation>(reloc); 599f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t sym_value = 0x0; 600f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSymbol* symbol = relocation->symInfo()->outSymbol(); 601f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (symbol->hasFragRef()) { 602f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t value = symbol->fragRef()->getOutputOffset(); 603f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t addr = 604f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines symbol->fragRef()->frag()->getParent()->getSection().addr(); 605f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines sym_value = addr + value; 606f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 607f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Stub* stub = getStubFactory()->create(*relocation, // relocation 608f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines sym_value, //symbol value 609f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pBuilder, 610f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *getBRIslandFactory()); 611f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (NULL != stub) { 612f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(NULL != stub->symInfo()); 613f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // increase the size of .symtab and .strtab 614f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSection& symtab = file_format->getSymTab(); 615f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSection& strtab = file_format->getStrTab(); 616f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym)); 617f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1); 618f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines isRelaxed = true; 619f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 620f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 621f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 622f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 623f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines default: 624f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 625f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 626f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 627f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 628f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 629f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 630f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // find the first fragment w/ invalid offset due to stub insertion 631f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Fragment* invalid = NULL; 632f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pFinished = true; 633f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(), 634f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines island_end = getBRIslandFactory()->end(); island != island_end; ++island) 635f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines { 636f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ((*island).end() == file_format->getText().getSectionData()->end()) 637f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 638f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 639f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Fragment* exit = (*island).end(); 640f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (((*island).offset() + (*island).size()) > exit->getOffset()) { 641f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines invalid = exit; 642f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pFinished = false; 643f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 644f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 645f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 646f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 647f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // reset the offset of invalid fragments 648f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines while (NULL != invalid) { 649f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines invalid->setOffset(invalid->getPrevNode()->getOffset() + 650f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines invalid->getPrevNode()->size()); 651f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines invalid = invalid->getNextNode(); 652f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 653f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 654f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // reset the size of .text 655f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (isRelaxed) { 656f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines file_format->getText().setSize( 657f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines file_format->getText().getSectionData()->back().getOffset() + 658f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines file_format->getText().getSectionData()->back().size()); 659f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 660f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return isRelaxed; 6616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 6626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// finalizeSymbol - finalize the symbol value 6646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool HexagonLDBackend::finalizeTargetSymbols() 6656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 666f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (config().codeGenType() == LinkerConfig::Object) 667f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 668f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (m_psdabase) 669f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_psdabase->setValue(m_psdata->addr()); 670f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 67187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegmentFactory::const_iterator edata = 67287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines elfSegmentTable().find(llvm::ELF::PT_LOAD, 67387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::ELF::PF_W, 67487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::ELF::PF_X); 67587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (elfSegmentTable().end() != edata) { 676f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (NULL != f_pEData && ResolveInfo::ThreadLocal != f_pEData->type()) { 67787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines f_pEData->setValue((*edata)->vaddr() + (*edata)->filesz()); 678f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 679f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (NULL != f_p_EData && ResolveInfo::ThreadLocal != f_p_EData->type()) { 68087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines f_p_EData->setValue((*edata)->vaddr() + (*edata)->filesz()); 681f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 682f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (NULL != f_pBSSStart && 683f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::ThreadLocal != f_pBSSStart->type()) { 68487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines f_pBSSStart->setValue((*edata)->vaddr() + (*edata)->filesz()); 685f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 686f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (NULL != f_pEnd && ResolveInfo::ThreadLocal != f_pEnd->type()) { 68787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines f_pEnd->setValue((((*edata)->vaddr() + 68887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*edata)->memsz()) + 7) & ~7); 689f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 690f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (NULL != f_p_End && ResolveInfo::ThreadLocal != f_p_End->type()) { 69187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines f_p_End->setValue((((*edata)->vaddr() + 69287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*edata)->memsz()) + 7) & ~7); 693f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 694f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 695f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 696f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 697f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 698f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// merge Input Sections 69987f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool HexagonLDBackend::mergeSection(Module& pModule, 70087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const Input& pInputFile, 70187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& pInputSection) 702f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 703f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ((pInputSection.flag() & llvm::ELF::SHF_HEX_GPREL) || 704f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (pInputSection.kind() == LDFileFormat::LinkOnce) || 705f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (pInputSection.kind() == LDFileFormat::Target)) { 706f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData *sd = NULL; 707f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (!m_psdata->hasSectionData()) { 708f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines sd = IRBuilder::CreateSectionData(*m_psdata); 709f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_psdata->setSectionData(sd); 710f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 711f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines sd = m_psdata->getSectionData(); 712f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines MoveSectionDataAndSort(*pInputSection.getSectionData(), *sd); 713f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 714f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines else { 715533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines ObjectBuilder builder(pModule); 71687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines builder.MergeSection(pInputFile, pInputSection); 717f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 718f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 719f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 720f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 721f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool HexagonLDBackend::SetSDataSection() { 722f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData *pTo = (m_psdata->getSectionData()); 723f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 724f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pTo) { 725f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines MoveCommonData(*m_pscommon_1->getSectionData(), *pTo); 726f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines MoveCommonData(*m_pscommon_2->getSectionData(), *pTo); 727f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines MoveCommonData(*m_pscommon_4->getSectionData(), *pTo); 728f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines MoveCommonData(*m_pscommon_8->getSectionData(), *pTo); 729f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 730f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData::FragmentListType& to_list = pTo->getFragmentList(); 731f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData::FragmentListType::iterator fragTo, fragToEnd = to_list.end(); 732f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint32_t offset = 0; 733f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (fragTo = to_list.begin(); fragTo != fragToEnd; ++fragTo) { 734f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines fragTo->setOffset(offset); 735f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines offset += fragTo->size(); 736f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 737f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 738f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set up pTo's header 739f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pTo->getSection().setSize(offset); 740f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 741f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData::FragmentListType& newlist = pTo->getFragmentList(); 742f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 743f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (fragTo = newlist.begin(), fragToEnd = newlist.end(); 744f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines fragTo != fragToEnd; ++fragTo) { 745f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines fragTo->setParent(pTo); 746f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 747f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 748f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 749f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 750f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 751f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 752f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// allocateCommonSymbols - allocate common symbols in the corresponding 753f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// sections. This is called at pre-layout stage. 754f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// @refer Google gold linker: common.cc: 214 755f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool HexagonLDBackend::allocateCommonSymbols(Module& pModule) 756f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 757f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SymbolCategory& symbol_list = pModule.getSymbolTable(); 758f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 759f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (symbol_list.emptyCommons() && symbol_list.emptyLocals()) { 760f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SetSDataSection(); 761f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 762f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 763f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 764f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines int8_t maxGPSize = config().options().getGPSize(); 765f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 766f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SymbolCategory::iterator com_sym, com_end; 767f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 768f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // get corresponding BSS LDSection 769f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ELFFileFormat* file_format = getOutputFormat(); 770f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSection& bss_sect = file_format->getBSS(); 771f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSection& tbss_sect = file_format->getTBSS(); 772f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 773f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // get or create corresponding BSS SectionData 774f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData* bss_sect_data = NULL; 775f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (bss_sect.hasSectionData()) 776f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bss_sect_data = bss_sect.getSectionData(); 777f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines else 778f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bss_sect_data = IRBuilder::CreateSectionData(bss_sect); 779f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 780f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData* tbss_sect_data = NULL; 781f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (tbss_sect.hasSectionData()) 782f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines tbss_sect_data = tbss_sect.getSectionData(); 783f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines else 784f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines tbss_sect_data = IRBuilder::CreateSectionData(tbss_sect); 785f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 786f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // remember original BSS size 787f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t bss_offset = bss_sect.size(); 788f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t tbss_offset = tbss_sect.size(); 789f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 790f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // allocate all local common symbols 791f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines com_end = symbol_list.localEnd(); 792f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 793f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (com_sym = symbol_list.localBegin(); com_sym != com_end; ++com_sym) { 794f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (ResolveInfo::Common == (*com_sym)->desc()) { 795f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // We have to reset the description of the symbol here. When doing 796f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // incremental linking, the output relocatable object may have common 797f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // symbols. Therefore, we can not treat common symbols as normal symbols 798f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // when emitting the regular name pools. We must change the symbols' 799f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // description here. 800f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 801f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 802f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 803f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines switch((*com_sym)->size()) { 804f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case 1: 805f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (maxGPSize <= 0) 806f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 807f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ObjectBuilder::AppendFragment(*frag, 808f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *(m_pscommon_1->getSectionData()), 809f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (*com_sym)->value()); 81087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 811f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 812f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case 2: 813f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (maxGPSize <= 1) 814f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 815f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ObjectBuilder::AppendFragment(*frag, 816f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *(m_pscommon_2->getSectionData()), 817f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (*com_sym)->value()); 81887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 819f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 820f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case 4: 821f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (maxGPSize <= 3) 822f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 823f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ObjectBuilder::AppendFragment(*frag, 824f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *(m_pscommon_4->getSectionData()), 825f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (*com_sym)->value()); 82687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 827f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 828f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case 8: 829f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (maxGPSize <= 7) 830f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 831f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ObjectBuilder::AppendFragment(*frag, 832f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *(m_pscommon_8->getSectionData()), 833f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (*com_sym)->value()); 83487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 835f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 836f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines default: 837f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 838f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 839f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 840f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 841f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // allocate TLS common symbol in tbss section 842f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines tbss_offset += ObjectBuilder::AppendFragment(*frag, 843f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *tbss_sect_data, 844f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (*com_sym)->value()); 84587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 846f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 847f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // FIXME: how to identify small and large common symbols? 848f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines else { 849f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bss_offset += ObjectBuilder::AppendFragment(*frag, 850f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *bss_sect_data, 851f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (*com_sym)->value()); 85287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 853f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 854f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 855f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 856f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 857f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // allocate all global common symbols 858f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines com_end = symbol_list.commonEnd(); 859f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (com_sym = symbol_list.commonBegin(); com_sym != com_end; ++com_sym) { 860f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // We have to reset the description of the symbol here. When doing 861f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // incremental linking, the output relocatable object may have common 862f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // symbols. Therefore, we can not treat common symbols as normal symbols 863f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // when emitting the regular name pools. We must change the symbols' 864f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // description here. 865f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (*com_sym)->resolveInfo()->setDesc(ResolveInfo::Define); 866f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Fragment* frag = new FillFragment(0x0, 1, (*com_sym)->size()); 867f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 868f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines switch((*com_sym)->size()) { 869f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case 1: 870f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (maxGPSize <= 0) 871f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 872f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ObjectBuilder::AppendFragment(*frag, 873f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *(m_pscommon_1->getSectionData()), 874f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (*com_sym)->value()); 87587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 876f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 877f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case 2: 878f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (maxGPSize <= 1) 879f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 880f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ObjectBuilder::AppendFragment(*frag, 881f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *(m_pscommon_2->getSectionData()), 882f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (*com_sym)->value()); 88387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 884f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 885f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case 4: 886f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (maxGPSize <= 3) 887f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 888f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ObjectBuilder::AppendFragment(*frag, 889f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *(m_pscommon_4->getSectionData()), 890f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (*com_sym)->value()); 89187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 892f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 893f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines case 8: 894f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (maxGPSize <= 7) 895f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 896f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ObjectBuilder::AppendFragment(*frag, 897f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *(m_pscommon_8->getSectionData()), 898f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (*com_sym)->value()); 89987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 900f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 901f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines default: 902f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 903f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 904f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 905f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (ResolveInfo::ThreadLocal == (*com_sym)->type()) { 906f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // allocate TLS common symbol in tbss section 907f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines tbss_offset += ObjectBuilder::AppendFragment(*frag, 908f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *tbss_sect_data, 909f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (*com_sym)->value()); 91087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 911f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 912f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // FIXME: how to identify small and large common symbols? 913f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines else { 914f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bss_offset += ObjectBuilder::AppendFragment(*frag, 915f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines *bss_sect_data, 916f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (*com_sym)->value()); 91787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (*com_sym)->setFragmentRef(FragmentRef::Create(*frag, 0)); 918f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 919f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 920f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 921f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bss_sect.setSize(bss_offset); 922f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines tbss_sect.setSize(tbss_offset); 923f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines symbol_list.changeCommonsToGlobal(); 924f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SetSDataSection(); 925f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 926f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 927f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 928f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool HexagonLDBackend::MoveCommonData(SectionData &pFrom, SectionData &pTo) 929f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 930f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData::FragmentListType& to_list = pTo.getFragmentList(); 931f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData::FragmentListType::iterator frag, fragEnd = to_list.end(); 932f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 933f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint32_t pFromFlag = pFrom.getSection().align(); 934f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool found = false; 935f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 936f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData::FragmentListType::iterator fragInsert; 937f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 938f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (frag = to_list.begin(); frag != fragEnd; ++frag) { 939f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (frag->getKind() == mcld::Fragment::Alignment) { 940f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines fragInsert = frag; 941f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 942f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 943f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ((frag->getKind() != mcld::Fragment::Region) && 944f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (frag->getKind() != mcld::Fragment::Fillment)) { 945f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 946f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 947f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint32_t flag = frag->getParent()->getSection().align(); 948f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pFromFlag < flag) { 949f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines found = true; 950f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 951f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 952f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 953f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines AlignFragment* align = NULL; 954f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pFrom.getSection().align() > 1) { 955f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // if the align constraint is larger than 1, append an alignment 956f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines align = new AlignFragment(pFrom.getSection().align(), // alignment 957f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 0x0, // the filled value 958f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1u, // the size of filled value 959f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pFrom.getSection().align() - 1 // max bytes to emit 960f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ); 961f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pFrom.getFragmentList().push_front(align); 962f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 963f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (found) 964f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines to_list.splice(fragInsert, pFrom.getFragmentList()); 965f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines else 966f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines to_list.splice(frag, pFrom.getFragmentList()); 967f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 968f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 969f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 970f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 971f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool HexagonLDBackend::readSection(Input& pInput, SectionData& pSD) 972f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 973f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Fragment* frag = NULL; 974f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint32_t offset = pInput.fileOffset() + pSD.getSection().offset(); 975f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint32_t size = pSD.getSection().size(); 976f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 977f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pSD.getSection().type() == llvm::ELF::SHT_NOBITS) { 978f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines frag = new FillFragment(0x0, 1, size); 979f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 980f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines else { 98187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::StringRef region = pInput.memArea()->request(offset, size); 98287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (region.size() == 0) { 983f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // If the input section's size is zero, we got a NULL region. 984f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // use a virtual fill fragment 985f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines frag = new FillFragment(0x0, 0, 0); 986f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 987f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines else { 98887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines frag = new RegionFragment(region); 989f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 990f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 991f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 992f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ObjectBuilder::AppendFragment(*frag, pSD); 993f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return true; 994f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 995f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 996f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// MoveSectionData - move the fragments of pTO section data to pTo 997f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool HexagonLDBackend::MoveSectionDataAndSort(SectionData& pFrom, SectionData& pTo) 998f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{ 999f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(&pFrom != &pTo && "Cannot move section data to itself!"); 1000f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData::FragmentListType& to_list = pTo.getFragmentList(); 1001f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData::FragmentListType::iterator frag, fragEnd = to_list.end(); 1002f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1003f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint32_t pFromFlag = pFrom.getSection().align(); 1004f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool found = false; 1005f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1006f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines SectionData::FragmentListType::iterator fragInsert; 1007f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1008f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (frag = to_list.begin(); frag != fragEnd; ++frag) { 1009f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (frag->getKind() == mcld::Fragment::Alignment) { 1010f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines fragInsert = frag; 1011f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 1012f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 1013f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ((frag->getKind() != mcld::Fragment::Region) && 1014f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines (frag->getKind() != mcld::Fragment::Fillment)) { 1015f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 1016f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 1017f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint32_t flag = frag->getParent()->getSection().align(); 1018f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pFromFlag < flag) { 1019f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines found = true; 1020f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 1021f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 1022f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 1023f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines AlignFragment* align = NULL; 1024f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pFrom.getSection().align() > 1) { 1025f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // if the align constraint is larger than 1, append an alignment 1026f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines align = new AlignFragment(pFrom.getSection().align(), // alignment 1027f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 0x0, // the filled value 1028f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1u, // the size of filled value 1029f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pFrom.getSection().align() - 1 // max bytes to emit 1030f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ); 1031f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pFrom.getFragmentList().push_front(align); 1032f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 1033f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (found) 1034f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines to_list.splice(fragInsert, pFrom.getFragmentList()); 1035f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines else 1036f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines to_list.splice(frag, pFrom.getFragmentList()); 1037f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1038f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint32_t offset = 0; 1039f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (frag = to_list.begin(); frag != fragEnd; ++frag) { 1040f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines frag->setOffset(offset); 1041f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines offset += frag->size(); 1042f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 1043f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1044f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set up pTo's header 1045f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pTo.getSection().setSize(offset); 1046f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1047f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pFrom.getSection().align() > pTo.getSection().align()) 1048f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pTo.getSection().setAlign(pFrom.getSection().align()); 1049f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1050f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pFrom.getSection().flag() > pTo.getSection().flag()) 1051f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pTo.getSection().setFlag(pFrom.getSection().flag()); 10526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 10536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 10546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// doCreateProgramHdrs - backend can implement this function to create the 10566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// target-dependent segments 10576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid HexagonLDBackend::doCreateProgramHdrs(Module& pModule) 10586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 10596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // TODO 10606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 10616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesnamespace mcld { 10636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 1065f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines/// createHexagonLDBackend - the help funtion to create corresponding 10666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// HexagonLDBackend 106787f34658dec9097d987d254a990ea7f311bfc95fStephen HinesTargetLDBackend* createHexagonLDBackend(const LinkerConfig& pConfig) 10686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 10696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pConfig.targets().triple().isOSDarwin()) { 10706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(0 && "MachO linker is not supported yet"); 10716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines /** 10726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return new HexagonMachOLDBackend(createHexagonMachOArchiveReader, 10736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines createHexagonMachOObjectReader, 10746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines createHexagonMachOObjectWriter); 10756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines **/ 10766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pConfig.targets().triple().isOSWindows()) { 10786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(0 && "COFF linker is not supported yet"); 10796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines /** 10806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return new HexagonCOFFLDBackend(createHexagonCOFFArchiveReader, 10816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines createHexagonCOFFObjectReader, 10826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines createHexagonCOFFObjectWriter); 10836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines **/ 10846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1085f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return new HexagonLDBackend(pConfig, new HexagonGNUInfo(pConfig.targets())); 10866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 10876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} // namespace of mcld 10896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 10916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// Force static initialization. 10926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 10936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesextern "C" void MCLDInitializeHexagonLDBackend() { 10946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Register the linker backend 1095f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines mcld::TargetRegistry::RegisterTargetLDBackend(TheHexagonTarget, 10966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines createHexagonLDBackend); 10976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1098