예제 #1
0
void ELFObjectWriter::writeELFHeader(const LinkerConfig& pConfig,
                                     const Module& pModule,
                                     MemoryArea& pOutput) const
{
  typedef typename ELFSizeTraits<SIZE>::Ehdr ElfXX_Ehdr;
  typedef typename ELFSizeTraits<SIZE>::Shdr ElfXX_Shdr;
  typedef typename ELFSizeTraits<SIZE>::Phdr ElfXX_Phdr;

  // ELF header must start from 0x0
  MemoryRegion *region = pOutput.request(0, sizeof(ElfXX_Ehdr));
  ElfXX_Ehdr* header = (ElfXX_Ehdr*)region->start();

  memcpy(header->e_ident, ElfMagic, EI_MAG3+1);

  header->e_ident[EI_CLASS]      = (SIZE == 32) ? ELFCLASS32 : ELFCLASS64;
  header->e_ident[EI_DATA]       = pConfig.targets().isLittleEndian()?
                                       ELFDATA2LSB : ELFDATA2MSB;
  header->e_ident[EI_VERSION]    = target().getInfo().ELFVersion();
  header->e_ident[EI_OSABI]      = target().getInfo().OSABI();
  header->e_ident[EI_ABIVERSION] = target().getInfo().ABIVersion();

  // FIXME: add processor-specific and core file types.
  switch(pConfig.codeGenType()) {
    case LinkerConfig::Object:
      header->e_type = ET_REL;
      break;
    case LinkerConfig::DynObj:
      header->e_type = ET_DYN;
      break;
    case LinkerConfig::Exec:
      header->e_type = ET_EXEC;
      break;
    default:
      llvm::errs() << "unspported output file type: " << pConfig.codeGenType() << ".\n";
      header->e_type = ET_NONE;
  }
  header->e_machine   = target().getInfo().machine();
  header->e_version   = header->e_ident[EI_VERSION];
  header->e_entry     = getEntryPoint(pConfig, pModule);

  if (LinkerConfig::Object != pConfig.codeGenType())
    header->e_phoff   = sizeof(ElfXX_Ehdr);
  else
    header->e_phoff   = 0x0;

  header->e_shoff     = getLastStartOffset<SIZE>(pModule);
  header->e_flags     = target().getInfo().flags();
  header->e_ehsize    = sizeof(ElfXX_Ehdr);
  header->e_phentsize = sizeof(ElfXX_Phdr);
  header->e_phnum     = target().elfSegmentTable().size();
  header->e_shentsize = sizeof(ElfXX_Shdr);
  header->e_shnum     = pModule.size();
  header->e_shstrndx  = pModule.getSection(".shstrtab")->index();
}
예제 #2
0
static bool MCLDEmulateARMELF(LinkerConfig& pConfig)
{
  if (!MCLDEmulateELF(pConfig))
    return false;

  // set up bitclass and endian
  pConfig.targets().setEndian(TargetOptions::Little);
  pConfig.targets().setBitClass(32);

  // set up target-dependent constraints of attributes
  pConfig.attribute().constraint().enableWholeArchive();
  pConfig.attribute().constraint().enableAsNeeded();
  pConfig.attribute().constraint().setSharedSystem();

  // set up the predefined attributes
  pConfig.attribute().predefined().unsetWholeArchive();
  pConfig.attribute().predefined().unsetAsNeeded();
  pConfig.attribute().predefined().setDynamic();

  // set up section map
  if (pConfig.codeGenType() != LinkerConfig::Object) {
    bool exist = false;
    pConfig.scripts().sectionMap().append(".ARM.exidx", ".ARM.exidx", exist);
    pConfig.scripts().sectionMap().append(".ARM.extab", ".ARM.extab", exist);
    pConfig.scripts().sectionMap().append(".ARM.attributes", ".ARM.attributes", exist);
  }
  return true;
}
// FIXME: LinkerConfig& pConfig should be constant
bool MCLDEmulateELF(LinkerScript& pScript, LinkerConfig& pConfig) {
  // set up section map
  if (pConfig.options().getScriptList().empty() &&
      pConfig.codeGenType() != LinkerConfig::Object) {
    const unsigned int map_size = (sizeof(map) / sizeof(map[0]));
    for (unsigned int i = 0; i < map_size; ++i) {
      std::pair<SectionMap::mapping, bool> res =
          pScript.sectionMap().insert(map[i].from, map[i].to, map[i].policy);
      if (!res.second)
        return false;
    }
  } else {
    // FIXME: this is the hack to help assignment processing in current
    // implementation.
    pScript.sectionMap().insert("", "");
  }

  if (!pConfig.options().nostdlib()) {
    // TODO: check if user sets the default search path instead via -Y option
    // set up default search path
    switch (pConfig.targets().triple().getOS()) {
      case llvm::Triple::NetBSD:
        pScript.directories().insert("=/usr/lib");
        break;
      case llvm::Triple::Win32:
        pScript.directories().insert("=/mingw/lib");
        break;
      default:
        pScript.directories().insert("=/lib");
        pScript.directories().insert("=/usr/lib");
        break;
    }
  }
  return true;
}
예제 #4
0
void ELFObjectWriter::emitRela(const LinkerConfig& pConfig,
                               const RelocData& pRelocData,
                               MemoryRegion& pRegion) const
{
  typedef typename ELFSizeTraits<SIZE>::Rela ElfXX_Rela;
  typedef typename ELFSizeTraits<SIZE>::Addr ElfXX_Addr;
  typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word;

  ElfXX_Rela* rel = reinterpret_cast<ElfXX_Rela*>(pRegion.start());

  const Relocation* relocation = 0;
  const FragmentRef* frag_ref = 0;

  for (RelocData::const_iterator it = pRelocData.begin(),
       ie = pRelocData.end(); it != ie; ++it, ++rel) {
    ElfXX_Addr r_offset = 0;
    ElfXX_Word r_sym = 0;

    relocation = &(llvm::cast<Relocation>(*it));
    frag_ref = &(relocation->targetRef());

    if(LinkerConfig::DynObj == pConfig.codeGenType() ||
       LinkerConfig::Exec == pConfig.codeGenType()) {
      r_offset = static_cast<ElfXX_Addr>(
                      frag_ref->frag()->getParent()->getSection().addr() +
                      frag_ref->getOutputOffset());
    }
    else {
      r_offset = static_cast<ElfXX_Addr>(frag_ref->getOutputOffset());
    }

    if( relocation->symInfo() == NULL )
      r_sym = 0;
    else
      r_sym = static_cast<ElfXX_Word>(
              target().getSymbolIdx(relocation->symInfo()->outSymbol()));

    target().emitRelocation(*rel, relocation->type(),
                            r_sym, r_offset, relocation->addend());
  }
}
예제 #5
0
/// getEntryPoint
uint64_t ELFObjectWriter::getEntryPoint(const LinkerConfig& pConfig,
                                        const Module& pModule) const
{
  llvm::StringRef entry_name;
  if (pModule.getScript().hasEntry())
    entry_name = pModule.getScript().entry();
  else
    entry_name = target().getInfo().entry();

  uint64_t result = 0x0;

  bool issue_warning = (pModule.getScript().hasEntry() &&
                        LinkerConfig::Object != pConfig.codeGenType() &&
                        LinkerConfig::DynObj != pConfig.codeGenType());

  const LDSymbol* entry_symbol = pModule.getNamePool().findSymbol(entry_name);

  // found the symbol
  if (NULL != entry_symbol) {
    if (entry_symbol->desc() != ResolveInfo::Define && issue_warning) {
      llvm::errs() << "WARNING: entry symbol '"
                   << entry_symbol->name()
                   << "' exists but is not defined.\n";
    }
    result = entry_symbol->value();
  }
  // not in the symbol pool
  else {
    // We should parse entry as a number.
    // @ref GNU ld manual, Options -e. e.g., -e 0x1000.
    char* endptr;
    result = strtoull(entry_name.data(), &endptr, 0);
    if (*endptr != '\0') {
      if (issue_warning) {
        llvm::errs() << "cannot find entry symbol '"
                     << entry_name.data()
                     << "'.\n";
      }
      result = 0x0;
    }
  }
  return result;
}
예제 #6
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;
}