コード例 #1
0
bool ARMGNULDBackend::mergeSection(Module& pModule,
                                   const Input& pInput,
                                   LDSection& pSection)
{
  switch (pSection.type()) {
    case llvm::ELF::SHT_ARM_ATTRIBUTES: {
      return attribute().merge(pInput, pSection);
    }
    case llvm::ELF::SHT_ARM_EXIDX: {
      assert(NULL != pSection.getLink());
      if ((pSection.getLink()->kind() == LDFileFormat::Ignore) ||
          (pSection.getLink()->kind() == LDFileFormat::Folded)) {
        // if the target section of the .ARM.exidx is Ignore, then it should be
        // ignored as well
        pSection.setKind(LDFileFormat::Ignore);
        return true;
      }
    }
    /** fall through **/
    default: {
      ObjectBuilder builder(pModule);
      builder.MergeSection(pInput, pSection);
      return true;
    }
  } // end of switch
  return true;
}
コード例 #2
0
void GarbageCollection::stripSections()
{
  // Traverse all the input Regular and BSS sections, if a section is not found
  // in the ReferencedSections, then it should be garbage collected
  Module::obj_iterator obj, objEnd = m_Module.obj_end();
  for (obj = m_Module.obj_begin(); obj != objEnd; ++obj) {
    LDContext::sect_iterator sect, sectEnd = (*obj)->context()->sectEnd();
    for (sect = (*obj)->context()->sectBegin(); sect != sectEnd; ++sect) {
      LDSection* section = *sect;
      if (LDFileFormat::Regular != section->kind() &&
          LDFileFormat::BSS != section->kind())
        continue;

      if (m_ReferencedSections.find(section) == m_ReferencedSections.end())
        section->setKind(LDFileFormat::Ignore);
    }
  }

  // Traverse all the relocation sections, if its target section is set to
  // Ignore, then set the relocation section to Ignore as well
  Module::obj_iterator input, inEnd = m_Module.obj_end();
  for (input = m_Module.obj_begin(); input != inEnd; ++input) {
    LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
    for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
      LDSection* reloc_sect = *rs;
      if (LDFileFormat::Ignore == reloc_sect->getLink()->kind())
        reloc_sect->setKind(LDFileFormat::Ignore);
    }
  }
}
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;
}
コード例 #4
0
void IdenticalCodeFolding::findCandidates(FoldingCandidates& pCandidateList) {
  Module::obj_iterator obj, objEnd = m_Module.obj_end();
  for (obj = m_Module.obj_begin(); obj != objEnd; ++obj) {
    std::set<const LDSection*> funcptr_access_set;
    typedef std::map<LDSection*, LDSection*> CandidateMap;
    CandidateMap candidate_map;
    LDContext::sect_iterator sect, sectEnd = (*obj)->context()->sectEnd();
    for (sect = (*obj)->context()->sectBegin(); sect != sectEnd; ++sect) {
      switch ((*sect)->kind()) {
        case LDFileFormat::TEXT: {
          candidate_map.insert(
              std::make_pair(*sect, reinterpret_cast<LDSection*>(NULL)));
          break;
        }
        case LDFileFormat::Relocation: {
          LDSection* target = (*sect)->getLink();
          if (target->kind() == LDFileFormat::TEXT) {
            candidate_map[target] = *sect;
          }

          // Safe icf
          if (m_Config.options().getICFMode() == GeneralOptions::ICF::Safe) {
            RelocData::iterator rel, relEnd = (*sect)->getRelocData()->end();
            for (rel = (*sect)->getRelocData()->begin(); rel != relEnd; ++rel) {
              LDSymbol* sym = rel->symInfo()->outSymbol();
              if (sym->hasFragRef() && (sym->type() == ResolveInfo::Function)) {
                const LDSection* def =
                    &sym->fragRef()->frag()->getParent()->getSection();
                if (!isSymCtorOrDtor(*rel->symInfo()) &&
                    m_Backend.mayHaveUnsafeFunctionPointerAccess(*target) &&
                    m_Backend.getRelocator()
                        ->mayHaveFunctionPointerAccess(*rel)) {
                  funcptr_access_set.insert(def);
                }
              }
            }  // for each reloc
          }

          break;
        }
        default: {
          // skip
          break;
        }
      }  // end of switch
    }    // for each section

    CandidateMap::iterator candidate, candidateEnd = candidate_map.end();
    for (candidate = candidate_map.begin(); candidate != candidateEnd;
         ++candidate) {
      if ((m_Config.options().getICFMode() == GeneralOptions::ICF::All) ||
          (funcptr_access_set.count(candidate->first) == 0)) {
        size_t index = m_KeptSections.size();
        m_KeptSections[candidate->first] = ObjectAndId(*obj, index);
        pCandidateList.push_back(
            FoldingCandidate(candidate->first, candidate->second, *obj));
      }
    }  // for each possible candidate
  }  // for each obj
}
コード例 #5
0
void HexagonRelocator::scanRelocation(Relocation& pReloc,
                                      IRBuilder& pLinker,
                                      Module& pModule,
                                      LDSection& pSection,
                                      Input& pInput) {
  if (LinkerConfig::Object == config().codeGenType())
    return;

  // rsym - The relocation target symbol
  ResolveInfo* rsym = pReloc.symInfo();
  assert(rsym != NULL &&
         "ResolveInfo of relocation not set while scanRelocation");

  if (config().isCodeStatic())
    return;

  assert(pSection.getLink() != NULL);
  if ((pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC) == 0)
    return;

  if (rsym->isLocal())  // rsym is local
    scanLocalReloc(pReloc, pLinker, pModule, pSection);
  else  // rsym is external
    scanGlobalReloc(pReloc, pLinker, pModule, pSection);

  // check if we should issue undefined reference for the relocation target
  // symbol
  if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull())
    issueUndefRef(pReloc, pSection, pInput);
}
コード例 #6
0
/// emitRelocation
void ELFObjectWriter::emitRelocation(const LinkerConfig& pConfig,
                                     const LDSection& pSection,
                                     MemoryRegion& pRegion) const
{
  const RelocData* sect_data = pSection.getRelocData();
  assert(NULL != sect_data && "SectionData is NULL in emitRelocation!");

  if (pSection.type() == SHT_REL) {
    if (pConfig.targets().is32Bits())
      emitRel<32>(pConfig, *sect_data, pRegion);
    else if (pConfig.targets().is64Bits())
      emitRel<64>(pConfig, *sect_data, pRegion);
    else {
      fatal(diag::unsupported_bitclass) << pConfig.targets().triple().str()
                                        << pConfig.targets().bitclass();
    }
  } else if (pSection.type() == SHT_RELA) {
    if (pConfig.targets().is32Bits())
      emitRela<32>(pConfig, *sect_data, pRegion);
    else if (pConfig.targets().is64Bits())
      emitRela<64>(pConfig, *sect_data, pRegion);
    else {
      fatal(diag::unsupported_bitclass) << pConfig.targets().triple().str()
                                        << pConfig.targets().bitclass();
    }
  } else
    llvm::report_fatal_error("unsupported relocation section type!");
}
コード例 #7
0
/// emitShStrTab - emit section string table
void
ELFObjectWriter::emitShStrTab(const LDSection& pShStrTab,
                              const Module& pModule,
                              MemoryArea& pOutput)
{
  // write out data
  MemoryRegion* region = pOutput.request(pShStrTab.offset(), pShStrTab.size());
  unsigned char* data = region->start();
  size_t shstrsize = 0;
  Module::const_iterator section, sectEnd = pModule.end();
  for (section = pModule.begin(); section != sectEnd; ++section) {
    strcpy((char*)(data + shstrsize), (*section)->name().data());
    shstrsize += (*section)->name().size() + 1;
  }
}
コード例 #8
0
/// getSectInfo - compute ElfXX_Shdr::sh_info
uint64_t ELFObjectWriter::getSectInfo(const LDSection& pSection) const
{
  if (llvm::ELF::SHT_SYMTAB == pSection.type() ||
      llvm::ELF::SHT_DYNSYM == pSection.type())
    return pSection.getInfo();

  if (llvm::ELF::SHT_REL == pSection.type() ||
      llvm::ELF::SHT_RELA == pSection.type()) {
    const LDSection* info_link = pSection.getLink();
    if (NULL != info_link)
      return info_link->index();
  }

  return 0x0;
}
コード例 #9
0
void GarbageCollection::getEntrySections(SectionVecTy& pEntry)
{
  // all the KEEP sections defined in ldscript are entries, traverse all the
  // input sections and check the SectionMap to find the KEEP sections
  Module::obj_iterator obj, objEnd = m_Module.obj_end();
  SectionMap& sect_map = m_Module.getScript().sectionMap();
  for (obj = m_Module.obj_begin(); obj != objEnd; ++obj) {
    const std::string input_name = (*obj)->name();
    LDContext::sect_iterator sect, sectEnd = (*obj)->context()->sectEnd();
    for (sect = (*obj)->context()->sectBegin(); sect != sectEnd; ++sect) {
      LDSection* section = *sect;
      if (LDFileFormat::Regular != section->kind() &&
          LDFileFormat::BSS != section->kind())
        continue;

      SectionMap::Input* sm_input =
                              sect_map.find(input_name, section->name()).second;
      if ((sm_input != NULL) && (InputSectDesc::Keep == sm_input->policy()))
        pEntry.push_back(section);
    }
  }

  // get the sections those the entry symbols defined in
  Module::SymbolTable& sym_tab = m_Module.getSymbolTable();
  if (LinkerConfig::Exec == m_Config.codeGenType()) {
    assert(NULL != m_pEntry);
    pEntry.push_back(&m_pEntry->fragRef()->frag()->getParent()->getSection());
  }
  else {
    // when building shared objects, the global define symbols are entries
    SymbolCategory::iterator it, end = sym_tab.regularEnd();
    for (it = sym_tab.dynamicBegin(); it != end; ++it) {
      LDSymbol* sym = *it;
      if (!sym->resolveInfo()->isDefine() || !sym->hasFragRef())
        continue;

      // only the target symbols defined in the concerned sections can make
      // the reference
      const LDSection* sect =
                             &sym->fragRef()->frag()->getParent()->getSection();
      if (sect->kind() != LDFileFormat::Regular &&
          sect->kind() != LDFileFormat::BSS)
        continue;

      pEntry.push_back(sect);
    }
  }
}
コード例 #10
0
//===----------------------------------------------------------------------===//
// HexagonGOTPLT
//===----------------------------------------------------------------------===//
HexagonGOTPLT::HexagonGOTPLT(LDSection& pSection) : HexagonGOT(pSection) {
  // Skip GOT0 entries
  for (size_t i = 0; i < HexagonGOTPLT0Num; ++i) {
    create();
  }
  pSection.setAlign(8);
}
bool SectionSymbolSet::add(LDSection& pOutSect, NamePool& pNamePool)
{
  // create the resolveInfo for this section symbol
  llvm::StringRef sym_name = llvm::StringRef(pOutSect.name());
  ResolveInfo* sym_info = pNamePool.createSymbol(sym_name,
                                                 false,
                                                 ResolveInfo::Section,
                                                 ResolveInfo::Define,
                                                 ResolveInfo::Local,
                                                 0x0, // size
                                                 ResolveInfo::Default);

  // create the output section symbol and set its fragRef to the first fragment
  // of the section
  LDSymbol* sym = LDSymbol::Create(*sym_info);
  sym_info->setSymPtr(sym);

  // insert the symbol to the Section to Symbol hash map
  bool exist = false;
  SectHashTableType::entry_type* entry =
                            m_pSectionSymbolMap->insert(&pOutSect, exist);
  assert(!exist);
  entry->setValue(sym);

  return true;
}
コード例 #12
0
bool ARMGNULDBackend::readSection(Input& pInput,
                                  MCLinker& pLinker,
                                  LDSection& pInputSectHdr)
{
  LDSection& out_sect = pLinker.getOrCreateOutputSectHdr(pInputSectHdr.name(),
                                                         pInputSectHdr.kind(),
                                                         pInputSectHdr.type(),
                                                         pInputSectHdr.flag());
  // FIXME: (Luba)
  // Handle ARM attributes in the right way.
  // In current milestone, MCLinker goes through the shortcut.
  // It reads input's ARM attributes and copies the first ARM attributes
  // into the output file. The correct way is merge these sections, not
  // just copy.
  if ((0 == out_sect.name().compare(".ARM.attributes")) &&
      (0 != out_sect.size()))
    return true;

  MemoryRegion* region = pInput.memArea()->request(pInputSectHdr.offset(),
                                                   pInputSectHdr.size());

  llvm::MCSectionData& sect_data = pLinker.getOrCreateSectData(pInputSectHdr);

  new MCRegionFragment(*region, &sect_data);

  out_sect.setSize(out_sect.size() + pInputSectHdr.size());
  return true;
}
コード例 #13
0
/// mayHaveUnsafeFunctionPointerAccess - check if the section may have unsafe
/// function pointer access
bool
ARMGNULDBackend::mayHaveUnsafeFunctionPointerAccess(const LDSection& pSection)
    const
{
  llvm::StringRef name(pSection.name());
  return !name.startswith(".ARM.exidx") &&
         !name.startswith(".ARM.extab") &&
         GNULDBackend::mayHaveUnsafeFunctionPointerAccess(pSection);
}
コード例 #14
0
void NyuziRelocator::scanRelocation(Relocation& pReloc,
                                      IRBuilder& pBuilder,
                                      Module& pModule,
                                      LDSection& pSection,
                                      Input& pInput)
{
  ResolveInfo* rsym = pReloc.symInfo();
  assert(NULL != rsym &&
         "ResolveInfo of relocation not set while scanRelocation");

  assert(NULL != pSection.getLink());
  if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC))
    return;

  // check if we shoule issue undefined reference for the relocation target
  // symbol
  if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull())
    issueUndefRef(pReloc, pSection, pInput);
}
コード例 #15
0
/// merge Input Sections
bool HexagonLDBackend::mergeSection(Module& pModule,
                                    const Input& pInputFile,
                                    LDSection& pInputSection) {
  if ((pInputSection.flag() & llvm::ELF::SHF_HEX_GPREL) ||
      (pInputSection.kind() == LDFileFormat::LinkOnce) ||
      (pInputSection.kind() == LDFileFormat::Target)) {
    SectionData* sd = NULL;
    if (!m_psdata->hasSectionData()) {
      sd = IRBuilder::CreateSectionData(*m_psdata);
      m_psdata->setSectionData(sd);
    }
    sd = m_psdata->getSectionData();
    MoveSectionDataAndSort(*pInputSection.getSectionData(), *sd);
  } else {
    ObjectBuilder builder(pModule);
    builder.MergeSection(pInputFile, pInputSection);
  }
  return true;
}
コード例 #16
0
ファイル: DebugString.cpp プロジェクト: ChihMin/mclinker
//==========================
// DebugString
void DebugString::merge(LDSection& pSection) {
  // get the fragment contents
  llvm::StringRef strings;
  SectionData::iterator it, end = pSection.getSectionData()->end();
  for (it = pSection.getSectionData()->begin(); it != end; ++it) {
    if ((*it).getKind() == Fragment::Region) {
      RegionFragment* frag = llvm::cast<RegionFragment>(&(*it));
      strings = frag->getRegion().data();
    }
  }

  // get the debug strings and add them into merged string table
  const char* str = strings.data();
  const char* str_end = str + pSection.size();
  while (str < str_end) {
    size_t len = string_length(str);
    m_StringTable.insertString(llvm::StringRef(str, len));
    str = str + len + 1;
  }
}
//===----------------------------------------------------------------------===//
// HexagonGOTPLT
//===----------------------------------------------------------------------===//
HexagonGOTPLT::HexagonGOTPLT(LDSection& pSection)
  : HexagonGOT(pSection)
{
  // Create GOT0 entries
  reserve(HexagonGOTPLT0Num);

  // Skip GOT0 entries
  for (size_t i = 0; i < HexagonGOTPLT0Num; ++i) {
    consume();
  }
  pSection.setAlign(8);
}
コード例 #18
0
uint64_t ARMGNULDBackend::emitSectionData(const Output& pOutput,
                                          const LDSection& pSection,
                                          const MCLDInfo& pInfo,
                                          MemoryRegion& pRegion) const
{
  assert(pRegion.size() && "Size of MemoryRegion is zero!");

  ELFFileFormat* file_format = getOutputFormat(pOutput);

  if (&pSection == m_pAttributes) {
    // FIXME: Currently Emitting .ARM.attributes directly from the input file.
    const llvm::MCSectionData* sect_data = pSection.getSectionData();
    assert(sect_data &&
           "Emit .ARM.attribute failed, MCSectionData doesn't exist!");

    uint8_t* start =
              llvm::cast<MCRegionFragment>(
                     sect_data->getFragmentList().front()).getRegion().start();

    memcpy(pRegion.start(), start, pRegion.size());
    return pRegion.size();
  }

  if (&pSection == &(file_format->getPLT())) {
    assert(NULL != m_pPLT && "emitSectionData failed, m_pPLT is NULL!");
    uint64_t result = m_pPLT->emit(pRegion);
    return result;
  }

  if (&pSection == &(file_format->getGOT())) {
    assert(NULL != m_pGOT && "emitSectionData failed, m_pGOT is NULL!");
    uint64_t result = m_pGOT->emit(pRegion);
    return result;
  }

  llvm::report_fatal_error(llvm::Twine("Unable to emit section `") +
                           pSection.name() +
                           llvm::Twine("'.\n"));
  return 0x0;
}
uint64_t X86GNULDBackend::emitSectionData(const LDSection& pSection,
                                          MemoryRegion& pRegion) const
{
  assert(pRegion.size() && "Size of MemoryRegion is zero!");

  const ELFFileFormat* FileFormat = getOutputFormat();
  assert(FileFormat &&
         "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!");

  unsigned int EntrySize = 0;
  uint64_t RegionSize = 0;

  if (&pSection == &(FileFormat->getPLT())) {
    assert(m_pPLT && "emitSectionData failed, m_pPLT is NULL!");

    unsigned char* buffer = pRegion.getBuffer();

    m_pPLT->applyPLT0();
    m_pPLT->applyPLT1();
    X86PLT::iterator it = m_pPLT->begin();
    unsigned int plt0_size = llvm::cast<PLTEntryBase>((*it)).size();

    memcpy(buffer, llvm::cast<PLTEntryBase>((*it)).getValue(), plt0_size);
    RegionSize += plt0_size;
    ++it;

    PLTEntryBase* plt1 = 0;
    X86PLT::iterator ie = m_pPLT->end();
    while (it != ie) {
      plt1 = &(llvm::cast<PLTEntryBase>(*it));
      EntrySize = plt1->size();
      memcpy(buffer + RegionSize, plt1->getValue(), EntrySize);
      RegionSize += EntrySize;
      ++it;
    }
  }

  else if (&pSection == &(FileFormat->getGOT())) {
    RegionSize += emitGOTSectionData(pRegion);
  }

  else if (&pSection == &(FileFormat->getGOTPLT())) {
    RegionSize += emitGOTPLTSectionData(pRegion, FileFormat);
  }

  else {
    fatal(diag::unrecognized_output_sectoin)
            << pSection.name()
            << "*****@*****.**";
  }
  return RegionSize;
}
コード例 #20
0
uint64_t ELFObjectWriter::getSectEntrySize(const LDSection& pSection) const
{
  typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word;
  typedef typename ELFSizeTraits<SIZE>::Sym  ElfXX_Sym;
  typedef typename ELFSizeTraits<SIZE>::Rel  ElfXX_Rel;
  typedef typename ELFSizeTraits<SIZE>::Rela ElfXX_Rela;
  typedef typename ELFSizeTraits<SIZE>::Dyn  ElfXX_Dyn;

  if (llvm::ELF::SHT_DYNSYM == pSection.type() ||
      llvm::ELF::SHT_SYMTAB == pSection.type())
    return sizeof(ElfXX_Sym);
  if (llvm::ELF::SHT_REL == pSection.type())
    return sizeof(ElfXX_Rel);
  if (llvm::ELF::SHT_RELA == pSection.type())
    return sizeof(ElfXX_Rela);
  if (llvm::ELF::SHT_HASH     == pSection.type() ||
      llvm::ELF::SHT_GNU_HASH == pSection.type())
    return sizeof(ElfXX_Word);
  if (llvm::ELF::SHT_DYNAMIC == pSection.type())
    return sizeof(ElfXX_Dyn);
  return 0x0;
}
コード例 #21
0
/// group - group fragments and create islands when needed
/// @param pSectionData - the SectionData holds fragments need to be grouped
void BranchIslandFactory::group(Module& pModule) {
  /* FIXME: Currently only support relaxing .text section! */
  LDSection* text = pModule.getSection(".text");
  if (text != NULL && text->hasSectionData()) {
    SectionData& sd = *text->getSectionData();
    uint64_t group_end = m_MaxFwdBranchRange;
    for (SectionData::iterator it = sd.begin(), ie = sd.end(); it != ie; ++it) {
      if ((*it).getOffset() + (*it).size() > group_end) {
        Fragment* frag = (*it).getPrevNode();
        while (frag != NULL && frag->getKind() == Fragment::Alignment) {
          frag = frag->getPrevNode();
        }
        if (frag != NULL) {
          produce(*frag);
          group_end = (*it).getOffset() + m_MaxFwdBranchRange;
        }
      }
    }
    if (getIslands(sd.back()).first == NULL)
      produce(sd.back());
  }
}
コード例 #22
0
void HexagonRelocator::scanLocalReloc(Relocation& pReloc,
                                      IRBuilder& pBuilder,
                                      Module& pModule,
                                      LDSection& pSection) {
  // rsym - The relocation target symbol
  ResolveInfo* rsym = pReloc.symInfo();

  switch (pReloc.type()) {
    case llvm::ELF::R_HEX_LO16:
    case llvm::ELF::R_HEX_HI16:
    case llvm::ELF::R_HEX_16:
    case llvm::ELF::R_HEX_8:
    case llvm::ELF::R_HEX_32_6_X:
    case llvm::ELF::R_HEX_16_X:
    case llvm::ELF::R_HEX_12_X:
    case llvm::ELF::R_HEX_11_X:
    case llvm::ELF::R_HEX_10_X:
    case llvm::ELF::R_HEX_9_X:
    case llvm::ELF::R_HEX_8_X:
    case llvm::ELF::R_HEX_7_X:
    case llvm::ELF::R_HEX_6_X:
      assert(!(rsym->reserved() & ReserveRel) &&
             "Cannot apply this relocation for read only section");
      return;

    case llvm::ELF::R_HEX_32:
      // If buiding PIC object (shared library or PIC executable),
      // a dynamic relocations with RELATIVE type to this location is needed.
      // Reserve an entry in .rel.dyn
      if (config().isCodeIndep()) {
        Relocation& reloc = helper_DynRel_init(rsym,
                                               *pReloc.targetRef().frag(),
                                               pReloc.targetRef().offset(),
                                               llvm::ELF::R_HEX_RELATIVE,
                                               *this);
        // we need to set up the relocation addend at apply relocation, record
        // the
        // relocation
        getRelRelMap().record(pReloc, reloc);

        // set Rel bit
        rsym->setReserved(rsym->reserved() | ReserveRel);
        getTarget().checkAndSetHasTextRel(*pSection.getLink());
      }
      return;

    default:
      return;
  }
}
コード例 #23
0
void Relocator::issueUndefRef(Relocation& pReloc,
                              LDSection& pSection,
                              Input& pInput)
{
  FragmentRef::Offset undef_sym_pos = pReloc.targetRef().offset();
  std::string sect_name(pSection.name());
  sect_name = sect_name.substr(sect_name.find('.', /*pos=*/1));  // Drop .rel(a) prefix

  std::string reloc_sym(pReloc.symInfo()->name());
  if (reloc_sym.substr(0, 2) == "_Z")
    reloc_sym = demangleSymbol(reloc_sym);

  std::stringstream ss;
  ss << "0x" << std::hex << undef_sym_pos;
  std::string undef_sym_pos_hex(ss.str());

  if (sect_name.substr(0, 5) != ".text") {
    // Function name is only valid for text section
    fatal(diag::undefined_reference) << reloc_sym
                                     << pInput.path()
                                     << sect_name
                                     << undef_sym_pos_hex;
    return;
  }

  std::string caller_file_name;
  std::string caller_func_name;
  for (LDContext::sym_iterator i = pInput.context()->symTabBegin(),
       e = pInput.context()->symTabEnd(); i != e; ++i) {
    LDSymbol& sym = **i;
    if (sym.resolveInfo()->type() == ResolveInfo::File)
      caller_file_name = sym.resolveInfo()->name();

    if (sym.resolveInfo()->type() == ResolveInfo::Function &&
        sym.value() <= undef_sym_pos &&
        sym.value() + sym.size() > undef_sym_pos) {
      caller_func_name = sym.name();
      break;
    }
  }

  if (caller_func_name.substr(0, 2) == "_Z")
    caller_func_name = demangleSymbol(caller_func_name);

  fatal(diag::undefined_reference_text) << reloc_sym
                                        << pInput.path()
                                        << caller_file_name
                                        << caller_func_name;
}
コード例 #24
0
ファイル: MipsAbiFlags.cpp プロジェクト: ChihMin/mclinker
bool MipsAbiFlags::fillBySection(const Input& pInput, const LDSection& pSection,
                                 MipsAbiFlags& mipsAbi) {
  assert(pSection.type() == llvm::ELF::SHT_MIPS_ABIFLAGS &&
         "Unexpected section type");

  if (pSection.size() != size()) {
    error(diag::error_Mips_abiflags_invalid_size) << pInput.name();
    return false;
  }

  const SectionData* secData = pSection.getSectionData();
  if (secData->size() != 2 || !llvm::isa<RegionFragment>(secData->front())) {
    error(diag::error_Mips_abiflags_invalid_size) << pInput.name();
    return false;
  }

  const auto& frag = llvm::cast<RegionFragment>(secData->front());
  auto* data =
      reinterpret_cast<const ElfMipsAbiFlags*>(frag.getRegion().data());
  if (data->version != 0) {
    error(diag::error_Mips_abiflags_invalid_version) << int(data->version)
                                                     << pInput.name();
    return false;
  }

  mipsAbi.m_IsaLevel = data->isa_level;
  mipsAbi.m_IsaRev = data->isa_rev;
  mipsAbi.m_GprSize = data->gpr_size;
  mipsAbi.m_Cpr1Size = data->cpr1_size;
  mipsAbi.m_Cpr2Size = data->cpr2_size;
  mipsAbi.m_FpAbi = data->fp_abi;
  mipsAbi.m_IsaExt = data->isa_ext;
  mipsAbi.m_Ases = data->ases;
  mipsAbi.m_Flags1 = data->flags1;
  return true;
}
コード例 #25
0
ファイル: ELFDynamic.cpp プロジェクト: aurorarom/JsonUtil
/// emit
void ELFDynamic::emit(const LDSection& pSection, MemoryRegion& pRegion) const
{
  if (pRegion.size() < pSection.size()) {
    llvm::report_fatal_error(llvm::Twine("the given memory is smaller") +
                             llvm::Twine(" than the section's demaind.\n"));
  }

  uint8_t* address = (uint8_t*)pRegion.begin();
  EntryListType::const_iterator entry, entryEnd = m_NeedList.end();
  for (entry = m_NeedList.begin(); entry != entryEnd; ++entry)
    address += (*entry)->emit(address);

  entryEnd = m_EntryList.end();
  for (entry = m_EntryList.begin(); entry != entryEnd; ++entry)
    address += (*entry)->emit(address);
}
コード例 #26
0
ファイル: MipsLDBackend.cpp プロジェクト: yodalee/mclinker
uint64_t MipsGNULDBackend::emitSectionData(const LDSection& pSection,
                                           MemoryRegion& pRegion) const {
  assert(pRegion.size() && "Size of MemoryRegion is zero!");

  const ELFFileFormat* file_format = getOutputFormat();

  if (file_format->hasGOT() && (&pSection == &(file_format->getGOT()))) {
    return m_pGOT->emit(pRegion);
  }

  if (file_format->hasPLT() && (&pSection == &(file_format->getPLT()))) {
    return m_pPLT->emit(pRegion);
  }

  if (file_format->hasGOTPLT() && (&pSection == &(file_format->getGOTPLT()))) {
    return m_pGOTPLT->emit(pRegion);
  }

  fatal(diag::unrecognized_output_sectoin) << pSection.name()
                                           << "*****@*****.**";
  return 0;
}
コード例 #27
0
/// emitSectionData
void
ELFObjectWriter::emitSectionData(const LDSection& pSection,
                                 MemoryRegion& pRegion) const
{
  const SectionData* sd = NULL;
  switch (pSection.kind()) {
    case LDFileFormat::Relocation:
      assert(pSection.hasRelocData());
      return;
    case LDFileFormat::EhFrame:
      assert(pSection.hasEhFrame());
      sd = pSection.getEhFrame()->getSectionData();
      break;
    default:
      assert(pSection.hasSectionData());
      sd = pSection.getSectionData();
      break;
  }
  emitSectionData(*sd, pRegion);
}
コード例 #28
0
/// getSectLink - compute ElfXX_Shdr::sh_link
uint64_t ELFObjectWriter::getSectLink(const LDSection& pSection,
                                      const LinkerConfig& pConfig) const
{
  if (llvm::ELF::SHT_SYMTAB == pSection.type())
    return target().getOutputFormat()->getStrTab().index();
  if (llvm::ELF::SHT_DYNSYM == pSection.type())
    return target().getOutputFormat()->getDynStrTab().index();
  if (llvm::ELF::SHT_DYNAMIC == pSection.type())
    return target().getOutputFormat()->getDynStrTab().index();
  if (llvm::ELF::SHT_HASH     == pSection.type() ||
      llvm::ELF::SHT_GNU_HASH == pSection.type())
    return target().getOutputFormat()->getDynSymTab().index();
  if (llvm::ELF::SHT_REL == pSection.type() ||
      llvm::ELF::SHT_RELA == pSection.type()) {
    if (LinkerConfig::Object == pConfig.codeGenType())
      return target().getOutputFormat()->getSymTab().index();
    else
      return target().getOutputFormat()->getDynSymTab().index();
  }
  // FIXME: currently we link ARM_EXIDX section to output text section here
  if (llvm::ELF::SHT_ARM_EXIDX == pSection.type())
    return target().getOutputFormat()->getText().index();
  return llvm::ELF::SHN_UNDEF;
}
コード例 #29
0
ファイル: MipsLDBackend.cpp プロジェクト: yodalee/mclinker
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;
}
コード例 #30
0
void IdenticalCodeFolding::foldIdenticalCode() {
  // 1. Find folding candidates.
  FoldingCandidates candidate_list;
  findCandidates(candidate_list);

  // 2. Initialize constant section content
  for (size_t i = 0; i < candidate_list.size(); ++i) {
    candidate_list[i].initConstantContent(m_Backend, m_KeptSections);
  }

  // 3. Find identical code until convergence
  bool converged = false;
  size_t iterations = 0;
  while (!converged && (iterations < m_Config.options().getICFIterations())) {
    converged = matchCandidates(candidate_list);
    ++iterations;
  }
  if (m_Config.options().printICFSections()) {
    debug(diag::debug_icf_iterations) << iterations;
  }

  // 4. Fold the identical code
  typedef std::set<Input*> FoldedObjects;
  FoldedObjects folded_objs;
  KeptSections::iterator kept, keptEnd = m_KeptSections.end();
  size_t index = 0;
  for (kept = m_KeptSections.begin(); kept != keptEnd; ++kept, ++index) {
    LDSection* sect = (*kept).first;
    Input* obj = (*kept).second.first;
    size_t kept_index = (*kept).second.second;
    if (index != kept_index) {
      sect->setKind(LDFileFormat::Folded);
      folded_objs.insert(obj);

      if (m_Config.options().printICFSections()) {
        KeptSections::iterator it = m_KeptSections.begin() + kept_index;
        LDSection* kept_sect = (*it).first;
        Input* kept_obj = (*it).second.first;
        debug(diag::debug_icf_folded_section) << sect->name() << obj->name()
                                              << kept_sect->name()
                                              << kept_obj->name();
      }
    }
  }

  // Adjust the fragment reference of the folded symbols.
  FoldedObjects::iterator fobj, fobjEnd = folded_objs.end();
  for (fobj = folded_objs.begin(); fobj != fobjEnd; ++fobj) {
    LDContext::sym_iterator sym, symEnd = (*fobj)->context()->symTabEnd();
    for (sym = (*fobj)->context()->symTabBegin(); sym != symEnd; ++sym) {
      if ((*sym)->hasFragRef() && ((*sym)->type() == ResolveInfo::Function)) {
        LDSymbol* out_sym = (*sym)->resolveInfo()->outSymbol();
        FragmentRef* frag_ref = out_sym->fragRef();
        LDSection* sect = &(frag_ref->frag()->getParent()->getSection());
        if (sect->kind() == LDFileFormat::Folded) {
          size_t kept_index = m_KeptSections[sect].second;
          LDSection* kept_sect = (*(m_KeptSections.begin() + kept_index)).first;
          frag_ref->assign(kept_sect->getSectionData()->front(),
                           frag_ref->offset());
        }
      }
    }  // for each symbol
  }    // for each folded object
}