Home | History | Annotate | Download | only in LD
      1 //===- ELFExecWriter.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/ELFExecWriter.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 // ELFExecWriter
     25 ELFExecWriter::ELFExecWriter(GNULDBackend& pBackend, MCLinker& pLinker)
     26   : ExecWriter(pBackend),
     27     ELFWriter(pBackend),
     28     m_Backend(pBackend),
     29     m_Linker(pLinker) {
     30 
     31 }
     32 
     33 ELFExecWriter::~ELFExecWriter()
     34 {
     35 }
     36 
     37 llvm::error_code ELFExecWriter::writeExecutable(Output& pOutput)
     38 {
     39   // write out the interpreter section: .interp
     40   target().emitInterp(pOutput, m_Linker.getLDInfo());
     41 
     42   // Write out name pool sections: .dynsym, .dynstr, .hash
     43   target().emitDynNamePools(pOutput,
     44                             m_Linker.getOutputSymbols(),
     45                             m_Linker.getLayout(),
     46                             m_Linker.getLDInfo());
     47 
     48   // Write out name pool sections: .symtab, .strtab
     49   target().emitRegNamePools(pOutput,
     50                             m_Linker.getOutputSymbols(),
     51                             m_Linker.getLayout(),
     52                             m_Linker.getLDInfo());
     53 
     54   // Write out regular ELF sections
     55   unsigned int secIdx = 0;
     56   unsigned int secEnd = pOutput.context()->numOfSections();
     57   for (secIdx = 0; secIdx < secEnd; ++secIdx) {
     58     LDSection* sect = pOutput.context()->getSection(secIdx);
     59     MemoryRegion* region = NULL;
     60     // request output region
     61     switch(sect->kind()) {
     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.memArea()->request(sect->offset(), sect->size());
     69         if (NULL == region) {
     70           llvm::report_fatal_error(llvm::Twine("cannot get enough memory region for output section[") +
     71                                    llvm::Twine(secIdx) +
     72                                    llvm::Twine("] - `") +
     73                                    sect->name() +
     74                                    llvm::Twine("'.\n"));
     75         }
     76         break;
     77       }
     78       case LDFileFormat::Null:
     79       case LDFileFormat::NamePool:
     80       case LDFileFormat::BSS:
     81       case LDFileFormat::Note:
     82       case LDFileFormat::MetaData:
     83       case LDFileFormat::Version:
     84       case LDFileFormat::EhFrameHdr:
     85         // ignore these sections
     86         continue;
     87       default: {
     88         llvm::errs() << "WARNING: unsupported section kind: "
     89                      << sect->kind()
     90                      << " of section "
     91                      << sect->name()
     92                      << ".\n";
     93         continue;
     94       }
     95     }
     96 
     97     // write out sections with data
     98     switch(sect->kind()) {
     99       case LDFileFormat::Regular:
    100       case LDFileFormat::Debug:
    101       case LDFileFormat::GCCExceptTable:
    102       case LDFileFormat::EhFrame: {
    103         // FIXME: if optimization of exception handling sections is enabled,
    104         // then we should emit these sections by the other way.
    105         emitSectionData(m_Linker.getLayout(), *sect, *region);
    106         break;
    107       }
    108       case LDFileFormat::Relocation:
    109         emitRelocation(m_Linker.getLayout(), pOutput, *sect, *region);
    110         break;
    111       case LDFileFormat::Target:
    112         target().emitSectionData(pOutput,
    113                                  *sect,
    114                                  m_Linker.getLDInfo(),
    115                                  m_Linker.getLayout(),
    116                                  *region);
    117         break;
    118       default:
    119         continue;
    120     }
    121   } // end of for loop
    122 
    123   if (32 == target().bitclass()) {
    124     // Write out ELF header
    125     // Write out section header table
    126     emitELF32ShStrTab(pOutput, m_Linker);
    127 
    128     writeELF32Header(m_Linker.getLDInfo(),
    129                      m_Linker.getLayout(),
    130                      target(),
    131                      pOutput);
    132 
    133     emitELF32ProgramHeader(pOutput, target());
    134 
    135     emitELF32SectionHeader(pOutput, m_Linker);
    136   }
    137   else if (64 == target().bitclass()) {
    138     // Write out ELF header
    139     // Write out section header table
    140     emitELF64ShStrTab(pOutput, m_Linker);
    141 
    142     writeELF64Header(m_Linker.getLDInfo(),
    143                      m_Linker.getLayout(),
    144                      target(),
    145                      pOutput);
    146 
    147     emitELF64ProgramHeader(pOutput, target());
    148 
    149     emitELF64SectionHeader(pOutput, m_Linker);
    150   }
    151   else
    152     return make_error_code(errc::not_supported);
    153 
    154   pOutput.memArea()->clear();
    155   return llvm::make_error_code(llvm::errc::success);
    156 }
    157 
    158