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;
}
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;
}
Ejemplo n.º 3
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;
  }
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
0
//==========================
// 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;
  }
}
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
bool ELFAttribute::merge(const Input &pInput, LDSection &pInputAttrSectHdr)
{
  // Skip corrupt subsection
  if (pInputAttrSectHdr.size() < MinimalELFAttributeSectionSize)
    return true;

  // Obtain the region containing the attribute data. Expect exactly one
  // RegionFragment in the section data.
  const SectionData* sect_data = pInputAttrSectHdr.getSectionData();

  // FIXME: Why is 2?
  if ((sect_data->size() != 2) ||
      (!llvm::isa<RegionFragment>(sect_data->front()))) {
    return true;
  }

  const RegionFragment& region_frag =
      llvm::cast<RegionFragment>(sect_data->front());

  llvm::StringRef region = region_frag.getRegion();

  // Parse the ELF attribute section header. ARM [ABI-addenda], 2.2.3.
  //
  // <format-version: ‘A’>
  // [ <uint32: subsection-length> NTBS: vendor-name
  //   <bytes: vendor-data>
  // ]*
  const char *attribute_data = region.begin();

  // format-version
  if (attribute_data[0] != FormatVersion) {
    warning(diag::warn_unsupported_attribute_section_format)
        << pInput.name() << attribute_data[0];
    return true;
  }

  size_t subsection_offset = FormatVersionFieldSize;

  // Iterate all subsections containing in this attribute section.
  do {
    const char *subsection_data = region.begin() + subsection_offset;

    // subsection-length
    uint32_t subsection_length =
        *reinterpret_cast<const uint32_t*>(subsection_data);

    if(llvm::sys::IsLittleEndianHost != m_Config.targets().isLittleEndian())
      bswap32(subsection_length);

    // vendor-name
    const char* vendor_name = subsection_data + SubsectionLengthFieldSize;
    const size_t vendor_name_length = ::strlen(vendor_name) + 1 /* '\0' */;

    // Check the length.
    if ((vendor_name_length <= 1) ||
        (subsection_length <= (SubsectionLengthFieldSize + vendor_name_length)))
      return true;

    // Select the attribute subsection.
    Subsection *subsection = getSubsection(vendor_name);

    // Only process the subsections whose vendor can be recognized.
    if (subsection == NULL) {
      warning(diag::warn_unrecognized_vendor_subsection)
          << vendor_name << pInput.name();
    } else {
      // vendor-data
      size_t vendor_data_offset = subsection_offset +
                                  SubsectionLengthFieldSize +
                                  vendor_name_length;
      size_t vendor_data_size = subsection_length - SubsectionLengthFieldSize -
                                vendor_name_length;

      ConstAddress vendor_data =
          reinterpret_cast<ConstAddress>(region.begin()) + vendor_data_offset;

      // Merge the vendor data in the subsection.
      if (!subsection->merge(pInput, vendor_data, vendor_data_size))
        return false;
    }

    subsection_offset += subsection_length;
  } while ((subsection_offset + SubsectionLengthFieldSize) < pInputAttrSectHdr.size());

  return true;
}