Ejemplo n.º 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;
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
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);
}
Ejemplo n.º 4
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;
  }
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
void ARMGNULDBackend::scanInputExceptionSections(Module& pModule,
                                                 Input& pInput) {
  std::unique_ptr<ARMInputExMap> exMap(new ARMInputExMap());

  // Scan the input and collect all related sections.
  LDContext* ctx = pInput.context();
  for (LDContext::sect_iterator it = ctx->sectBegin(),
                                end = ctx->sectEnd(); it != end; ++it) {
    LDSection* sect = *it;
    llvm::StringRef name(sect->name());

    if (name.startswith(".ARM.exidx")) {
      ARMExSectionTuple* exTuple = exMap->getOrCreateByExSection(name);
      exTuple->setExIdxSection(sect);
      exTuple->setTextSection(sect->getLink());
    } else if (name.startswith(".ARM.extab")) {
      ARMExSectionTuple* exTuple = exMap->getOrCreateByExSection(name);
      exTuple->setExTabSection(sect);
    } else if (name.startswith(".rel.ARM.exidx")) {
      ARMExSectionTuple* exTuple = exMap->getOrCreateByRelExSection(name);
      exTuple->setRelExIdxSection(sect);
    } else if (name.startswith(".rel.ARM.extab")) {
      ARMExSectionTuple* exTuple = exMap->getOrCreateByRelExSection(name);
      exTuple->setRelExIdxSection(sect);
    }
  }

  // Remove the invalid exception tuples and convert LDSection to RegionFragment
  // or RelocData.
  ARMInputExMap::iterator it = exMap->begin();
  ARMInputExMap::iterator end = exMap->end();
  while (it != end) {
    ARMExSectionTuple* exTuple = it->second.get();
    LDSection* const text = exTuple->getTextSection();
    LDSection* const exIdx = exTuple->getExIdxSection();
    LDSection* const exTab = exTuple->getExTabSection();
    LDSection* const relExIdx = exTuple->getRelExIdxSection();
    LDSection* const relExTab = exTuple->getRelExTabSection();

    // Check the .ARM.exidx section.
    if (!exIdx) {
      if (exTab) {
        fatal(diag::eh_missing_exidx_section) << exTab->name() << pInput.name();
      } else if (relExIdx) {
        fatal(diag::eh_missing_exidx_section) << relExIdx->name()
                                              << pInput.name();
      } else if (relExTab) {
        fatal(diag::eh_missing_exidx_section) << relExTab->name()
                                              << pInput.name();
      } else {
        llvm_unreachable("unexpected bad exception tuple");
      }
    }

    // Check the text section.
    if (!text) {
      fatal(diag::eh_missing_text_section) << exIdx->name() << pInput.name();
    }

    // Ignore the exception section if the text section is ignored.
    if ((text->kind() == LDFileFormat::Ignore) ||
        (text->kind() == LDFileFormat::Folded)) {
      // Set the related exception sections as LDFileFormat::Ignore.
      exIdx->setKind(LDFileFormat::Ignore);
      if (exTab) {
        exTab->setKind(LDFileFormat::Ignore);
      }
      // Remove this tuple from the input exception map.
      exMap->erase(it++);
      continue;
    }

    // Get RegionFragment from ".text", ".ARM.exidx", and ".ARM.extab" sections.
    RegionFragment* textFrag = findRegionFragment(*text);
    RegionFragment* exIdxFrag = findRegionFragment(*exIdx);
    RegionFragment* exTabFrag = exTab ? findRegionFragment(*exTab) : NULL;

    exTuple->setTextFragment(textFrag);
    exTuple->setExIdxFragment(exIdxFrag);
    exTuple->setExTabFragment(exTabFrag);

    // Get the RelocData from ".rel.ARM.exidx" and ".rel.ARM.extab" sections.
    RelocData* exIdxRD = relExIdx ? relExIdx->getRelocData() : NULL;
    RelocData* exTabRD = relExTab ? relExTab->getRelocData() : NULL;

    exTuple->setExIdxRelocData(exIdxRD);
    exTuple->setExTabRelocData(exTabRD);

    // If there is no region fragment in the .ARM.extab section, then we can
    // skip this tuple.
    if (!exIdxFrag) {
      exMap->erase(it++);
      continue;
    }

    // TODO: Sort the RelocData w.r.t. the fixup offset.

    // Check next tuple
    ++it;
  }

  // Add input map
  m_ExData.addInputMap(&pInput, std::move(exMap));
}
Ejemplo n.º 7
0
void HexagonRelocator::scanGlobalReloc(Relocation& pReloc,
                                       IRBuilder& pBuilder,
                                       Module& pModule,
                                       LDSection& pSection) {
  // rsym - The relocation target symbol
  ResolveInfo* rsym = pReloc.symInfo();
  HexagonLDBackend& ld_backend = getTarget();

  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 (ld_backend.symbolNeedsPLT(*rsym)) {
        // create PLT for this symbol if it does not have.
        if (!(rsym->reserved() & ReservePLT)) {
          helper_PLT_init(pReloc, *this);
          rsym->setReserved(rsym->reserved() | ReservePLT);
        }
      }

      if (ld_backend.symbolNeedsDynRel(
              *rsym, (rsym->reserved() & ReservePLT), true)) {
        if (ld_backend.symbolNeedsCopyReloc(pReloc, *rsym)) {
          LDSymbol& cpy_sym =
              defineSymbolforCopyReloc(pBuilder, *rsym, ld_backend);
          addCopyReloc(*cpy_sym.resolveInfo(), ld_backend);
        } else {
          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);
          rsym->setReserved(rsym->reserved() | ReserveRel);
          ld_backend.checkAndSetHasTextRel(*pSection.getLink());
        }
      }
      return;

    case llvm::ELF::R_HEX_GOTREL_LO16:
    case llvm::ELF::R_HEX_GOTREL_HI16:
    case llvm::ELF::R_HEX_GOTREL_32:
    case llvm::ELF::R_HEX_GOTREL_32_6_X:
    case llvm::ELF::R_HEX_GOTREL_16_X:
    case llvm::ELF::R_HEX_GOTREL_11_X:
      // This assumes that GOT exists
      return;

    case llvm::ELF::R_HEX_GOT_LO16:
    case llvm::ELF::R_HEX_GOT_HI16:
    case llvm::ELF::R_HEX_GOT_32:
    case llvm::ELF::R_HEX_GOT_16:
    case llvm::ELF::R_HEX_GOT_32_6_X:
    case llvm::ELF::R_HEX_GOT_16_X:
    case llvm::ELF::R_HEX_GOT_11_X:
      // Symbol needs GOT entry, reserve entry in .got
      // return if we already create GOT for this symbol
      if (rsym->reserved() & ReserveGOT)
        return;
      // If the GOT is used in statically linked binaries,
      // the GOT entry is enough and no relocation is needed.
      if (config().isCodeStatic())
        helper_GOT_init(pReloc, false, *this);
      else
        helper_GOT_init(pReloc, true, *this);
      // set GOT bit
      rsym->setReserved(rsym->reserved() | ReserveGOT);
      return;

    case llvm::ELF::R_HEX_B22_PCREL:
    case llvm::ELF::R_HEX_B15_PCREL:
    case llvm::ELF::R_HEX_B7_PCREL:
    case llvm::ELF::R_HEX_B13_PCREL:
    case llvm::ELF::R_HEX_B9_PCREL:
    case llvm::ELF::R_HEX_B32_PCREL_X:
    case llvm::ELF::R_HEX_B22_PCREL_X:
    case llvm::ELF::R_HEX_B15_PCREL_X:
    case llvm::ELF::R_HEX_B13_PCREL_X:
    case llvm::ELF::R_HEX_B9_PCREL_X:
    case llvm::ELF::R_HEX_B7_PCREL_X:
    case llvm::ELF::R_HEX_32_PCREL:
    case llvm::ELF::R_HEX_6_PCREL_X:
    case llvm::ELF::R_HEX_PLT_B22_PCREL:
      if (rsym->reserved() & ReservePLT)
        return;
      if (ld_backend.symbolNeedsPLT(*rsym) ||
          pReloc.type() == llvm::ELF::R_HEX_PLT_B22_PCREL) {
        helper_PLT_init(pReloc, *this);
        rsym->setReserved(rsym->reserved() | ReservePLT);
      }
      return;

    default:
      break;
  }  // end of switch
}