Ejemplo n.º 1
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!");
}
Ejemplo n.º 2
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;
}
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;
}
Ejemplo n.º 4
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.º 5
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
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;
}