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