Home | History | Annotate | Download | only in LD
      1 //===- ELFDynObjWriter.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/ELFDynObjWriter.h>
     10 #include <mcld/LD/LDSymbol.h>
     11 #include <mcld/Target/GNULDBackend.h>
     12 #include <mcld/MC/MCLDInput.h>
     13 #include <mcld/MC/MCLDOutput.h>
     14 #include <mcld/MC/MCLDInfo.h>
     15 #include <mcld/MC/MCLinker.h>
     16 #include <llvm/Support/ELF.h>
     17 #include <vector>
     18 
     19 using namespace llvm;
     20 using namespace mcld;
     21 
     22 
     23 //==========================
     24 // ELFDynObjWriter
     25 ELFDynObjWriter::ELFDynObjWriter(GNULDBackend& pBackend, MCLinker& pLinker)
     26   : DynObjWriter(pBackend),
     27     ELFWriter(pBackend),
     28     m_Backend(pBackend),
     29     m_Linker(pLinker) {
     30 
     31 }
     32 
     33 ELFDynObjWriter::~ELFDynObjWriter()
     34 {
     35 }
     36 
     37 llvm::error_code ELFDynObjWriter::writeDynObj(Output& pOutput)
     38 {
     39   // Write out name pool sections: .dynsym, .dynstr, .hash
     40   target().emitDynNamePools(pOutput,
     41                             m_Linker.getOutputSymbols(),
     42                             m_Linker.getLayout(),
     43                             m_Linker.getLDInfo());
     44 
     45   // Write out name pool sections: .symtab, .strtab
     46   target().emitRegNamePools(pOutput,
     47                             m_Linker.getOutputSymbols(),
     48                             m_Linker.getLayout(),
     49                             m_Linker.getLDInfo());
     50 
     51   // Write out regular ELF sections
     52   unsigned int secIdx = 0;
     53   unsigned int secEnd = pOutput.context()->numOfSections();
     54   for (secIdx = 0; secIdx < secEnd; ++secIdx) {
     55     LDSection* sect = pOutput.context()->getSection(secIdx);
     56     MemoryRegion* region = NULL;
     57     // request output region
     58     switch(sect->kind()) {
     59       case LDFileFormat::Regular:
     60       case LDFileFormat::Relocation:
     61       case LDFileFormat::Target: {
     62         region = pOutput.memArea()->request(sect->offset(), sect->size());
     63         if (NULL == region) {
     64           llvm::report_fatal_error(llvm::Twine("cannot get enough memory region for output section[") +
     65                                    llvm::Twine(secIdx) +
     66                                    llvm::Twine("] - `") +
     67                                    sect->name() +
     68                                    llvm::Twine("'.\n"));
     69         }
     70         break;
     71       }
     72       case LDFileFormat::Null:
     73       case LDFileFormat::NamePool:
     74       case LDFileFormat::BSS:
     75       case LDFileFormat::Debug:
     76       case LDFileFormat::Note:
     77       case LDFileFormat::MetaData:
     78       case LDFileFormat::Exception:
     79       case LDFileFormat::Version:
     80         // ignore these sections
     81         continue;
     82       default: {
     83         llvm::errs() << "WARNING: unsupported section kind: "
     84                      << sect->kind()
     85                      << " of section "
     86                      << sect->name()
     87                      << ".\n";
     88         continue;
     89       }
     90     }
     91 
     92     // write out sections with data
     93     switch(sect->kind()) {
     94       case LDFileFormat::Regular: {
     95         emitSectionData(m_Linker.getLayout(), *sect, *region);
     96         break;
     97       }
     98       case LDFileFormat::Relocation:
     99         emitRelocation(m_Linker.getLayout(), pOutput, *sect, *region);
    100         break;
    101       case LDFileFormat::Target:
    102         target().emitSectionData(pOutput, *sect, m_Linker.getLDInfo(), *region);
    103         break;
    104       default:
    105         continue;
    106     }
    107   } // end of for loop
    108 
    109   if (32 == target().bitclass()) {
    110     // Write out ELF header
    111     // Write out section header table
    112     emitELF32ShStrTab(pOutput, m_Linker);
    113 
    114     writeELF32Header(m_Linker.getLDInfo(),
    115                      m_Linker.getLayout(),
    116                      target(),
    117                      pOutput);
    118 
    119     emitELF32SectionHeader(pOutput, m_Linker);
    120   }
    121   else if (64 == target().bitclass()) {
    122     // Write out ELF header
    123     // Write out section header table
    124     emitELF64ShStrTab(pOutput, m_Linker);
    125 
    126     writeELF64Header(m_Linker.getLDInfo(),
    127                      m_Linker.getLayout(),
    128                      target(),
    129                      pOutput);
    130 
    131     emitELF64SectionHeader(pOutput, m_Linker);
    132   }
    133   else
    134     return make_error_code(errc::not_supported);
    135 
    136   return llvm::make_error_code(llvm::errc::success);
    137 }
    138 
    139