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