ELFObjectWriter.cpp revision 6f75755c9204b1d8817ae5a65a2f7e5af0ec3f70
15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- ELFObjectWriter.cpp ------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ELFObjectWriter.h>
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h>
12d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LinkerConfig.h>
1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Target/GNULDBackend.h>
1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MemoryArea.h>
156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Support/MemoryRegion.h>
166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Support/MsgHandling.h>
176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/ADT/SizeTraits.h>
186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Fragment/FragmentLinker.h>
196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Fragment/AlignFragment.h>
206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Fragment/FillFragment.h>
216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Fragment/RegionFragment.h>
226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Fragment/Stub.h>
236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Fragment/NullFragment.h>
246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/LD/LDSection.h>
256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/LD/SectionData.h>
266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/LD/ELFSegment.h>
276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/LD/ELFSegmentFactory.h>
286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/LD/RelocData.h>
296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/LD/EhFrame.h>
3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/Support/ErrorHandling.h>
3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/Support/system_error.h>
336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/Support/ELF.h>
346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/Support/Casting.h>
35d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace llvm;
376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesusing namespace llvm::ELF;
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ELFObjectWriter
4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFObjectWriter::ELFObjectWriter(GNULDBackend& pBackend,
44d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                 const LinkerConfig& pConfig)
456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  : ObjectWriter(), m_Backend(pBackend), m_Config(pConfig)
466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFObjectWriter::~ELFObjectWriter()
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::writeSection(MemoryArea& pOutput, LDSection *section)
546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  MemoryRegion* region;
566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // Request output region
576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  switch (section->kind()) {
586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::Note:
596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (section->getSectionData() == NULL)
606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return;
616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // Fall through
626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::Regular:
636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::Relocation:
646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::Target:
656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::Debug:
666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::GCCExceptTable:
676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::EhFrame: {
686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    region = pOutput.request(section->offset(), section->size());
696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (NULL == region) {
706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      llvm::report_fatal_error(llvm::Twine("cannot get enough memory region for output section `") +
716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                               llvm::Twine(section->name()) +
726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                               llvm::Twine("'.\n"));
736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    break;
756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::Null:
776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::NamePool:
786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::BSS:
796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::MetaData:
806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::Version:
816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::EhFrameHdr:
826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::StackNote:
836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // Ignore these sections
846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return;
856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  default:
866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    llvm::errs() << "WARNING: unsupported section kind: "
876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                 << section->kind()
886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                 << " of section "
896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                 << section->name()
906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                 << ".\n";
916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return;
926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // Write out sections with data
956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  switch(section->kind()) {
966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::GCCExceptTable:
976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::EhFrame:
986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::Regular:
996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::Debug:
1006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::Note:
1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // FIXME: if optimization of exception handling sections is enabled,
1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // then we should emit these sections by the other way.
1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitSectionData(*section, *region);
1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    break;
1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::Relocation:
1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitRelocation(m_Config, *section, *region);
1076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    break;
1086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  case LDFileFormat::Target:
1096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    target().emitSectionData(*section, *region);
1106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    break;
1116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  default:
1126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    llvm_unreachable("invalid section kind");
1136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
1156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaollvm::error_code ELFObjectWriter::writeObject(Module& pModule,
11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                              MemoryArea& pOutput)
11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
1196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool is_dynobj = m_Config.codeGenType() == LinkerConfig::DynObj;
1206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool is_exec = m_Config.codeGenType() == LinkerConfig::Exec;
1216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool is_binary = m_Config.codeGenType() == LinkerConfig::Binary;
1226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool is_object = m_Config.codeGenType() == LinkerConfig::Object;
1236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(is_dynobj || is_exec || is_binary || is_object);
1256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (is_dynobj || is_exec) {
1276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // Write out the interpreter section: .interp
1286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    target().emitInterp(pOutput);
1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // Write out name pool sections: .dynsym, .dynstr, .hash
1316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    target().emitDynNamePools(pModule, pOutput);
1326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (is_object || is_dynobj || is_exec) {
1356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // Write out name pool sections: .symtab, .strtab
1366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    target().emitRegNamePools(pModule, pOutput);
1376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (is_binary) {
1406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // Iterate over the loadable segments and write the corresponding sections
1416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ELFSegmentFactory::iterator seg, segEnd = target().elfSegmentTable().end();
1426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    for (seg = target().elfSegmentTable().begin(); seg != segEnd; ++seg) {
1446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (llvm::ELF::PT_LOAD == (*seg).type()) {
1456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        ELFSegment::sect_iterator sect, sectEnd = (*seg).end();
1466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        for (sect = (*seg).begin(); sect != sectEnd; ++sect)
1476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          writeSection(pOutput, *sect);
14822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
14922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
1506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  } else {
1516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // Write out regular ELF sections
1526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    Module::iterator sect, sectEnd = pModule.end();
1536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    for (sect = pModule.begin(); sect != sectEnd; ++sect)
1546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      writeSection(pOutput, *sect);
15522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    emitShStrTab(target().getOutputFormat()->getShStrTab(), pModule, pOutput);
1576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (m_Config.targets().is32Bits()) {
1596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // Write out ELF header
1606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // Write out section header table
1616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      writeELFHeader<32>(m_Config, pModule, pOutput);
1626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (is_dynobj || is_exec)
1636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        emitProgramHeader<32>(pOutput);
1646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      emitSectionHeader<32>(pModule, m_Config, pOutput);
1666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
1676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else if (m_Config.targets().is64Bits()) {
1686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // Write out ELF header
1696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // Write out section header table
1706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      writeELFHeader<64>(m_Config, pModule, pOutput);
1716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (is_dynobj || is_exec)
1726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        emitProgramHeader<64>(pOutput);
1736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      emitSectionHeader<64>(pModule, m_Config, pOutput);
1756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
1766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else
1776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return make_error_code(errc::not_supported);
1786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  pOutput.clear();
1816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return llvm::make_error_code(llvm::errc::success);
1826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
1836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// writeELFHeader - emit ElfXX_Ehdr
1856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<size_t SIZE>
1866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::writeELFHeader(const LinkerConfig& pConfig,
1876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                     const Module& pModule,
1886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                     MemoryArea& pOutput) const
1896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
1906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef typename ELFSizeTraits<SIZE>::Ehdr ElfXX_Ehdr;
1916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef typename ELFSizeTraits<SIZE>::Shdr ElfXX_Shdr;
1926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef typename ELFSizeTraits<SIZE>::Phdr ElfXX_Phdr;
1936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // ELF header must start from 0x0
1956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  MemoryRegion *region = pOutput.request(0, sizeof(ElfXX_Ehdr));
1966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ElfXX_Ehdr* header = (ElfXX_Ehdr*)region->start();
1976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  memcpy(header->e_ident, ElfMagic, EI_MAG3+1);
1996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  header->e_ident[EI_CLASS]      = (SIZE == 32) ? ELFCLASS32 : ELFCLASS64;
2016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  header->e_ident[EI_DATA]       = pConfig.targets().isLittleEndian()?
2026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                       ELFDATA2LSB : ELFDATA2MSB;
2036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  header->e_ident[EI_VERSION]    = target().getInfo().ELFVersion();
2046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  header->e_ident[EI_OSABI]      = target().getInfo().OSABI();
2056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  header->e_ident[EI_ABIVERSION] = target().getInfo().ABIVersion();
2066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // FIXME: add processor-specific and core file types.
2086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  switch(pConfig.codeGenType()) {
2096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LinkerConfig::Object:
2106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      header->e_type = ET_REL;
2116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
2126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LinkerConfig::DynObj:
2136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      header->e_type = ET_DYN;
2146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
2156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LinkerConfig::Exec:
2166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      header->e_type = ET_EXEC;
2176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
2186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    default:
2196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      llvm::errs() << "unspported output file type: " << pConfig.codeGenType() << ".\n";
2206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      header->e_type = ET_NONE;
2216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  header->e_machine   = target().getInfo().machine();
2236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  header->e_version   = header->e_ident[EI_VERSION];
2246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  header->e_entry     = getEntryPoint(pConfig, pModule);
2256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (LinkerConfig::Object != pConfig.codeGenType())
2276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    header->e_phoff   = sizeof(ElfXX_Ehdr);
2286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else
2296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    header->e_phoff   = 0x0;
2306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  header->e_shoff     = getLastStartOffset<SIZE>(pModule);
2326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  header->e_flags     = target().getInfo().flags();
2336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  header->e_ehsize    = sizeof(ElfXX_Ehdr);
2346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  header->e_phentsize = sizeof(ElfXX_Phdr);
2356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  header->e_phnum     = target().numOfSegments();
2366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  header->e_shentsize = sizeof(ElfXX_Shdr);
2376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  header->e_shnum     = pModule.size();
2386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  header->e_shstrndx  = pModule.getSection(".shstrtab")->index();
2396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
2406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getEntryPoint
2426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getEntryPoint(const LinkerConfig& pConfig,
2436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                        const Module& pModule) const
2446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  llvm::StringRef entry_name;
2466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (pConfig.options().hasEntry())
2476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    entry_name = pConfig.options().entry();
2486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else
2496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    entry_name = target().getInfo().entry();
2506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t result = 0x0;
2526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool issue_warning = (pConfig.options().hasEntry() &&
2546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                        LinkerConfig::Object != pConfig.codeGenType() &&
2556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                        LinkerConfig::DynObj != pConfig.codeGenType());
2566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const LDSymbol* entry_symbol = pModule.getNamePool().findSymbol(entry_name);
2586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // found the symbol
2606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (NULL != entry_symbol) {
2616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (entry_symbol->desc() != ResolveInfo::Define && issue_warning) {
2626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      llvm::errs() << "WARNING: entry symbol '"
2636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                   << entry_symbol->name()
2646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                   << "' exists but is not defined.\n";
2656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
2666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    result = entry_symbol->value();
2676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // not in the symbol pool
2696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else {
2706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // We should parse entry as a number.
2716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // @ref GNU ld manual, Options -e. e.g., -e 0x1000.
2726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    char* endptr;
2736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    result = strtoull(entry_name.data(), &endptr, 0);
2746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (*endptr != '\0') {
2756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (issue_warning) {
2766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        llvm::errs() << "cannot find entry symbol '"
2776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                     << entry_name.data()
2786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                     << "'.\n";
27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
2806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      result = 0x0;
28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
2826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return result;
2846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// emitSectionHeader - emit ElfXX_Shdr
2876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<size_t SIZE>
2886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::emitSectionHeader(const Module& pModule,
2896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                        const LinkerConfig& pConfig,
2906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                        MemoryArea& pOutput) const
2916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
2926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef typename ELFSizeTraits<SIZE>::Shdr ElfXX_Shdr;
29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emit section header
2956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned int sectNum = pModule.size();
2966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned int header_size = sizeof(ElfXX_Shdr) * sectNum;
2976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  MemoryRegion* region = pOutput.request(getLastStartOffset<SIZE>(pModule),
2986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                         header_size);
2996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ElfXX_Shdr* shdr = (ElfXX_Shdr*)region->start();
30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // Iterate the SectionTable in LDContext
3026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned int sectIdx = 0;
3036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned int shstridx = 0; // NULL section has empty name
3046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (; sectIdx < sectNum; ++sectIdx) {
3056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    const LDSection *ld_sect   = pModule.getSectionTable().at(sectIdx);
3066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    shdr[sectIdx].sh_name      = shstridx;
3076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    shdr[sectIdx].sh_type      = ld_sect->type();
3086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    shdr[sectIdx].sh_flags     = ld_sect->flag();
3096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    shdr[sectIdx].sh_addr      = ld_sect->addr();
3106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    shdr[sectIdx].sh_offset    = ld_sect->offset();
3116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    shdr[sectIdx].sh_size      = ld_sect->size();
3126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    shdr[sectIdx].sh_addralign = ld_sect->align();
3136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    shdr[sectIdx].sh_entsize   = getSectEntrySize<SIZE>(*ld_sect);
3146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    shdr[sectIdx].sh_link      = getSectLink(*ld_sect, pConfig);
3156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    shdr[sectIdx].sh_info      = getSectInfo(*ld_sect);
3166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // adjust strshidx
3186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    shstridx += ld_sect->name().size() + 1;
31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
3206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// emitProgramHeader - emit ElfXX_Phdr
3236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<size_t SIZE>
3246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::emitProgramHeader(MemoryArea& pOutput) const
3256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef typename ELFSizeTraits<SIZE>::Ehdr ElfXX_Ehdr;
3276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef typename ELFSizeTraits<SIZE>::Phdr ElfXX_Phdr;
3286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t start_offset, phdr_size;
33022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  start_offset = sizeof(ElfXX_Ehdr);
3326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  phdr_size = sizeof(ElfXX_Phdr);
3336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // Program header must start directly after ELF header
3346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  MemoryRegion *region = pOutput.request(start_offset,
3356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                         target().numOfSegments() * phdr_size);
3366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ElfXX_Phdr* phdr = (ElfXX_Phdr*)region->start();
3386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // Iterate the elf segment table in GNULDBackend
3406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t index = 0;
3416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ELFSegmentFactory::const_iterator seg = target().elfSegmentTable().begin(),
3426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                 segEnd = target().elfSegmentTable().end();
3436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (; seg != segEnd; ++seg, ++index) {
3446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    phdr[index].p_type   = (*seg).type();
3456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    phdr[index].p_flags  = (*seg).flag();
3466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    phdr[index].p_offset = (*seg).offset();
3476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    phdr[index].p_vaddr  = (*seg).vaddr();
3486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    phdr[index].p_paddr  = (*seg).paddr();
3496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    phdr[index].p_filesz = (*seg).filesz();
3506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    phdr[index].p_memsz  = (*seg).memsz();
3516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    phdr[index].p_align  = (*seg).align();
35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
3536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
35422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitShStrTab - emit section string table
3566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid
3576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFObjectWriter::emitShStrTab(const LDSection& pShStrTab,
3586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                              const Module& pModule,
3596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                              MemoryArea& pOutput)
3606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // write out data
3626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  MemoryRegion* region = pOutput.request(pShStrTab.offset(), pShStrTab.size());
3636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  unsigned char* data = region->start();
3646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t shstrsize = 0;
3656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Module::const_iterator section, sectEnd = pModule.end();
3666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (section = pModule.begin(); section != sectEnd; ++section) {
3676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    strcpy((char*)(data + shstrsize), (*section)->name().data());
3686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    shstrsize += (*section)->name().size() + 1;
3696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
3706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitSectionData
3736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid
3746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFObjectWriter::emitSectionData(const LDSection& pSection,
3756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                 MemoryRegion& pRegion) const
3766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const SectionData* sd = NULL;
3786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  switch (pSection.kind()) {
3796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::Relocation:
3806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      assert(pSection.hasRelocData());
3816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return;
3826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    case LDFileFormat::EhFrame:
3836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      assert(pSection.hasEhFrame());
3846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      sd = &pSection.getEhFrame()->getSectionData();
3856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
3866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    default:
3876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      assert(pSection.hasSectionData());
3886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      sd = pSection.getSectionData();
3896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      break;
3906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
3916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  emitSectionData(*sd, pRegion);
3926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
3936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
3946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitRelocation
3956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::emitRelocation(const LinkerConfig& pConfig,
3966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                     const LDSection& pSection,
3976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                     MemoryRegion& pRegion) const
3986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
3996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const RelocData* sect_data = pSection.getRelocData();
4006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(NULL != sect_data && "SectionData is NULL in emitRelocation!");
4016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (pSection.type() == SHT_REL) {
4036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (pConfig.targets().is32Bits())
4046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      emitRel<32>(pConfig, *sect_data, pRegion);
4056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else if (pConfig.targets().is64Bits())
4066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      emitRel<64>(pConfig, *sect_data, pRegion);
4076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else {
4086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      fatal(diag::unsupported_bitclass) << pConfig.targets().triple().str()
4096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                        << pConfig.targets().bitclass();
4106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
4116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  } else if (pSection.type() == SHT_RELA) {
4126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (pConfig.targets().is32Bits())
4136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      emitRela<32>(pConfig, *sect_data, pRegion);
4146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else if (pConfig.targets().is64Bits())
4156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      emitRela<64>(pConfig, *sect_data, pRegion);
4166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else {
4176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      fatal(diag::unsupported_bitclass) << pConfig.targets().triple().str()
4186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                        << pConfig.targets().bitclass();
4196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
4206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  } else
4216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    llvm::report_fatal_error("unsupported relocation section type!");
4226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
4236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// emitRel - emit ElfXX_Rel
4266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<size_t SIZE>
4276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::emitRel(const LinkerConfig& pConfig,
4286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                              const RelocData& pRelocData,
4296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                              MemoryRegion& pRegion) const
4306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
4316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef typename ELFSizeTraits<SIZE>::Rel  ElfXX_Rel;
4326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef typename ELFSizeTraits<SIZE>::Addr ElfXX_Addr;
4336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word;
4346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ElfXX_Rel* rel = reinterpret_cast<ElfXX_Rel*>(pRegion.start());
4366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const Relocation* relocation = 0;
4386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const FragmentRef* frag_ref = 0;
4396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (RelocData::const_iterator it = pRelocData.begin(),
4416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines       ie = pRelocData.end(); it != ie; ++it, ++rel) {
4426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    relocation = &(llvm::cast<Relocation>(*it));
4446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    frag_ref = &(relocation->targetRef());
4456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if(LinkerConfig::DynObj == pConfig.codeGenType() ||
4476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines       LinkerConfig::Exec == pConfig.codeGenType()) {
4486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      rel->r_offset = static_cast<ElfXX_Addr>(
4496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      frag_ref->frag()->getParent()->getSection().addr() +
4506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      frag_ref->getOutputOffset());
4516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
4526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else {
4536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      rel->r_offset = static_cast<ElfXX_Addr>(frag_ref->getOutputOffset());
4546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
4556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ElfXX_Word Index;
4566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if( relocation->symInfo() == NULL )
4576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      Index = 0;
4586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else
4596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      Index = static_cast<ElfXX_Word>(
4606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines              target().getSymbolIdx(relocation->symInfo()->outSymbol()));
4616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    rel->setSymbolAndType(Index, relocation->type());
4636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
4646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
4656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// emitRela - emit ElfXX_Rela
4676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<size_t SIZE>
4686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::emitRela(const LinkerConfig& pConfig,
4696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                               const RelocData& pRelocData,
4706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                               MemoryRegion& pRegion) const
4716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
4726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef typename ELFSizeTraits<SIZE>::Rela ElfXX_Rela;
4736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef typename ELFSizeTraits<SIZE>::Addr ElfXX_Addr;
4746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word;
4756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ElfXX_Rela* rel = reinterpret_cast<ElfXX_Rela*>(pRegion.start());
4776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const Relocation* relocation = 0;
4796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const FragmentRef* frag_ref = 0;
4806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (RelocData::const_iterator it = pRelocData.begin(),
4826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines       ie = pRelocData.end(); it != ie; ++it, ++rel) {
4836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    relocation = &(llvm::cast<Relocation>(*it));
4856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    frag_ref = &(relocation->targetRef());
4866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if(LinkerConfig::DynObj == pConfig.codeGenType() ||
4886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines       LinkerConfig::Exec == pConfig.codeGenType()) {
4896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      rel->r_offset = static_cast<ElfXX_Addr>(
4906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      frag_ref->frag()->getParent()->getSection().addr() +
4916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      frag_ref->getOutputOffset());
4926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
4936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else {
4946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      rel->r_offset = static_cast<ElfXX_Addr>(frag_ref->getOutputOffset());
4956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
4966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ElfXX_Word Index;
4986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if( relocation->symInfo() == NULL )
4996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      Index = 0;
5006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else
5016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      Index = static_cast<ElfXX_Word>(
5026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines              target().getSymbolIdx(relocation->symInfo()->outSymbol()));
5036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    rel->setSymbolAndType(Index, relocation->type());
5056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    rel->r_addend = relocation->addend();
5066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
5076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
5086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSectEntrySize - compute ElfXX_Shdr::sh_entsize
5116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<size_t SIZE>
5126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getSectEntrySize(const LDSection& pSection) const
5136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
5146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word;
5156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef typename ELFSizeTraits<SIZE>::Sym  ElfXX_Sym;
5166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef typename ELFSizeTraits<SIZE>::Rel  ElfXX_Rel;
5176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef typename ELFSizeTraits<SIZE>::Rela ElfXX_Rela;
5186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef typename ELFSizeTraits<SIZE>::Dyn  ElfXX_Dyn;
5196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (llvm::ELF::SHT_DYNSYM == pSection.type() ||
5216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      llvm::ELF::SHT_SYMTAB == pSection.type())
5226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return sizeof(ElfXX_Sym);
5236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (llvm::ELF::SHT_REL == pSection.type())
5246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return sizeof(ElfXX_Rel);
5256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (llvm::ELF::SHT_RELA == pSection.type())
5266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return sizeof(ElfXX_Rela);
5276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (llvm::ELF::SHT_HASH     == pSection.type() ||
5286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      llvm::ELF::SHT_GNU_HASH == pSection.type())
5296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return sizeof(ElfXX_Word);
5306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (llvm::ELF::SHT_DYNAMIC == pSection.type())
5316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return sizeof(ElfXX_Dyn);
5326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return 0x0;
5336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
5346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSectLink - compute ElfXX_Shdr::sh_link
5366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getSectLink(const LDSection& pSection,
5376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                      const LinkerConfig& pConfig) const
5386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
5396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (llvm::ELF::SHT_SYMTAB == pSection.type())
5406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return target().getOutputFormat()->getStrTab().index();
5416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (llvm::ELF::SHT_DYNSYM == pSection.type())
5426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return target().getOutputFormat()->getDynStrTab().index();
5436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (llvm::ELF::SHT_DYNAMIC == pSection.type())
5446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return target().getOutputFormat()->getDynStrTab().index();
5456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (llvm::ELF::SHT_HASH     == pSection.type() ||
5466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      llvm::ELF::SHT_GNU_HASH == pSection.type())
5476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return target().getOutputFormat()->getDynSymTab().index();
5486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (llvm::ELF::SHT_REL == pSection.type() ||
5496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      llvm::ELF::SHT_RELA == pSection.type()) {
5506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (LinkerConfig::Object == pConfig.codeGenType())
5516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return target().getOutputFormat()->getSymTab().index();
5526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else
5536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return target().getOutputFormat()->getDynSymTab().index();
5546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
5556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // FIXME: currently we link ARM_EXIDX section to output text section here
5566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (llvm::ELF::SHT_ARM_EXIDX == pSection.type())
5576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return target().getOutputFormat()->getText().index();
5586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return llvm::ELF::SHN_UNDEF;
5596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
5606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSectInfo - compute ElfXX_Shdr::sh_info
5626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getSectInfo(const LDSection& pSection) const
5636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
5646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (llvm::ELF::SHT_SYMTAB == pSection.type() ||
5656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      llvm::ELF::SHT_DYNSYM == pSection.type())
5666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return pSection.getInfo();
5676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (llvm::ELF::SHT_REL == pSection.type() ||
5696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      llvm::ELF::SHT_RELA == pSection.type()) {
5706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    const LDSection* info_link = pSection.getLink();
5716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (NULL != info_link)
5726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return info_link->index();
5736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
5746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return 0x0;
5766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
5776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getLastStartOffset
5796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<>
5806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getLastStartOffset<32>(const Module& pModule) const
5816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
5826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const LDSection* lastSect = pModule.back();
5836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(lastSect != NULL);
5846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return Align<32>(lastSect->offset() + lastSect->size());
5856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
5866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getLastStartOffset
5886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<>
5896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getLastStartOffset<64>(const Module& pModule) const
5906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
5916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const LDSection* lastSect = pModule.back();
5926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  assert(lastSect != NULL);
5936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return Align<64>(lastSect->offset() + lastSect->size());
5946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
5956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitSectionData
5976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::emitSectionData(const SectionData& pSD,
5986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                      MemoryRegion& pRegion) const
5996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
6006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  SectionData::const_iterator fragIter, fragEnd = pSD.end();
6016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  size_t cur_offset = 0;
6026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  for (fragIter = pSD.begin(); fragIter != fragEnd; ++fragIter) {
6036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    size_t size = fragIter->size();
6046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    switch(fragIter->getKind()) {
6056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      case Fragment::Region: {
6066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        const RegionFragment& region_frag = llvm::cast<RegionFragment>(*fragIter);
6076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        const uint8_t* from = region_frag.getRegion().start();
6086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        memcpy(pRegion.getBuffer(cur_offset), from, size);
6096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        break;
6106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
6116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      case Fragment::Alignment: {
6126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        // TODO: emit values with different sizes (> 1 byte), and emit nops
6136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        const AlignFragment& align_frag = llvm::cast<AlignFragment>(*fragIter);
6146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        uint64_t count = size / align_frag.getValueSize();
6156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        switch (align_frag.getValueSize()) {
6166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          case 1u:
6176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            std::memset(pRegion.getBuffer(cur_offset),
6186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                        align_frag.getValue(),
6196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                        count);
6206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            break;
6216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          default:
6226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            llvm::report_fatal_error("unsupported value size for align fragment emission yet.\n");
6236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            break;
6246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
6256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        break;
6266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
6276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      case Fragment::Fillment: {
6286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        const FillFragment& fill_frag = llvm::cast<FillFragment>(*fragIter);
6296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        if (0 == size ||
6306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            0 == fill_frag.getValueSize() ||
6316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines            0 == fill_frag.size()) {
6326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          // ignore virtual fillment
6336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          break;
6346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
6356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
6366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        uint64_t num_tiles = fill_frag.size() / fill_frag.getValueSize();
6376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        for (uint64_t i = 0; i != num_tiles; ++i) {
6386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          std::memset(pRegion.getBuffer(cur_offset),
6396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      fill_frag.getValue(),
6406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      fill_frag.getValueSize());
6416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        }
6426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        break;
6436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
6446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      case Fragment::Stub: {
6456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        const Stub& stub_frag = llvm::cast<Stub>(*fragIter);
6466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        memcpy(pRegion.getBuffer(cur_offset), stub_frag.getContent(), size);
6476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        break;
6486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
6496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      case Fragment::Null: {
6506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        assert(0x0 == size);
6516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        break;
6526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      }
6536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      case Fragment::Target:
6546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        llvm::report_fatal_error("Target fragment should not be in a regular section.\n");
6556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        break;
6566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      default:
6576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        llvm::report_fatal_error("invalid fragment should not be in a regular section.\n");
6586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines        break;
6596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
6606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    cur_offset += size;
6616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
66222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
664