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