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