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