uint64_t MipsGOTPLT::emit(MemoryRegion& pRegion) {
  uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin());

  uint64_t result = 0;
  for (iterator it = begin(), ie = end(); it != ie; ++it, ++buffer) {
    GOTPLTEntry* got = &(llvm::cast<GOTPLTEntry>((*it)));
    *buffer = static_cast<uint32_t>(got->getValue());
    result += got->size();
  }
  return result;
}
uint64_t AArch64GOT::emit(MemoryRegion& pRegion) {
  uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.begin());

  AArch64GOTEntry* got = NULL;
  uint64_t result = 0x0;
  for (iterator it = begin(), ie = end(); it != ie; ++it, ++buffer) {
    got = &(llvm::cast<AArch64GOTEntry>((*it)));
    *buffer = static_cast<uint64_t>(got->getValue());
    result += AArch64GOTEntry::EntrySize;
  }
  return result;
}
/// computePCBegin - return the address of FDE's pc
uint32_t EhFrameHdr::computePCBegin(const EhFrame::FDE& pFDE,
                                    const MemoryRegion& pEhFrameRegion) {
  uint8_t fde_encoding = pFDE.getCIE().getFDEEncode();
  unsigned int eh_value = fde_encoding & 0x7;

  // check the size to read in
  if (eh_value == llvm::dwarf::DW_EH_PE_absptr) {
    eh_value = llvm::dwarf::DW_EH_PE_udata4;
  }

  size_t pc_size = 0x0;
  switch (eh_value) {
    case llvm::dwarf::DW_EH_PE_udata2:
      pc_size = 2;
      break;
    case llvm::dwarf::DW_EH_PE_udata4:
      pc_size = 4;
      break;
    case llvm::dwarf::DW_EH_PE_udata8:
      pc_size = 8;
      break;
    default:
      // TODO
      break;
  }

  SizeTraits<32>::Address pc = 0x0;
  const uint8_t* offset = (const uint8_t*)pEhFrameRegion.begin() +
                          pFDE.getOffset() + EhFrame::getDataStartOffset<32>();
  std::memcpy(&pc, offset, pc_size);

  // adjust the signed value
  bool is_signed = (fde_encoding & llvm::dwarf::DW_EH_PE_signed) != 0x0;
  if (llvm::dwarf::DW_EH_PE_udata2 == eh_value && is_signed)
    pc = (pc ^ 0x8000) - 0x8000;

  // handle eh application
  switch (fde_encoding & 0x70) {
    case llvm::dwarf::DW_EH_PE_absptr:
      break;
    case llvm::dwarf::DW_EH_PE_pcrel:
      pc += m_EhFrame.addr() + pFDE.getOffset() +
            EhFrame::getDataStartOffset<32>();
      break;
    case llvm::dwarf::DW_EH_PE_datarel:
      // TODO
      break;
    default:
      // TODO
      break;
  }
  return pc;
}
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.begin();

    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;
}
Exemple #5
0
uint64_t MipsAbiFlags::emit(const MipsAbiFlags& pInfo, MemoryRegion& pRegion) {
  auto* buf = reinterpret_cast<ElfMipsAbiFlags*>(pRegion.begin());
  buf->version = 0;
  buf->isa_level = pInfo.m_IsaLevel;
  buf->isa_rev = pInfo.m_IsaRev;
  buf->gpr_size = pInfo.m_GprSize;
  buf->cpr1_size = pInfo.m_Cpr1Size;
  buf->cpr2_size = pInfo.m_Cpr2Size;
  buf->fp_abi = pInfo.m_FpAbi;
  buf->isa_ext = pInfo.m_IsaExt;
  buf->ases = pInfo.m_Ases;
  buf->flags1 = pInfo.m_Flags1;
  buf->flags2 = 0;
  return size();
}
Exemple #6
0
/// 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);
}
Exemple #7
0
uint64_t MipsPLT::emit(MemoryRegion& pRegion) {
  uint64_t result = 0x0;
  iterator it = begin();

  unsigned char* buffer = pRegion.begin();
  memcpy(buffer, llvm::cast<MipsPLT0>((*it)).getValue(), MipsPLT0::EntrySize);
  result += MipsPLT0::EntrySize;
  ++it;

  MipsPLTA* plta = 0;
  for (iterator ie = end(); it != ie; ++it) {
    plta = &(llvm::cast<MipsPLTA>(*it));
    memcpy(buffer + result, plta->getValue(), MipsPLTA::EntrySize);
    result += MipsPLTA::EntrySize;
  }
  return result;
}
uint64_t HexagonLDBackend::emitGOTSectionData(MemoryRegion& pRegion) const {
  assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!");

  uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin());

  HexagonGOTEntry* got = 0;
  unsigned int EntrySize = HexagonGOTEntry::EntrySize;
  uint64_t RegionSize = 0;

  for (HexagonGOT::iterator it = m_pGOT->begin(), ie = m_pGOT->end(); it != ie;
       ++it, ++buffer) {
    got = &(llvm::cast<HexagonGOTEntry>((*it)));
    *buffer = static_cast<uint32_t>(got->getValue());
    RegionSize += EntrySize;
  }

  return RegionSize;
}
Exemple #9
0
SecureVector<byte> rfc3394_keyunwrap(const MemoryRegion<byte>& key,
                                     const SymmetricKey& kek,
                                     Algorithm_Factory& af)
   {
   if(key.size() < 16 || key.size() % 8 != 0)
      throw std::invalid_argument("Bad input key size for NIST key unwrap");

   std::auto_ptr<BlockCipher> aes(make_aes(kek.length(), af));
   aes->set_key(kek);

   const size_t n = (key.size() - 8) / 8;

   SecureVector<byte> R(n * 8);
   SecureVector<byte> A(16);

   for(size_t i = 0; i != 8; ++i)
      A[i] = key[i];

   copy_mem(&R[0], key.begin() + 8, key.size() - 8);

   for(size_t j = 0; j <= 5; ++j)
      {
      for(size_t i = n; i != 0; --i)
         {
         const u32bit t = (5 - j) * n + i;

         byte t_buf[4] = { 0 };
         store_be(t, t_buf);

         xor_buf(&A[4], &t_buf[0], 4);

         copy_mem(&A[8], &R[8*(i-1)], 8);

         aes->decrypt(&A[0]);

         copy_mem(&R[8*(i-1)], &A[8], 8);
         }
      }

   if(load_be<u64bit>(&A[0], 0) != 0xA6A6A6A6A6A6A6A6)
      throw Integrity_Failure("NIST key unwrap failed");

   return R;
   }
Exemple #10
0
size_t ELFAttribute::emit(MemoryRegion &pRegion) const
{
  // ARM [ABI-addenda], 2.2.3
  uint64_t total_size = 0;

  // Write format-version.
  char* buffer = reinterpret_cast<char*>(pRegion.begin());
  buffer[0] = FormatVersion;
  total_size += FormatVersionFieldSize;

  for (llvm::SmallVectorImpl<Subsection*>::const_iterator
          subsec_it = m_Subsections.begin(), subsec_end = m_Subsections.end();
       subsec_it != subsec_end; ++subsec_it) {
    // Write out subsection.
    total_size += (*subsec_it)->emit(buffer + total_size);
  }

  return total_size;
}
Exemple #11
0
SecureVector<byte> rfc3394_keywrap(const MemoryRegion<byte>& key,
                                   const SymmetricKey& kek,
                                   Algorithm_Factory& af)
   {
   if(key.size() % 8 != 0)
      throw std::invalid_argument("Bad input key size for NIST key wrap");

   std::auto_ptr<BlockCipher> aes(make_aes(kek.length(), af));
   aes->set_key(kek);

   const size_t n = key.size() / 8;

   SecureVector<byte> R((n + 1) * 8);
   SecureVector<byte> A(16);

   for(size_t i = 0; i != 8; ++i)
      A[i] = 0xA6;

   copy_mem(&R[8], key.begin(), key.size());

   for(size_t j = 0; j <= 5; ++j)
      {
      for(size_t i = 1; i <= n; ++i)
         {
         const u32bit t = (n * j) + i;

         copy_mem(&A[8], &R[8*i], 8);

         aes->encrypt(&A[0]);
         copy_mem(&R[8*i], &A[8], 8);

         byte t_buf[4] = { 0 };
         store_be(t, t_buf);
         xor_buf(&A[4], &t_buf[0], 4);
         }
      }

   copy_mem(&R[0], &A[0], 8);

   return R;
   }
uint64_t X86_64GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion,
						   const ELFFileFormat* FileFormat) const
{
  assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!");
  m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr());
  m_pGOTPLT->applyAllGOTPLT(*m_pPLT);

  uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.begin());

  X86_64GOTEntry* got = 0;
  unsigned int EntrySize = X86_64GOTEntry::EntrySize;
  uint64_t RegionSize = 0;

  for (X86_64GOTPLT::iterator it = m_pGOTPLT->begin(),
       ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) {
    got = &(llvm::cast<X86_64GOTEntry>((*it)));
    *buffer = static_cast<uint64_t>(got->getValue());
    RegionSize += EntrySize;
  }

  return RegionSize;
}
Exemple #13
0
/*
* Process a full message at once
*/
void Pipe::process_msg(const MemoryRegion<byte>& input)
   {
   process_msg(input.begin(), input.size());
   }
uint64_t HexagonLDBackend::emitSectionData(const LDSection& pSection,
                                           MemoryRegion& pRegion) const
{
  if (!pRegion.size())
    return 0;

  const ELFFileFormat* FileFormat = getOutputFormat();
  unsigned int EntrySize = 0;
  uint64_t RegionSize = 0;

  if ((LinkerConfig::Object != config().codeGenType()) &&
      (!config().isCodeStatic())) {
    if (FileFormat->hasPLT() && (&pSection == &(FileFormat->getPLT()))) {

      unsigned char* buffer = pRegion.begin();

      m_pPLT->applyPLT0();
      m_pPLT->applyPLT1();
      HexagonPLT::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;
      HexagonPLT::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;
      }
      return RegionSize;
    }
    else if (FileFormat->hasGOT() && (&pSection == &(FileFormat->getGOT()))) {
      RegionSize += emitGOTSectionData(pRegion);
      return RegionSize;
    }
    else if (FileFormat->hasGOTPLT() &&
             (&pSection == &(FileFormat->getGOTPLT()))) {
      RegionSize += emitGOTPLTSectionData(pRegion, FileFormat);
      return RegionSize;
    }
  }

  const SectionData* sect_data = pSection.getSectionData();
  SectionData::const_iterator frag_iter, frag_end = sect_data->end();
  uint8_t* out_offset = pRegion.begin();
  for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) {
    size_t size = frag_iter->size();
    switch(frag_iter->getKind()) {
      case Fragment::Fillment: {
        const FillFragment& fill_frag =
          llvm::cast<FillFragment>(*frag_iter);
        if (0 == fill_frag.getValueSize()) {
          // virtual fillment, ignore it.
          break;
        }
        memset(out_offset, fill_frag.getValue(), fill_frag.size());
        break;
      }
      case Fragment::Region: {
        const RegionFragment& region_frag =
          llvm::cast<RegionFragment>(*frag_iter);
        const char* start = region_frag.getRegion().begin();
        memcpy(out_offset, start, size);
        break;
      }
      case Fragment::Alignment: {
        const AlignFragment& align_frag = llvm::cast<AlignFragment>(*frag_iter);
        uint64_t count = size / align_frag.getValueSize();
        switch (align_frag.getValueSize()) {
          case 1u:
            std::memset(out_offset, align_frag.getValue(), count);
            break;
          default:
            llvm::report_fatal_error(
              "unsupported value size for align fragment emission yet.\n");
            break;
        } // end switch
        break;
      }
      case Fragment::Null: {
        assert(0x0 == size);
        break;
      }
      default:
        llvm::report_fatal_error("unsupported fragment type.\n");
        break;
    } // end switch
    out_offset += size;
  } // end for

  return pRegion.size();
}
uint64_t ARMGNULDBackend::emitSectionData(const LDSection& pSection,
                                          MemoryRegion& pRegion) const
{
  assert(pRegion.size() && "Size of MemoryRegion is zero!");

  const ELFFileFormat* file_format = getOutputFormat();

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

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

  if (&pSection == m_pAttributes) {
    return attribute().emit(pRegion);
  }

  // FIXME: Currently Emitting .ARM.attributes, .ARM.exidx, and .ARM.extab
  // directly from the input file.
  const SectionData* sect_data = pSection.getSectionData();
  SectionData::const_iterator frag_iter, frag_end = sect_data->end();
  uint8_t* out_offset = pRegion.begin();
  for (frag_iter = sect_data->begin(); frag_iter != frag_end; ++frag_iter) {
    size_t size = frag_iter->size();
    switch(frag_iter->getKind()) {
      case Fragment::Fillment: {
        const FillFragment& fill_frag =
          llvm::cast<FillFragment>(*frag_iter);
        if (0 == fill_frag.getValueSize()) {
          // virtual fillment, ignore it.
          break;
        }

        memset(out_offset, fill_frag.getValue(), fill_frag.size());
        break;
      }
      case Fragment::Region: {
        const RegionFragment& region_frag =
          llvm::cast<RegionFragment>(*frag_iter);
        const char* start = region_frag.getRegion().begin();
        memcpy(out_offset, start, size);
        break;
      }
      case Fragment::Alignment: {
        const AlignFragment& align_frag = llvm::cast<AlignFragment>(*frag_iter);
        uint64_t count = size / align_frag.getValueSize();
        switch (align_frag.getValueSize()) {
          case 1u:
            std::memset(out_offset, align_frag.getValue(), count);
            break;
          default:
            llvm::report_fatal_error(
              "unsupported value size for align fragment emission yet.\n");
            break;
        } // end switch
        break;
      }
      case Fragment::Null: {
        assert(0x0 == size);
        break;
      }
      default:
        llvm::report_fatal_error("unsupported fragment type.\n");
        break;
    } // end switch
    out_offset += size;
  } // end for
  return pRegion.size();
}