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