Home | History | Annotate | Download | only in LD
      1 //===- ELFBinaryReader.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/ELFBinaryReader.h>
     10 
     11 #include <mcld/IRBuilder.h>
     12 #include <mcld/LinkerConfig.h>
     13 #include <mcld/MC/Input.h>
     14 #include <mcld/Support/MemoryArea.h>
     15 
     16 #include <llvm/Support/ELF.h>
     17 
     18 #include <cctype>
     19 
     20 using namespace mcld;
     21 
     22 //===----------------------------------------------------------------------===//
     23 // ELFBinaryReader
     24 //===----------------------------------------------------------------------===//
     25 /// constructor
     26 ELFBinaryReader::ELFBinaryReader(IRBuilder& pBuilder,
     27                                  const LinkerConfig& pConfig)
     28   : m_Builder(pBuilder), m_Config(pConfig) {
     29 }
     30 
     31 /// destructor
     32 ELFBinaryReader::~ELFBinaryReader()
     33 {
     34 }
     35 
     36 bool ELFBinaryReader::isMyFormat(Input& pInput, bool &pContinue) const
     37 {
     38   pContinue = true;
     39   return m_Config.options().isBinaryInput();
     40 }
     41 
     42 bool ELFBinaryReader::readBinary(Input& pInput)
     43 {
     44   // section: NULL
     45   m_Builder.CreateELFHeader(pInput,
     46                             "",
     47                             LDFileFormat::Null,
     48                             llvm::ELF::SHT_NULL,
     49                             0x0);
     50 
     51   // section: .data
     52   LDSection* data_sect =
     53     m_Builder.CreateELFHeader(pInput,
     54                               ".data",
     55                               LDFileFormat::DATA,
     56                               llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC,
     57                               0x1);
     58 
     59 
     60   SectionData* data = m_Builder.CreateSectionData(*data_sect);
     61   size_t data_size = pInput.memArea()->size();
     62   Fragment* frag = m_Builder.CreateRegion(pInput, 0x0, data_size);
     63   m_Builder.AppendFragment(*frag, *data);
     64 
     65   // section: .shstrtab
     66   m_Builder.CreateELFHeader(pInput,
     67                             ".shstrtab",
     68                             LDFileFormat::NamePool,
     69                             llvm::ELF::SHT_STRTAB,
     70                             0x1);
     71 
     72   // section: .symtab
     73   m_Builder.CreateELFHeader(pInput,
     74                             ".symtab",
     75                             LDFileFormat::NamePool,
     76                             llvm::ELF::SHT_SYMTAB,
     77                             m_Config.targets().bitclass() / 8);
     78 
     79   // symbol: .data
     80   m_Builder.AddSymbol(pInput,
     81                       ".data",
     82                       ResolveInfo::Section,
     83                       ResolveInfo::Define,
     84                       ResolveInfo::Local,
     85                       0x0,
     86                       0x0,
     87                       data_sect);
     88 
     89   // Note: in Win32, the filename is wstring. Is it correct to convert
     90   // filename to std::string?
     91   std::string mangled_name = pInput.path().filename().native();
     92   for (std::string::iterator it = mangled_name.begin(),
     93     ie = mangled_name.end(); it != ie; ++it) {
     94     if (isalnum(*it) == 0)
     95       *it = '_';
     96   }
     97 
     98   // symbol: _start
     99   m_Builder.AddSymbol(pInput,
    100                       "_binary_" + mangled_name + "_start",
    101                       ResolveInfo::NoType,
    102                       ResolveInfo::Define,
    103                       ResolveInfo::Global,
    104                       0x0,
    105                       0x0,
    106                       data_sect);
    107 
    108   // symbol: _end
    109   m_Builder.AddSymbol(pInput,
    110                       "_binary_" + mangled_name + "_end",
    111                       ResolveInfo::NoType,
    112                       ResolveInfo::Define,
    113                       ResolveInfo::Global,
    114                       0x0,
    115                       data_size,
    116                       data_sect);
    117 
    118   // symbol: _size
    119   m_Builder.AddSymbol(pInput,
    120                       "_binary_" + mangled_name + "_size",
    121                       ResolveInfo::NoType,
    122                       ResolveInfo::Define,
    123                       ResolveInfo::Global,
    124                       0x0,
    125                       data_size,
    126                       data_sect);
    127 
    128   // section: .strtab
    129   m_Builder.CreateELFHeader(pInput,
    130                             ".strtab",
    131                             LDFileFormat::NamePool,
    132                             llvm::ELF::SHT_STRTAB,
    133                             0x1);
    134 
    135   return true;
    136 }
    137