Beispiel #1
0
TEST_F(SectionDataTest, Fragment_list_and_iterator) {
  LDSection* test = LDSection::Create("test", LDFileFormat::Null, 0, 0);
  SectionData* s = SectionData::Create(*test);
  EXPECT_TRUE(s->empty());

  new Fragment(Fragment::Alignment, s);
  new Fragment(Fragment::Alignment, s);
  new Fragment(Fragment::Region, s);
  new Fragment(Fragment::Fillment, s);
  new Fragment(Fragment::Target, s);
  EXPECT_TRUE(5 == s->size());

  // iterator
  llvm::iplist<Fragment>::iterator iter = s->begin();
  EXPECT_TRUE(Fragment::Alignment == iter->getKind());
  ++iter;
  EXPECT_TRUE(Fragment::Alignment == iter->getKind());
  ++iter;
  EXPECT_TRUE(Fragment::Region == iter->getKind());
  ++iter;
  EXPECT_TRUE(Fragment::Fillment == iter->getKind());
  ++iter;
  EXPECT_TRUE(Fragment::Target == iter->getKind());
  ++iter;
  EXPECT_TRUE(iter == s->end());

  LDSection::Destroy(test);
}
bool SectionSymbolSet::finalize(LDSection& pOutSect,
                                SymbolTable& pSymTab, bool relocatable)
{
  if (!relocatable && pOutSect.size() == 0)
      return true;

  LDSymbol* sym = get(pOutSect);
  assert(NULL != sym);
  SectionData* data = NULL;
  switch (pOutSect.kind()) {
    case LDFileFormat::Relocation:
      // Relocation section should not have section symbol.
      return true;

    case LDFileFormat::EhFrame:
      if (EhFrame *ehframe = pOutSect.getEhFrame())
          data = ehframe->getSectionData();
      break;

    default:
      data = pOutSect.getSectionData();
      break;
  }
  FragmentRef* frag_ref;
  if (data && !data->empty())
    frag_ref = FragmentRef::Create(data->front(), 0x0);
  else
    frag_ref = FragmentRef::Null();
  sym->setFragmentRef(frag_ref);
  // push symbol into output symbol table
  pSymTab.add(*sym);

  return true;
}
bool HexagonLDBackend::SetSDataSection() {
  SectionData *pTo = (m_psdata->getSectionData());

  if (pTo) {
    MoveCommonData(*m_pscommon_1->getSectionData(), *pTo);
    MoveCommonData(*m_pscommon_2->getSectionData(), *pTo);
    MoveCommonData(*m_pscommon_4->getSectionData(), *pTo);
    MoveCommonData(*m_pscommon_8->getSectionData(), *pTo);

    SectionData::FragmentListType& to_list = pTo->getFragmentList();
    SectionData::FragmentListType::iterator fragTo, fragToEnd = to_list.end();
    uint32_t offset = 0;
    for (fragTo = to_list.begin(); fragTo != fragToEnd; ++fragTo) {
      fragTo->setOffset(offset);
      offset += fragTo->size();
    }

    // set up pTo's header
    pTo->getSection().setSize(offset);

    SectionData::FragmentListType& newlist = pTo->getFragmentList();

    for (fragTo = newlist.begin(), fragToEnd = newlist.end();
         fragTo != fragToEnd; ++fragTo) {
      fragTo->setParent(pTo);
    }
  }

  return true;
}
/// addStub - add a stub into the island
bool BranchIsland::addStub(const Stub* pPrototype,
                           const Relocation& pReloc,
                           Stub& pStub)
{
  bool exist = false;
  Key key(pPrototype, pReloc.symInfo()->outSymbol(), pReloc.addend());
  StubEntryType* entry = m_StubMap.insert(key, exist);
  if (!exist) {
    entry->setValue(&pStub);
    m_pRear = &pStub;
    SectionData* sd = m_Entry.getParent();

    // insert alignment fragment
    // TODO: check if we can reduce this alignment fragment for some cases
    AlignFragment* align_frag = new AlignFragment(pStub.alignment(),
                                                  0x0,
                                                  1u,
                                                  pStub.alignment() - 1);
    align_frag->setParent(sd);
    sd->getFragmentList().insert(end(), align_frag);
    align_frag->setOffset(align_frag->getPrevNode()->getOffset() +
                          align_frag->getPrevNode()->size());

    // insert stub fragment
    pStub.setParent(sd);
    sd->getFragmentList().insert(end(), &pStub);
    pStub.setOffset(pStub.getPrevNode()->getOffset() +
                    pStub.getPrevNode()->size());
  }
  return !exist;
}
Beispiel #5
0
TEST_F(SectionDataTest, constructor_and_trivial_func) {
  LDSection* test = LDSection::Create("test", LDFileFormat::Null, 0, 0);

  SectionData* s = SectionData::Create(*test);
  EXPECT_TRUE(s->getSection().name() == "test" &&
              s->getSection().kind() == LDFileFormat::Null);

  LDSection::Destroy(test);
}
Beispiel #6
0
static RegionFragment* findRegionFragment(LDSection& pSection) {
  SectionData* sectData = pSection.getSectionData();
  for (SectionData::iterator it = sectData->begin(),
                             end = sectData->end(); it != end; ++it) {
    if (it->getKind() == Fragment::Region) {
      return static_cast<RegionFragment*>(&*it);
    }
  }
  return NULL;
}
void AArch64GNULDBackend::scanErrata(Module& pModule,
                                     IRBuilder& pBuilder,
                                     size_t& num_new_stubs,
                                     size_t& stubs_strlen) {
  // TODO: Implement AArch64 ErrataStubFactory to create the specific erratum
  //       stub and simplify the logics.
  for (Module::iterator sect = pModule.begin(), sectEnd = pModule.end();
       sect != sectEnd; ++sect) {
    if (((*sect)->kind() == LDFileFormat::TEXT) && (*sect)->hasSectionData()) {
      SectionData* sd = (*sect)->getSectionData();
      for (SectionData::iterator it = sd->begin(), ie = sd->end(); it != ie;
           ++it) {
        Fragment* frag = llvm::dyn_cast<RegionFragment>(it);
        if (frag != NULL) {
          FragmentRef* frag_ref = FragmentRef::Create(*frag, 0);
          for (unsigned offset = 0; offset < frag->size();
               offset += AArch64InsnHelpers::InsnSize) {
            Stub* stub = getStubFactory()->create(*frag_ref,
                                                  pBuilder,
                                                  *getBRIslandFactory());
            if (stub != NULL) {
              // A stub symbol should be local
              assert(stub->symInfo() != NULL && stub->symInfo()->isLocal());
              const AArch64CA53ErratumStub* erratum_stub =
                  reinterpret_cast<const AArch64CA53ErratumStub*>(stub);
              assert(erratum_stub != NULL);
              // Rewrite the erratum instruction as a branch to the stub.
              uint64_t offset = frag_ref->offset() +
                                erratum_stub->getErratumInsnOffset();
              Relocation* reloc =
                  Relocation::Create(llvm::ELF::R_AARCH64_JUMP26,
                                     *(FragmentRef::Create(*frag, offset)),
                                     /* pAddend */0);
              reloc->setSymInfo(stub->symInfo());
              reloc->target() = AArch64InsnHelpers::buildBranchInsn();
              addExtraRelocation(reloc);

              ++num_new_stubs;
              stubs_strlen += stub->symInfo()->nameSize() + 1;
            }

            frag_ref->assign(*frag, offset + AArch64InsnHelpers::InsnSize);
          }  // for each INSN
        }
      }  // for each FRAGMENT
    }
  }  // for each TEXT section
}
/**
 * 检查是否超限
 * 如果有左值、右值小于超限值,则返回true
 * 如果当前值为-1不做比较
 */
bool ClearanceData::checkLessThanStdSectionData(SectionData & basedata)
{
    std::map<int,ClearanceItem>::iterator it = vals.begin();
    std::map<int, item> & basemap = basedata.getMaps();
    int tempkey;
    float tmpvalf;
    int tmpvali;
	while (it != vals.end())
    {
        /*
        vs2012下不行,出错“初始化”: 无法从“std::pair<_Ty1,_Ty2>”转换为“std::pair<_Ty1,_Ty2>”
        std::pair<int,item&> pair = (*it);
        pair.second.left = -1;
        pair.second.right = -1;
        */
        std::pair<int,ClearanceItem> pair = (*it);
        tempkey = pair.first;
        if (vals[tempkey].leftval > 0 && vals[tempkey].leftval < basemap[tempkey].left)
            return true;
        if (vals[tempkey].rightval > 0 && vals[tempkey].rightval < basemap[tempkey].right)
            return true;

        it++;
    }
    return false;
}
Beispiel #9
0
    pySectionData(int np, const bpn::array &z_np, const bpn::array &EA_np,
                  const bpn::array &EIxx_np, const bpn::array &EIyy_np, const bpn::array &GJ_np,
                  const bpn::array &rhoA_np, const bpn::array &rhoJ_np) {

        sec.nodes = np;

        sec.z.resize(sec.nodes);
        sec.EA.resize(sec.nodes);
        sec.EIxx.resize(sec.nodes);
        sec.EIyy.resize(sec.nodes);
        sec.GJ.resize(sec.nodes);
        sec.rhoA.resize(sec.nodes);
        sec.rhoJ.resize(sec.nodes);


        for (int i = 0 ; i < sec.nodes; i++) {
            sec.z(i) = bp::extract<double>(z_np[i]);
            sec.EA(i) = bp::extract<double>(EA_np[i]);
            sec.EIxx(i) = bp::extract<double>(EIxx_np[i]);
            sec.EIyy(i) = bp::extract<double>(EIyy_np[i]);
            sec.GJ(i) = bp::extract<double>(GJ_np[i]);
            sec.rhoA(i) = bp::extract<double>(rhoA_np[i]);
            sec.rhoJ(i) = bp::extract<double>(rhoJ_np[i]);
        }



    }
bool ARMGNULDBackend::readSection(Input& pInput, SectionData& pSD)
{
  Fragment* frag = NULL;
  uint32_t offset = pInput.fileOffset() + pSD.getSection().offset();
  uint32_t size = pSD.getSection().size();

  llvm::StringRef region = pInput.memArea()->request(offset, size);
  if (region.size() == 0) {
    // If the input section's size is zero, we got a NULL region.
    // use a virtual fill fragment
    frag = new FillFragment(0x0, 0, 0);
  }
  else {
    frag = new RegionFragment(region);
  }

  ObjectBuilder::AppendFragment(*frag, pSD);
  return true;
}
Beispiel #11
0
ErrorStatus::FileError AFTSectionPipeFace::Save(SectionData &Data,SectionPipePerisistent& model)
{
	Data.Search(model.Search());
	Data.MaxSections(model.MaxSections());
	Data.MinSections(model.MinSections());
	Data.MaxError(model.MaxError());
	Data.PctIncrement(model.PctIncrement());
	Data.Sort(model.Sort());
	Data.IdealSections(model.IdealSections());
	Data.TimeStep(model.TimeStep());
	return ErrorStatus::eFileOK;
}
Beispiel #12
0
FragmentRef* FragmentRef::Create(LDSection& pSection, uint64_t pOffset) {
  SectionData* data = NULL;
  switch (pSection.kind()) {
    case LDFileFormat::Relocation:
      // No fragment reference refers to a relocation section
      break;
    case LDFileFormat::EhFrame:
      if (pSection.hasEhFrame())
        data = pSection.getEhFrame()->getSectionData();
      break;
    default:
      data = pSection.getSectionData();
      break;
  }

  if (data == NULL || data->empty()) {
    return Null();
  }

  return Create(data->front(), pOffset);
}
Beispiel #13
0
bool HexagonLDBackend::MoveCommonData(SectionData &pFrom, SectionData &pTo)
{
  SectionData::FragmentListType& to_list = pTo.getFragmentList();
  SectionData::FragmentListType::iterator frag, fragEnd = to_list.end();

  uint32_t pFromFlag = pFrom.getSection().align();
  bool found = false;

  SectionData::FragmentListType::iterator fragInsert;

  for (frag = to_list.begin(); frag != fragEnd; ++frag) {
    if (frag->getKind() == mcld::Fragment::Alignment) {
      fragInsert = frag;
      continue;
    }
    if ((frag->getKind() != mcld::Fragment::Region) &&
        (frag->getKind() != mcld::Fragment::Fillment)) {
      continue;
    }
    uint32_t flag = frag->getParent()->getSection().align();
    if (pFromFlag < flag) {
      found = true;
      break;
    }
  }
  AlignFragment* align = NULL;
  if (pFrom.getSection().align() > 1) {
    // if the align constraint is larger than 1, append an alignment
    align = new AlignFragment(pFrom.getSection().align(), // alignment
                              0x0, // the filled value
                              1u,  // the size of filled value
                              pFrom.getSection().align() - 1 // max bytes to emit
                              );
    pFrom.getFragmentList().push_front(align);
  }
  if (found)
    to_list.splice(fragInsert, pFrom.getFragmentList());
  else
    to_list.splice(frag, pFrom.getFragmentList());

  return true;
}
/// emitSectionData
void ELFObjectWriter::emitSectionData(const SectionData& pSD,
                                      MemoryRegion& pRegion) const
{
  SectionData::const_iterator fragIter, fragEnd = pSD.end();
  size_t cur_offset = 0;
  for (fragIter = pSD.begin(); fragIter != fragEnd; ++fragIter) {
    size_t size = fragIter->size();
    switch(fragIter->getKind()) {
      case Fragment::Region: {
        const RegionFragment& region_frag = llvm::cast<RegionFragment>(*fragIter);
        const uint8_t* from = region_frag.getRegion().start();
        memcpy(pRegion.getBuffer(cur_offset), from, size);
        break;
      }
      case Fragment::Alignment: {
        // TODO: emit values with different sizes (> 1 byte), and emit nops
        const AlignFragment& align_frag = llvm::cast<AlignFragment>(*fragIter);
        uint64_t count = size / align_frag.getValueSize();
        switch (align_frag.getValueSize()) {
          case 1u:
            std::memset(pRegion.getBuffer(cur_offset),
                        align_frag.getValue(),
                        count);
            break;
          default:
            llvm::report_fatal_error("unsupported value size for align fragment emission yet.\n");
            break;
        }
        break;
      }
      case Fragment::Fillment: {
        const FillFragment& fill_frag = llvm::cast<FillFragment>(*fragIter);
        if (0 == size ||
            0 == fill_frag.getValueSize() ||
            0 == fill_frag.size()) {
          // ignore virtual fillment
          break;
        }

        uint64_t num_tiles = fill_frag.size() / fill_frag.getValueSize();
        for (uint64_t i = 0; i != num_tiles; ++i) {
          std::memset(pRegion.getBuffer(cur_offset),
                      fill_frag.getValue(),
                      fill_frag.getValueSize());
        }
        break;
      }
      case Fragment::Stub: {
        const Stub& stub_frag = llvm::cast<Stub>(*fragIter);
        memcpy(pRegion.getBuffer(cur_offset), stub_frag.getContent(), size);
        break;
      }
      case Fragment::Null: {
        assert(0x0 == size);
        break;
      }
      case Fragment::Target:
        llvm::report_fatal_error("Target fragment should not be in a regular section.\n");
        break;
      default:
        llvm::report_fatal_error("invalid fragment should not be in a regular section.\n");
        break;
    }
    cur_offset += size;
  }
}
int LzExcelOutput::outputSingleSection(TunnelDataModel * inputbasicdata, QString collectdate, SectionData & inputdata, QString templatepath, QString outputfile, QString insertimgpath)
{
    QString templatename = "SingleSectionTemplate.xls";
    int ret = copy(templatepath, templatename, outputfile);
    qDebug() << templatepath << outputfile << insertimgpath;

    if (ret != 0)
        return ret;

    // 插入图片路径不存在
    if (!QFile(insertimgpath).exists())
        return 3;

    //操作已经存在的excel,生成限界尺寸表
    ExcelEngine excel;

    excel.Open(outputfile, 1, false);

    // 限界表名称
    excel.SetCellData(1,1,QObject::tr("%1隧道单幅尺寸表").arg(QObject::tr(inputbasicdata->getName().c_str())));
    excel.SetCellData(52,1,QObject::tr("%1隧道断面示意图").arg(QObject::tr(inputbasicdata->getName().c_str())));

    // 线路名称
    excel.SetCellData(3,2,QObject::tr(inputbasicdata->getLinename().c_str()));
    excel.SetCellData(54,2,QObject::tr(inputbasicdata->getLinename().c_str()));

    // 区段///TODO
    excel.SetCellData(3,7,QObject::tr(inputbasicdata->getLinename().c_str()));
    // 面向站名
    excel.SetCellData(3,10,QObject::tr(inputbasicdata->getLineEndStation().c_str()));
    excel.SetCellData(54,8,QObject::tr(inputbasicdata->getLineEndStation().c_str()));

    // 桥隧名称
    excel.SetCellData(4,3,QObject::tr(inputbasicdata->getName().c_str()));
    excel.SetCellData(54,4,QObject::tr(inputbasicdata->getName().c_str()));

    // 时间
    QByteArray ba = collectdate.toLocal8Bit();
    excel.SetCellData(48,10,ba.constData());
    excel.SetCellData(54,10,ba.constData());

    // 计算隧道长度
    _int64 tunnellength = inputbasicdata->getEndPoint() - inputbasicdata->getStartPoint();
    if (tunnellength < 0)
        tunnellength = 0 - tunnellength;
    //excel.SetCellData(102,3,tunnellength); 

    // 计算中心里程 隧道中心点的里程数
    float centerlength = 1.0 * (inputbasicdata->getEndPoint() + inputbasicdata->getStartPoint()) / 2; 
    excel.SetCellData(4,7,centerlength);
    excel.SetCellData(101,3,centerlength); 

    SectionData & data = inputdata;
    int rowcount = data.getMaps().size();
    
    // Excel模板从第9行开始为高度限界数据,前面几行为表头或空格
    int startrownum = 9;
    int startcolumnnumdef = 1;
    
    // 临时变量
    int startcolumnnum = startcolumnnumdef;
    float tmpval;
    __int64 tmppos;
    int tmpradius;
    
    {
        startcolumnnum = startcolumnnumdef;
        
        CurveType type = inputdata.getType();
        long long pos = inputdata.getMile();
        int radius = inputdata.getRadius();
        float minHeight = inputdata.getCenterHeight();

        switch(type)
        {
            case Curve_Straight:
                startcolumnnum += LzOutputTableColumn::Straight_Left_Val;
                break;
            case Curve_Left:
                startcolumnnum += 3;
                break;
            case Curve_Right:
                startcolumnnum += 7;
                break;
            default:
                break;
        }

        // map反向遍历,正向为高度从小到大,插入图表是需要高度从大到小
        std::map<int, item>::reverse_iterator it = data.getMaps().rbegin();
        int k = 0; // 相对行数
        while (it != data.getMaps().rend())
        {
            std::pair<int, item> pair = (*it);

            if (pair.first > minHeight)
            {
                it++;
                k++;
                continue;
            }

            // 此处写要插入的内容
            if (pair.second.left >= 0)
                excel.SetCellData(k + startrownum, startcolumnnum, (int)pair.second.left); 
            if (pair.second.right >= 0)
                excel.SetCellData(k + startrownum, startcolumnnum + 1, (int)pair.second.right);
            if (type != Curve_Straight) // 不是直线,折减后尺寸
            {
                if (pair.second.left >= 0)
                    excel.SetCellData(k + startrownum, startcolumnnum + 2, (long long)pair.second.left); 
                if (pair.second.right >= 0)
                    excel.SetCellData(k + startrownum, startcolumnnum + 3, (long long)pair.second.left);
            }
            it++;
            k++;
        }
    }

    // <150高度手动输入? ///TODO

    // 线路中心线上方最低净高mm///TODO
    excel.SetCellData(rowcount+startrownum+1,6,(int)inputdata.getCenterHeight());
    
    // 半径
    int radius = inputdata.getRadius();
    if (radius <= 0)
        radius = 0;
    excel.SetCellData(4,10,radius); 
    excel.SetCellData(54,6,radius); 
    excel.SetCellData(102,3,radius); 

    excel.setProperty("DisplayAlerts", 0);
    
    // 保存
    excel.Save(); 
    excel.Close();    
    
    // 生成限界图
    initExcelEngine();

    QAxObject *workBooks1 = excel1->querySubObject("Workbooks");
    workBooks1->dynamicCall("Open(const QString&)", outputfile);
    QAxObject *workBook1 = excel1->querySubObject("ActiveWorkBook");
    QAxObject *sheets1 = workBook1->querySubObject("WorkSheets");
    QAxObject *sheet1 = sheets1->querySubObject("Item(int)", 1);//获得第一个工作表

    // QAxObject *range=sheet1->querySubObject("Range(const QVariant&)",QVariant(QString("D52:AA92")));
    // range->dynamicCall("Clear()");//指定清除某个区域

    /////////////AddPicture函数详解////////////////
    // AddPicture(FileName, LinkToFile, SaveWithDocument, Left, Top, Width, Height)中7个参数的意思。
    // (1)FileName 必选 String 图片的路径和文件名。
    // (2)LinkToFile 可选 Variant 如果该参数值为 True,则将图片链接到创建它的文件。如果该参数值为 False,则将图片作为该文件的独立副本。默认值为 False。
    // (3)SaveWithDocument 可选 Variant 如果该参数值为 True,则将链接的图片与文档一起保存。默认值为 False。
    // (4)Left 可选 Variant 新图片的左边缘相对于绘图画布的位置,以磅为单位。
    // (5)Top 可选 Variant 新图片的上边缘相对于绘图画布的位置,以磅为单位。
    // (6)Width 可选 Variant 图片的宽度,以磅为单位。
    // (7)Height 可选 Variant 图片的高度,以磅为单位。
    ///////////////////////////////////////////////

    // @author 熊雪、范翔。路径变成反斜杠,否则AddPicture,SaveAs函数出错
    outputfile = toBackSlashStr(outputfile);
    insertimgpath = toBackSlashStr(insertimgpath);

    QAxObject *shapes1 = sheet1->querySubObject("Shapes");
    shapes1->dynamicCall("AddPicture(QString&,bool,bool,double,double,double,double",QString("%1").arg(insertimgpath),true,true,8,770,510,595);//8,750,510,627  QString("%1image.jpg").arg(outputfile)
    excel1->setProperty("DisplayAlerts", 0);
    //excel1->dynamicCall("Save()");
    workBook1->dynamicCall("SaveAs(const QString&)", outputfile);
    // QMessageBox::information(NULL, tr("OK"), tr("成功生成Excel文件!"),QMessageBox::Yes | QMessageBox::No);
    excel1->dynamicCall("Quit()");

    return 0;
}
Beispiel #16
0
void ARMGNULDBackend::rewriteARMExIdxSection(Module& pModule) {
  if (!m_pEXIDX->hasSectionData()) {
    // Return if this is empty section.
    return;
  }

  SectionData* sectData = m_pEXIDX->getSectionData();
  SectionData::FragmentListType& list = sectData->getFragmentList();

  // Move the first fragment (align fragment) and last fragment (null fragment)
  // to temporary list because we would only like to sort the region fragment.
  SectionData::FragmentListType tmp;
  {
    SectionData::iterator first = sectData->begin();
    SectionData::iterator last = sectData->end();
    --last;

    assert(first->getKind() == Fragment::Alignment);
    assert(last->getKind() == Fragment::Null);

    tmp.splice(tmp.end(), list, first);
    tmp.splice(tmp.end(), list, last);
  }

  // Sort the region fragments in the .ARM.exidx output section.
  sort(list, ExIdxFragmentComparator(m_ExData));

  // Fix the coverage of the .ARM.exidx table.
  llvm::StringRef cantUnwindRegion(g_CantUnwindEntry,
                                   sizeof(g_CantUnwindEntry));

  SectionData::FragmentListType::iterator it = list.begin();
  if (it != list.end()) {
    Fragment* prevTextFrag = m_ExData.getTupleByExIdx(it)->getTextFragment();
    uint64_t prevTextEnd = prevTextFrag->getParent()->getSection().addr() +
                           prevTextFrag->getOffset() +
                           prevTextFrag->size();
    ++it;
    while (it != list.end()) {
      Fragment* currTextFrag = m_ExData.getTupleByExIdx(it)->getTextFragment();
      uint64_t currTextBegin = currTextFrag->getParent()->getSection().addr() +
                               currTextFrag->getOffset();

      if (currTextBegin > prevTextEnd) {
        // Found a gap. Insert a can't unwind entry.
        RegionFragment* frag = new RegionFragment(cantUnwindRegion, nullptr);
        frag->setParent(sectData);
        list.insert(it, frag);

        // Add PREL31 reference to the beginning of the uncovered region.
        Relocation* reloc =
            Relocation::Create(static_cast<uint32_t>(llvm::ELF::R_ARM_PREL31),
                               *FragmentRef::Create(*frag, /* pOffset */0),
                               /* pAddend */0);
        reloc->setSymInfo(
            CreateLocalSymbolToFragmentEnd(pModule, *prevTextFrag));
        addExtraRelocation(reloc);
      }

      prevTextEnd = currTextBegin + currTextFrag->size();
      prevTextFrag = currTextFrag;
      ++it;
    }

    // Add a can't unwind entry to terminate .ARM.exidx section.
    RegionFragment* frag = new RegionFragment(cantUnwindRegion, nullptr);
    frag->setParent(sectData);
    list.push_back(frag);

    // Add PREL31 reference to the end of the .text section.
    Relocation* reloc =
        Relocation::Create(static_cast<uint32_t>(llvm::ELF::R_ARM_PREL31),
                           *FragmentRef::Create(*frag, /* pOffset */0),
                           /* pAddend */0);
    reloc->setSymInfo(CreateLocalSymbolToFragmentEnd(pModule, *prevTextFrag));
    addExtraRelocation(reloc);
  }

  // Add the first and the last fragment back.
  list.splice(list.begin(), tmp, tmp.begin());
  list.splice(list.end(), tmp, tmp.begin());

  // Update the fragment offsets.
  uint64_t offset = 0;
  for (SectionData::iterator it = sectData->begin(), end = sectData->end();
       it != end; ++it) {
    it->setOffset(offset);
    offset += it->size();
  }

  // Update the section size.
  m_pEXIDX->setSize(offset);

  // Rebuild the section header.
  setOutputSectionAddress(pModule);
}
Beispiel #17
0
/// MoveSectionData - move the fragments of pTO section data to pTo
bool HexagonLDBackend::MoveSectionDataAndSort(SectionData& pFrom, SectionData& pTo)
{
  assert(&pFrom != &pTo && "Cannot move section data to itself!");
  SectionData::FragmentListType& to_list = pTo.getFragmentList();
  SectionData::FragmentListType::iterator frag, fragEnd = to_list.end();

  uint32_t pFromFlag = pFrom.getSection().align();
  bool found = false;

  SectionData::FragmentListType::iterator fragInsert;

  for (frag = to_list.begin(); frag != fragEnd; ++frag) {
    if (frag->getKind() == mcld::Fragment::Alignment) {
      fragInsert = frag;
      continue;
    }
    if ((frag->getKind() != mcld::Fragment::Region) &&
        (frag->getKind() != mcld::Fragment::Fillment)) {
      continue;
    }
    uint32_t flag = frag->getParent()->getSection().align();
    if (pFromFlag < flag) {
      found = true;
      break;
    }
  }
  AlignFragment* align = NULL;
  if (pFrom.getSection().align() > 1) {
    // if the align constraint is larger than 1, append an alignment
    align = new AlignFragment(pFrom.getSection().align(), // alignment
                              0x0, // the filled value
                              1u,  // the size of filled value
                              pFrom.getSection().align() - 1 // max bytes to emit
                              );
    pFrom.getFragmentList().push_front(align);
  }
  if (found)
    to_list.splice(fragInsert, pFrom.getFragmentList());
  else
    to_list.splice(frag, pFrom.getFragmentList());

  uint32_t offset = 0;
  for (frag = to_list.begin(); frag != fragEnd; ++frag) {
    frag->setOffset(offset);
    offset += frag->size();
  }

  // set up pTo's header
  pTo.getSection().setSize(offset);

  if (pFrom.getSection().align() > pTo.getSection().align())
    pTo.getSection().setAlign(pFrom.getSection().align());

  if (pFrom.getSection().flag() > pTo.getSection().flag())
    pTo.getSection().setFlag(pFrom.getSection().flag());
  return true;
}
Beispiel #18
0
bool MipsGNULDBackend::doRelax(Module& pModule,
                               IRBuilder& pBuilder,
                               bool& pFinished) {
  assert(getStubFactory() != NULL && getBRIslandFactory() != NULL);

  bool isRelaxed = false;

  for (Module::obj_iterator input = pModule.obj_begin();
       input != pModule.obj_end();
       ++input) {
    LDContext* context = (*input)->context();

    for (LDContext::sect_iterator rs = context->relocSectBegin();
         rs != context->relocSectEnd();
         ++rs) {
      LDSection* sec = *rs;

      if (LDFileFormat::Ignore == sec->kind() || !sec->hasRelocData())
        continue;

      for (RelocData::iterator reloc = sec->getRelocData()->begin();
           reloc != sec->getRelocData()->end();
           ++reloc) {
        if (llvm::ELF::R_MIPS_26 != reloc->type())
          continue;

        if (relaxRelocation(pBuilder, *llvm::cast<Relocation>(reloc)))
          isRelaxed = true;
      }
    }
  }

  SectionData* textData = getOutputFormat()->getText().getSectionData();

  // find the first fragment w/ invalid offset due to stub insertion
  Fragment* invalid = NULL;
  pFinished = true;
  for (BranchIslandFactory::iterator ii = getBRIslandFactory()->begin(),
                                     ie = getBRIslandFactory()->end();
       ii != ie;
       ++ii) {
    BranchIsland& island = *ii;
    if (island.end() == textData->end())
      break;

    Fragment* exit = island.end();
    if ((island.offset() + island.size()) > exit->getOffset()) {
      invalid = exit;
      pFinished = false;
      break;
    }
  }

  // reset the offset of invalid fragments
  while (invalid != NULL) {
    invalid->setOffset(invalid->getPrevNode()->getOffset() +
                       invalid->getPrevNode()->size());
    invalid = invalid->getNextNode();
  }

  // reset the size of .text
  if (isRelaxed)
    getOutputFormat()->getText().setSize(textData->back().getOffset() +
                                         textData->back().size());

  return isRelaxed;
}
bool AArch64GNULDBackend::doRelax(Module& pModule,
                                  IRBuilder& pBuilder,
                                  bool& pFinished) {
  assert(getStubFactory() != NULL && getBRIslandFactory() != NULL);

  // Number of new stubs added
  size_t num_new_stubs = 0;
  // String lengh to hold new stub symbols
  size_t stubs_strlen = 0;

  if (config().targets().fixCA53Erratum835769() ||
      config().targets().fixCA53Erratum843419()) {
    scanErrata(pModule, pBuilder, num_new_stubs, stubs_strlen);
  }

  ELFFileFormat* file_format = getOutputFormat();
  // check branch relocs and create the related stubs if needed
  Module::obj_iterator input, inEnd = pModule.obj_end();
  for (input = pModule.obj_begin(); input != inEnd; ++input) {
    LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
    for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
      if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData())
        continue;
      RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end();
      for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) {
        Relocation* relocation = llvm::cast<Relocation>(reloc);

        switch (relocation->type()) {
          case llvm::ELF::R_AARCH64_CALL26:
          case llvm::ELF::R_AARCH64_JUMP26: {
            // calculate the possible symbol value
            uint64_t sym_value = 0x0;
            LDSymbol* symbol = relocation->symInfo()->outSymbol();
            if (symbol->hasFragRef()) {
              uint64_t value = symbol->fragRef()->getOutputOffset();
              uint64_t addr =
                  symbol->fragRef()->frag()->getParent()->getSection().addr();
              sym_value = addr + value;
            }
            if ((relocation->symInfo()->reserved() &
                 AArch64Relocator::ReservePLT) != 0x0) {
              // FIXME: we need to find out the address of the specific plt
              // entry
              assert(file_format->hasPLT());
              sym_value = file_format->getPLT().addr();
            }
            Stub* stub = getStubFactory()->create(*relocation,  // relocation
                                                  sym_value,    // symbol value
                                                  pBuilder,
                                                  *getBRIslandFactory());
            if (stub != NULL) {
              // a stub symbol should be local
              assert(stub->symInfo() != NULL && stub->symInfo()->isLocal());
              // reset the branch target of the reloc to this stub instead
              relocation->setSymInfo(stub->symInfo());

              ++num_new_stubs;
              stubs_strlen += stub->symInfo()->nameSize() + 1;
            }
            break;
          }
          default: {
            break;
          }
        }  // end of switch
      }  // for all relocations
    }  // for all relocation section
  }  // for all inputs

  // Find the first fragment w/ invalid offset due to stub insertion.
  std::vector<Fragment*> invalid_frags;
  pFinished = true;
  for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(),
                                     island_end = getBRIslandFactory()->end();
       island != island_end;
       ++island) {
    if ((*island).size() > stubGroupSize()) {
      error(diag::err_no_space_to_place_stubs) << stubGroupSize();
      return false;
    }

    if ((*island).numOfStubs() == 0) {
      continue;
    }

    Fragment* exit = &*(*island).end();
    if (exit == (*island).begin()->getParent()->end()) {
      continue;
    }

    if (((*island).offset() + (*island).size()) > exit->getOffset()) {
      if (invalid_frags.empty() ||
          (invalid_frags.back()->getParent() != (*island).getParent())) {
        invalid_frags.push_back(exit);
        pFinished = false;
      }
      continue;
    }
  }

  // Reset the offset of invalid fragments.
  for (auto it = invalid_frags.begin(), ie = invalid_frags.end(); it != ie;
       ++it) {
    Fragment* invalid = *it;
    while (invalid != NULL) {
      invalid->setOffset(invalid->getPrevNode()->getOffset() +
                         invalid->getPrevNode()->size());
      invalid = invalid->getNextNode();
    }
  }

  // Fix up the size of .symtab, .strtab, and TEXT sections
  if (num_new_stubs == 0) {
    return false;
  } else {
    switch (config().options().getStripSymbolMode()) {
      case GeneralOptions::StripSymbolMode::StripAllSymbols:
      case GeneralOptions::StripSymbolMode::StripLocals:
        break;
      default: {
        LDSection& symtab = file_format->getSymTab();
        LDSection& strtab = file_format->getStrTab();

        symtab.setSize(symtab.size() +
                       sizeof(llvm::ELF::Elf64_Sym) * num_new_stubs);
        symtab.setInfo(symtab.getInfo() + num_new_stubs);
        strtab.setSize(strtab.size() + stubs_strlen);
      }
    }  // switch (config().options().getStripSymbolMode())

    SectionData* prev = NULL;
    for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(),
                                       island_end = getBRIslandFactory()->end();
         island != island_end;
         ++island) {
      SectionData* sd = (*island).begin()->getParent();
      if ((*island).numOfStubs() != 0) {
        if (sd != prev) {
          sd->getSection().setSize(sd->back().getOffset() + sd->back().size());
        }
      }
      prev = sd;
    }
    return true;
  }  // if (num_new_stubs == 0)
}