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 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 bool ELFBinaryReader::isMyFormat(Input& pInput, bool& pContinue) const {
     36   pContinue = true;
     37   return m_Config.options().isBinaryInput();
     38 }
     39 
     40 bool ELFBinaryReader::readBinary(Input& pInput) {
     41   // section: NULL
     42   m_Builder.CreateELFHeader(
     43       pInput, "", LDFileFormat::Null, llvm::ELF::SHT_NULL, 0x0);
     44 
     45   // section: .data
     46   LDSection* data_sect =
     47       m_Builder.CreateELFHeader(pInput,
     48                                 ".data",
     49                                 LDFileFormat::DATA,
     50                                 llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC,
     51                                 0x1);
     52 
     53   SectionData* data = m_Builder.CreateSectionData(*data_sect);
     54   size_t data_size = pInput.memArea()->size();
     55   Fragment* frag = m_Builder.CreateRegion(pInput, 0x0, data_size);
     56   m_Builder.AppendFragment(*frag, *data);
     57 
     58   // section: .shstrtab
     59   m_Builder.CreateELFHeader(
     60       pInput, ".shstrtab", LDFileFormat::NamePool, llvm::ELF::SHT_STRTAB, 0x1);
     61 
     62   // section: .symtab
     63   m_Builder.CreateELFHeader(pInput,
     64                             ".symtab",
     65                             LDFileFormat::NamePool,
     66                             llvm::ELF::SHT_SYMTAB,
     67                             m_Config.targets().bitclass() / 8);
     68 
     69   // symbol: .data
     70   m_Builder.AddSymbol(pInput,
     71                       ".data",
     72                       ResolveInfo::Section,
     73                       ResolveInfo::Define,
     74                       ResolveInfo::Local,
     75                       0x0,
     76                       0x0,
     77                       data_sect);
     78 
     79   // Note: in Win32, the filename is wstring. Is it correct to convert
     80   // filename to std::string?
     81   std::string mangled_name = pInput.path().filename().native();
     82   for (std::string::iterator it = mangled_name.begin(), ie = mangled_name.end();
     83        it != ie;
     84        ++it) {
     85     if (isalnum(*it) == 0)
     86       *it = '_';
     87   }
     88 
     89   // symbol: _start
     90   m_Builder.AddSymbol(pInput,
     91                       "_binary_" + mangled_name + "_start",
     92                       ResolveInfo::NoType,
     93                       ResolveInfo::Define,
     94                       ResolveInfo::Global,
     95                       0x0,
     96                       0x0,
     97                       data_sect);
     98 
     99   // symbol: _end
    100   m_Builder.AddSymbol(pInput,
    101                       "_binary_" + mangled_name + "_end",
    102                       ResolveInfo::NoType,
    103                       ResolveInfo::Define,
    104                       ResolveInfo::Global,
    105                       0x0,
    106                       data_size,
    107                       data_sect);
    108 
    109   // symbol: _size
    110   m_Builder.AddSymbol(pInput,
    111                       "_binary_" + mangled_name + "_size",
    112                       ResolveInfo::NoType,
    113                       ResolveInfo::Define,
    114                       ResolveInfo::Global,
    115                       0x0,
    116                       data_size,
    117                       data_sect);
    118 
    119   // section: .strtab
    120   m_Builder.CreateELFHeader(
    121       pInput, ".strtab", LDFileFormat::NamePool, llvm::ELF::SHT_STRTAB, 0x1);
    122 
    123   return true;
    124 }
    125 
    126 }  // namespace mcld
    127