Home | History | Annotate | Download | only in LD
      1 //===- ELFObjectWriter.cpp ------------------------------------------------===//
      2 //
      3 //                     The MCLinker Project
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 #include <mcld/LD/ELFObjectWriter.h>
     10 
     11 #include <mcld/Module.h>
     12 #include <mcld/LinkerConfig.h>
     13 #include <mcld/Target/GNULDBackend.h>
     14 #include <mcld/Support/MemoryArea.h>
     15 #include <mcld/Support/MemoryRegion.h>
     16 #include <mcld/Support/MsgHandling.h>
     17 #include <mcld/ADT/SizeTraits.h>
     18 #include <mcld/Fragment/FragmentLinker.h>
     19 #include <mcld/Fragment/AlignFragment.h>
     20 #include <mcld/Fragment/FillFragment.h>
     21 #include <mcld/Fragment/RegionFragment.h>
     22 #include <mcld/Fragment/Stub.h>
     23 #include <mcld/Fragment/NullFragment.h>
     24 #include <mcld/LD/LDSection.h>
     25 #include <mcld/LD/SectionData.h>
     26 #include <mcld/LD/ELFSegment.h>
     27 #include <mcld/LD/ELFSegmentFactory.h>
     28 #include <mcld/LD/RelocData.h>
     29 #include <mcld/LD/EhFrame.h>
     30 
     31 #include <llvm/Support/ErrorHandling.h>
     32 #include <llvm/Support/system_error.h>
     33 #include <llvm/Support/ELF.h>
     34 #include <llvm/Support/Casting.h>
     35 
     36 using namespace llvm;
     37 using namespace llvm::ELF;
     38 using namespace mcld;
     39 
     40 //===----------------------------------------------------------------------===//
     41 // ELFObjectWriter
     42 //===----------------------------------------------------------------------===//
     43 ELFObjectWriter::ELFObjectWriter(GNULDBackend& pBackend,
     44                                  const LinkerConfig& pConfig)
     45   : ObjectWriter(), m_Backend(pBackend), m_Config(pConfig)
     46 {
     47 }
     48 
     49 ELFObjectWriter::~ELFObjectWriter()
     50 {
     51 }
     52 
     53 void ELFObjectWriter::writeSection(MemoryArea& pOutput, LDSection *section)
     54 {
     55   MemoryRegion* region;
     56   // Request output region
     57   switch (section->kind()) {
     58   case LDFileFormat::Note:
     59     if (section->getSectionData() == NULL)
     60       return;
     61     // Fall through
     62   case LDFileFormat::Regular:
     63   case LDFileFormat::Relocation:
     64   case LDFileFormat::Target:
     65   case LDFileFormat::Debug:
     66   case LDFileFormat::GCCExceptTable:
     67   case LDFileFormat::EhFrame: {
     68     region = pOutput.request(section->offset(), section->size());
     69     if (NULL == region) {
     70       llvm::report_fatal_error(llvm::Twine("cannot get enough memory region for output section `") +
     71                                llvm::Twine(section->name()) +
     72                                llvm::Twine("'.\n"));
     73     }
     74     break;
     75   }
     76   case LDFileFormat::Null:
     77   case LDFileFormat::NamePool:
     78   case LDFileFormat::BSS:
     79   case LDFileFormat::MetaData:
     80   case LDFileFormat::Version:
     81   case LDFileFormat::EhFrameHdr:
     82   case LDFileFormat::StackNote:
     83     // Ignore these sections
     84     return;
     85   default:
     86     llvm::errs() << "WARNING: unsupported section kind: "
     87                  << section->kind()
     88                  << " of section "
     89                  << section->name()
     90                  << ".\n";
     91     return;
     92   }
     93 
     94   // Write out sections with data
     95   switch(section->kind()) {
     96   case LDFileFormat::GCCExceptTable:
     97   case LDFileFormat::EhFrame:
     98   case LDFileFormat::Regular:
     99   case LDFileFormat::Debug:
    100   case LDFileFormat::Note:
    101     // FIXME: if optimization of exception handling sections is enabled,
    102     // then we should emit these sections by the other way.
    103     emitSectionData(*section, *region);
    104     break;
    105   case LDFileFormat::Relocation:
    106     emitRelocation(m_Config, *section, *region);
    107     break;
    108   case LDFileFormat::Target:
    109     target().emitSectionData(*section, *region);
    110     break;
    111   default:
    112     llvm_unreachable("invalid section kind");
    113   }
    114 }
    115 
    116 llvm::error_code ELFObjectWriter::writeObject(Module& pModule,
    117                                               MemoryArea& pOutput)
    118 {
    119   bool is_dynobj = m_Config.codeGenType() == LinkerConfig::DynObj;
    120   bool is_exec = m_Config.codeGenType() == LinkerConfig::Exec;
    121   bool is_binary = m_Config.codeGenType() == LinkerConfig::Binary;
    122   bool is_object = m_Config.codeGenType() == LinkerConfig::Object;
    123 
    124   assert(is_dynobj || is_exec || is_binary || is_object);
    125 
    126   if (is_dynobj || is_exec) {
    127     // Write out the interpreter section: .interp
    128     target().emitInterp(pOutput);
    129 
    130     // Write out name pool sections: .dynsym, .dynstr, .hash
    131     target().emitDynNamePools(pModule, pOutput);
    132   }
    133 
    134   if (is_object || is_dynobj || is_exec) {
    135     // Write out name pool sections: .symtab, .strtab
    136     target().emitRegNamePools(pModule, pOutput);
    137   }
    138 
    139   if (is_binary) {
    140     // Iterate over the loadable segments and write the corresponding sections
    141     ELFSegmentFactory::iterator seg, segEnd = target().elfSegmentTable().end();
    142 
    143     for (seg = target().elfSegmentTable().begin(); seg != segEnd; ++seg) {
    144       if (llvm::ELF::PT_LOAD == (*seg).type()) {
    145         ELFSegment::sect_iterator sect, sectEnd = (*seg).end();
    146         for (sect = (*seg).begin(); sect != sectEnd; ++sect)
    147           writeSection(pOutput, *sect);
    148       }
    149     }
    150   } else {
    151     // Write out regular ELF sections
    152     Module::iterator sect, sectEnd = pModule.end();
    153     for (sect = pModule.begin(); sect != sectEnd; ++sect)
    154       writeSection(pOutput, *sect);
    155 
    156     emitShStrTab(target().getOutputFormat()->getShStrTab(), pModule, pOutput);
    157 
    158     if (m_Config.targets().is32Bits()) {
    159       // Write out ELF header
    160       // Write out section header table
    161       writeELFHeader<32>(m_Config, pModule, pOutput);
    162       if (is_dynobj || is_exec)
    163         emitProgramHeader<32>(pOutput);
    164 
    165       emitSectionHeader<32>(pModule, m_Config, pOutput);
    166     }
    167     else if (m_Config.targets().is64Bits()) {
    168       // Write out ELF header
    169       // Write out section header table
    170       writeELFHeader<64>(m_Config, pModule, pOutput);
    171       if (is_dynobj || is_exec)
    172         emitProgramHeader<64>(pOutput);
    173 
    174       emitSectionHeader<64>(pModule, m_Config, pOutput);
    175     }
    176     else
    177       return make_error_code(errc::not_supported);
    178   }
    179 
    180   pOutput.clear();
    181   return llvm::make_error_code(llvm::errc::success);
    182 }
    183 
    184 // writeELFHeader - emit ElfXX_Ehdr
    185 template<size_t SIZE>
    186 void ELFObjectWriter::writeELFHeader(const LinkerConfig& pConfig,
    187                                      const Module& pModule,
    188                                      MemoryArea& pOutput) const
    189 {
    190   typedef typename ELFSizeTraits<SIZE>::Ehdr ElfXX_Ehdr;
    191   typedef typename ELFSizeTraits<SIZE>::Shdr ElfXX_Shdr;
    192   typedef typename ELFSizeTraits<SIZE>::Phdr ElfXX_Phdr;
    193 
    194   // ELF header must start from 0x0
    195   MemoryRegion *region = pOutput.request(0, sizeof(ElfXX_Ehdr));
    196   ElfXX_Ehdr* header = (ElfXX_Ehdr*)region->start();
    197 
    198   memcpy(header->e_ident, ElfMagic, EI_MAG3+1);
    199 
    200   header->e_ident[EI_CLASS]      = (SIZE == 32) ? ELFCLASS32 : ELFCLASS64;
    201   header->e_ident[EI_DATA]       = pConfig.targets().isLittleEndian()?
    202                                        ELFDATA2LSB : ELFDATA2MSB;
    203   header->e_ident[EI_VERSION]    = target().getInfo().ELFVersion();
    204   header->e_ident[EI_OSABI]      = target().getInfo().OSABI();
    205   header->e_ident[EI_ABIVERSION] = target().getInfo().ABIVersion();
    206 
    207   // FIXME: add processor-specific and core file types.
    208   switch(pConfig.codeGenType()) {
    209     case LinkerConfig::Object:
    210       header->e_type = ET_REL;
    211       break;
    212     case LinkerConfig::DynObj:
    213       header->e_type = ET_DYN;
    214       break;
    215     case LinkerConfig::Exec:
    216       header->e_type = ET_EXEC;
    217       break;
    218     default:
    219       llvm::errs() << "unspported output file type: " << pConfig.codeGenType() << ".\n";
    220       header->e_type = ET_NONE;
    221   }
    222   header->e_machine   = target().getInfo().machine();
    223   header->e_version   = header->e_ident[EI_VERSION];
    224   header->e_entry     = getEntryPoint(pConfig, pModule);
    225 
    226   if (LinkerConfig::Object != pConfig.codeGenType())
    227     header->e_phoff   = sizeof(ElfXX_Ehdr);
    228   else
    229     header->e_phoff   = 0x0;
    230 
    231   header->e_shoff     = getLastStartOffset<SIZE>(pModule);
    232   header->e_flags     = target().getInfo().flags();
    233   header->e_ehsize    = sizeof(ElfXX_Ehdr);
    234   header->e_phentsize = sizeof(ElfXX_Phdr);
    235   header->e_phnum     = target().numOfSegments();
    236   header->e_shentsize = sizeof(ElfXX_Shdr);
    237   header->e_shnum     = pModule.size();
    238   header->e_shstrndx  = pModule.getSection(".shstrtab")->index();
    239 }
    240 
    241 /// getEntryPoint
    242 uint64_t ELFObjectWriter::getEntryPoint(const LinkerConfig& pConfig,
    243                                         const Module& pModule) const
    244 {
    245   llvm::StringRef entry_name;
    246   if (pConfig.options().hasEntry())
    247     entry_name = pConfig.options().entry();
    248   else
    249     entry_name = target().getInfo().entry();
    250 
    251   uint64_t result = 0x0;
    252 
    253   bool issue_warning = (pConfig.options().hasEntry() &&
    254                         LinkerConfig::Object != pConfig.codeGenType() &&
    255                         LinkerConfig::DynObj != pConfig.codeGenType());
    256 
    257   const LDSymbol* entry_symbol = pModule.getNamePool().findSymbol(entry_name);
    258 
    259   // found the symbol
    260   if (NULL != entry_symbol) {
    261     if (entry_symbol->desc() != ResolveInfo::Define && issue_warning) {
    262       llvm::errs() << "WARNING: entry symbol '"
    263                    << entry_symbol->name()
    264                    << "' exists but is not defined.\n";
    265     }
    266     result = entry_symbol->value();
    267   }
    268   // not in the symbol pool
    269   else {
    270     // We should parse entry as a number.
    271     // @ref GNU ld manual, Options -e. e.g., -e 0x1000.
    272     char* endptr;
    273     result = strtoull(entry_name.data(), &endptr, 0);
    274     if (*endptr != '\0') {
    275       if (issue_warning) {
    276         llvm::errs() << "cannot find entry symbol '"
    277                      << entry_name.data()
    278                      << "'.\n";
    279       }
    280       result = 0x0;
    281     }
    282   }
    283   return result;
    284 }
    285 
    286 // emitSectionHeader - emit ElfXX_Shdr
    287 template<size_t SIZE>
    288 void ELFObjectWriter::emitSectionHeader(const Module& pModule,
    289                                         const LinkerConfig& pConfig,
    290                                         MemoryArea& pOutput) const
    291 {
    292   typedef typename ELFSizeTraits<SIZE>::Shdr ElfXX_Shdr;
    293 
    294   // emit section header
    295   unsigned int sectNum = pModule.size();
    296   unsigned int header_size = sizeof(ElfXX_Shdr) * sectNum;
    297   MemoryRegion* region = pOutput.request(getLastStartOffset<SIZE>(pModule),
    298                                          header_size);
    299   ElfXX_Shdr* shdr = (ElfXX_Shdr*)region->start();
    300 
    301   // Iterate the SectionTable in LDContext
    302   unsigned int sectIdx = 0;
    303   unsigned int shstridx = 0; // NULL section has empty name
    304   for (; sectIdx < sectNum; ++sectIdx) {
    305     const LDSection *ld_sect   = pModule.getSectionTable().at(sectIdx);
    306     shdr[sectIdx].sh_name      = shstridx;
    307     shdr[sectIdx].sh_type      = ld_sect->type();
    308     shdr[sectIdx].sh_flags     = ld_sect->flag();
    309     shdr[sectIdx].sh_addr      = ld_sect->addr();
    310     shdr[sectIdx].sh_offset    = ld_sect->offset();
    311     shdr[sectIdx].sh_size      = ld_sect->size();
    312     shdr[sectIdx].sh_addralign = ld_sect->align();
    313     shdr[sectIdx].sh_entsize   = getSectEntrySize<SIZE>(*ld_sect);
    314     shdr[sectIdx].sh_link      = getSectLink(*ld_sect, pConfig);
    315     shdr[sectIdx].sh_info      = getSectInfo(*ld_sect);
    316 
    317     // adjust strshidx
    318     shstridx += ld_sect->name().size() + 1;
    319   }
    320 }
    321 
    322 // emitProgramHeader - emit ElfXX_Phdr
    323 template<size_t SIZE>
    324 void ELFObjectWriter::emitProgramHeader(MemoryArea& pOutput) const
    325 {
    326   typedef typename ELFSizeTraits<SIZE>::Ehdr ElfXX_Ehdr;
    327   typedef typename ELFSizeTraits<SIZE>::Phdr ElfXX_Phdr;
    328 
    329   uint64_t start_offset, phdr_size;
    330 
    331   start_offset = sizeof(ElfXX_Ehdr);
    332   phdr_size = sizeof(ElfXX_Phdr);
    333   // Program header must start directly after ELF header
    334   MemoryRegion *region = pOutput.request(start_offset,
    335                                          target().numOfSegments() * phdr_size);
    336 
    337   ElfXX_Phdr* phdr = (ElfXX_Phdr*)region->start();
    338 
    339   // Iterate the elf segment table in GNULDBackend
    340   size_t index = 0;
    341   ELFSegmentFactory::const_iterator seg = target().elfSegmentTable().begin(),
    342                                  segEnd = target().elfSegmentTable().end();
    343   for (; seg != segEnd; ++seg, ++index) {
    344     phdr[index].p_type   = (*seg).type();
    345     phdr[index].p_flags  = (*seg).flag();
    346     phdr[index].p_offset = (*seg).offset();
    347     phdr[index].p_vaddr  = (*seg).vaddr();
    348     phdr[index].p_paddr  = (*seg).paddr();
    349     phdr[index].p_filesz = (*seg).filesz();
    350     phdr[index].p_memsz  = (*seg).memsz();
    351     phdr[index].p_align  = (*seg).align();
    352   }
    353 }
    354 
    355 /// emitShStrTab - emit section string table
    356 void
    357 ELFObjectWriter::emitShStrTab(const LDSection& pShStrTab,
    358                               const Module& pModule,
    359                               MemoryArea& pOutput)
    360 {
    361   // write out data
    362   MemoryRegion* region = pOutput.request(pShStrTab.offset(), pShStrTab.size());
    363   unsigned char* data = region->start();
    364   size_t shstrsize = 0;
    365   Module::const_iterator section, sectEnd = pModule.end();
    366   for (section = pModule.begin(); section != sectEnd; ++section) {
    367     strcpy((char*)(data + shstrsize), (*section)->name().data());
    368     shstrsize += (*section)->name().size() + 1;
    369   }
    370 }
    371 
    372 /// emitSectionData
    373 void
    374 ELFObjectWriter::emitSectionData(const LDSection& pSection,
    375                                  MemoryRegion& pRegion) const
    376 {
    377   const SectionData* sd = NULL;
    378   switch (pSection.kind()) {
    379     case LDFileFormat::Relocation:
    380       assert(pSection.hasRelocData());
    381       return;
    382     case LDFileFormat::EhFrame:
    383       assert(pSection.hasEhFrame());
    384       sd = &pSection.getEhFrame()->getSectionData();
    385       break;
    386     default:
    387       assert(pSection.hasSectionData());
    388       sd = pSection.getSectionData();
    389       break;
    390   }
    391   emitSectionData(*sd, pRegion);
    392 }
    393 
    394 /// emitRelocation
    395 void ELFObjectWriter::emitRelocation(const LinkerConfig& pConfig,
    396                                      const LDSection& pSection,
    397                                      MemoryRegion& pRegion) const
    398 {
    399   const RelocData* sect_data = pSection.getRelocData();
    400   assert(NULL != sect_data && "SectionData is NULL in emitRelocation!");
    401 
    402   if (pSection.type() == SHT_REL) {
    403     if (pConfig.targets().is32Bits())
    404       emitRel<32>(pConfig, *sect_data, pRegion);
    405     else if (pConfig.targets().is64Bits())
    406       emitRel<64>(pConfig, *sect_data, pRegion);
    407     else {
    408       fatal(diag::unsupported_bitclass) << pConfig.targets().triple().str()
    409                                         << pConfig.targets().bitclass();
    410     }
    411   } else if (pSection.type() == SHT_RELA) {
    412     if (pConfig.targets().is32Bits())
    413       emitRela<32>(pConfig, *sect_data, pRegion);
    414     else if (pConfig.targets().is64Bits())
    415       emitRela<64>(pConfig, *sect_data, pRegion);
    416     else {
    417       fatal(diag::unsupported_bitclass) << pConfig.targets().triple().str()
    418                                         << pConfig.targets().bitclass();
    419     }
    420   } else
    421     llvm::report_fatal_error("unsupported relocation section type!");
    422 }
    423 
    424 
    425 // emitRel - emit ElfXX_Rel
    426 template<size_t SIZE>
    427 void ELFObjectWriter::emitRel(const LinkerConfig& pConfig,
    428                               const RelocData& pRelocData,
    429                               MemoryRegion& pRegion) const
    430 {
    431   typedef typename ELFSizeTraits<SIZE>::Rel  ElfXX_Rel;
    432   typedef typename ELFSizeTraits<SIZE>::Addr ElfXX_Addr;
    433   typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word;
    434 
    435   ElfXX_Rel* rel = reinterpret_cast<ElfXX_Rel*>(pRegion.start());
    436 
    437   const Relocation* relocation = 0;
    438   const FragmentRef* frag_ref = 0;
    439 
    440   for (RelocData::const_iterator it = pRelocData.begin(),
    441        ie = pRelocData.end(); it != ie; ++it, ++rel) {
    442 
    443     relocation = &(llvm::cast<Relocation>(*it));
    444     frag_ref = &(relocation->targetRef());
    445 
    446     if(LinkerConfig::DynObj == pConfig.codeGenType() ||
    447        LinkerConfig::Exec == pConfig.codeGenType()) {
    448       rel->r_offset = static_cast<ElfXX_Addr>(
    449                       frag_ref->frag()->getParent()->getSection().addr() +
    450                       frag_ref->getOutputOffset());
    451     }
    452     else {
    453       rel->r_offset = static_cast<ElfXX_Addr>(frag_ref->getOutputOffset());
    454     }
    455     ElfXX_Word Index;
    456     if( relocation->symInfo() == NULL )
    457       Index = 0;
    458     else
    459       Index = static_cast<ElfXX_Word>(
    460               target().getSymbolIdx(relocation->symInfo()->outSymbol()));
    461 
    462     rel->setSymbolAndType(Index, relocation->type());
    463   }
    464 }
    465 
    466 // emitRela - emit ElfXX_Rela
    467 template<size_t SIZE>
    468 void ELFObjectWriter::emitRela(const LinkerConfig& pConfig,
    469                                const RelocData& pRelocData,
    470                                MemoryRegion& pRegion) const
    471 {
    472   typedef typename ELFSizeTraits<SIZE>::Rela ElfXX_Rela;
    473   typedef typename ELFSizeTraits<SIZE>::Addr ElfXX_Addr;
    474   typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word;
    475 
    476   ElfXX_Rela* rel = reinterpret_cast<ElfXX_Rela*>(pRegion.start());
    477 
    478   const Relocation* relocation = 0;
    479   const FragmentRef* frag_ref = 0;
    480 
    481   for (RelocData::const_iterator it = pRelocData.begin(),
    482        ie = pRelocData.end(); it != ie; ++it, ++rel) {
    483 
    484     relocation = &(llvm::cast<Relocation>(*it));
    485     frag_ref = &(relocation->targetRef());
    486 
    487     if(LinkerConfig::DynObj == pConfig.codeGenType() ||
    488        LinkerConfig::Exec == pConfig.codeGenType()) {
    489       rel->r_offset = static_cast<ElfXX_Addr>(
    490                       frag_ref->frag()->getParent()->getSection().addr() +
    491                       frag_ref->getOutputOffset());
    492     }
    493     else {
    494       rel->r_offset = static_cast<ElfXX_Addr>(frag_ref->getOutputOffset());
    495     }
    496 
    497     ElfXX_Word Index;
    498     if( relocation->symInfo() == NULL )
    499       Index = 0;
    500     else
    501       Index = static_cast<ElfXX_Word>(
    502               target().getSymbolIdx(relocation->symInfo()->outSymbol()));
    503 
    504     rel->setSymbolAndType(Index, relocation->type());
    505     rel->r_addend = relocation->addend();
    506   }
    507 }
    508 
    509 
    510 /// getSectEntrySize - compute ElfXX_Shdr::sh_entsize
    511 template<size_t SIZE>
    512 uint64_t ELFObjectWriter::getSectEntrySize(const LDSection& pSection) const
    513 {
    514   typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word;
    515   typedef typename ELFSizeTraits<SIZE>::Sym  ElfXX_Sym;
    516   typedef typename ELFSizeTraits<SIZE>::Rel  ElfXX_Rel;
    517   typedef typename ELFSizeTraits<SIZE>::Rela ElfXX_Rela;
    518   typedef typename ELFSizeTraits<SIZE>::Dyn  ElfXX_Dyn;
    519 
    520   if (llvm::ELF::SHT_DYNSYM == pSection.type() ||
    521       llvm::ELF::SHT_SYMTAB == pSection.type())
    522     return sizeof(ElfXX_Sym);
    523   if (llvm::ELF::SHT_REL == pSection.type())
    524     return sizeof(ElfXX_Rel);
    525   if (llvm::ELF::SHT_RELA == pSection.type())
    526     return sizeof(ElfXX_Rela);
    527   if (llvm::ELF::SHT_HASH     == pSection.type() ||
    528       llvm::ELF::SHT_GNU_HASH == pSection.type())
    529     return sizeof(ElfXX_Word);
    530   if (llvm::ELF::SHT_DYNAMIC == pSection.type())
    531     return sizeof(ElfXX_Dyn);
    532   return 0x0;
    533 }
    534 
    535 /// getSectLink - compute ElfXX_Shdr::sh_link
    536 uint64_t ELFObjectWriter::getSectLink(const LDSection& pSection,
    537                                       const LinkerConfig& pConfig) const
    538 {
    539   if (llvm::ELF::SHT_SYMTAB == pSection.type())
    540     return target().getOutputFormat()->getStrTab().index();
    541   if (llvm::ELF::SHT_DYNSYM == pSection.type())
    542     return target().getOutputFormat()->getDynStrTab().index();
    543   if (llvm::ELF::SHT_DYNAMIC == pSection.type())
    544     return target().getOutputFormat()->getDynStrTab().index();
    545   if (llvm::ELF::SHT_HASH     == pSection.type() ||
    546       llvm::ELF::SHT_GNU_HASH == pSection.type())
    547     return target().getOutputFormat()->getDynSymTab().index();
    548   if (llvm::ELF::SHT_REL == pSection.type() ||
    549       llvm::ELF::SHT_RELA == pSection.type()) {
    550     if (LinkerConfig::Object == pConfig.codeGenType())
    551       return target().getOutputFormat()->getSymTab().index();
    552     else
    553       return target().getOutputFormat()->getDynSymTab().index();
    554   }
    555   // FIXME: currently we link ARM_EXIDX section to output text section here
    556   if (llvm::ELF::SHT_ARM_EXIDX == pSection.type())
    557     return target().getOutputFormat()->getText().index();
    558   return llvm::ELF::SHN_UNDEF;
    559 }
    560 
    561 /// getSectInfo - compute ElfXX_Shdr::sh_info
    562 uint64_t ELFObjectWriter::getSectInfo(const LDSection& pSection) const
    563 {
    564   if (llvm::ELF::SHT_SYMTAB == pSection.type() ||
    565       llvm::ELF::SHT_DYNSYM == pSection.type())
    566     return pSection.getInfo();
    567 
    568   if (llvm::ELF::SHT_REL == pSection.type() ||
    569       llvm::ELF::SHT_RELA == pSection.type()) {
    570     const LDSection* info_link = pSection.getLink();
    571     if (NULL != info_link)
    572       return info_link->index();
    573   }
    574 
    575   return 0x0;
    576 }
    577 
    578 /// getLastStartOffset
    579 template<>
    580 uint64_t ELFObjectWriter::getLastStartOffset<32>(const Module& pModule) const
    581 {
    582   const LDSection* lastSect = pModule.back();
    583   assert(lastSect != NULL);
    584   return Align<32>(lastSect->offset() + lastSect->size());
    585 }
    586 
    587 /// getLastStartOffset
    588 template<>
    589 uint64_t ELFObjectWriter::getLastStartOffset<64>(const Module& pModule) const
    590 {
    591   const LDSection* lastSect = pModule.back();
    592   assert(lastSect != NULL);
    593   return Align<64>(lastSect->offset() + lastSect->size());
    594 }
    595 
    596 /// emitSectionData
    597 void ELFObjectWriter::emitSectionData(const SectionData& pSD,
    598                                       MemoryRegion& pRegion) const
    599 {
    600   SectionData::const_iterator fragIter, fragEnd = pSD.end();
    601   size_t cur_offset = 0;
    602   for (fragIter = pSD.begin(); fragIter != fragEnd; ++fragIter) {
    603     size_t size = fragIter->size();
    604     switch(fragIter->getKind()) {
    605       case Fragment::Region: {
    606         const RegionFragment& region_frag = llvm::cast<RegionFragment>(*fragIter);
    607         const uint8_t* from = region_frag.getRegion().start();
    608         memcpy(pRegion.getBuffer(cur_offset), from, size);
    609         break;
    610       }
    611       case Fragment::Alignment: {
    612         // TODO: emit values with different sizes (> 1 byte), and emit nops
    613         const AlignFragment& align_frag = llvm::cast<AlignFragment>(*fragIter);
    614         uint64_t count = size / align_frag.getValueSize();
    615         switch (align_frag.getValueSize()) {
    616           case 1u:
    617             std::memset(pRegion.getBuffer(cur_offset),
    618                         align_frag.getValue(),
    619                         count);
    620             break;
    621           default:
    622             llvm::report_fatal_error("unsupported value size for align fragment emission yet.\n");
    623             break;
    624         }
    625         break;
    626       }
    627       case Fragment::Fillment: {
    628         const FillFragment& fill_frag = llvm::cast<FillFragment>(*fragIter);
    629         if (0 == size ||
    630             0 == fill_frag.getValueSize() ||
    631             0 == fill_frag.size()) {
    632           // ignore virtual fillment
    633           break;
    634         }
    635 
    636         uint64_t num_tiles = fill_frag.size() / fill_frag.getValueSize();
    637         for (uint64_t i = 0; i != num_tiles; ++i) {
    638           std::memset(pRegion.getBuffer(cur_offset),
    639                       fill_frag.getValue(),
    640                       fill_frag.getValueSize());
    641         }
    642         break;
    643       }
    644       case Fragment::Stub: {
    645         const Stub& stub_frag = llvm::cast<Stub>(*fragIter);
    646         memcpy(pRegion.getBuffer(cur_offset), stub_frag.getContent(), size);
    647         break;
    648       }
    649       case Fragment::Null: {
    650         assert(0x0 == size);
    651         break;
    652       }
    653       case Fragment::Target:
    654         llvm::report_fatal_error("Target fragment should not be in a regular section.\n");
    655         break;
    656       default:
    657         llvm::report_fatal_error("invalid fragment should not be in a regular section.\n");
    658         break;
    659     }
    660     cur_offset += size;
    661   }
    662 }
    663 
    664