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   std::string mangled_name = pInput.path().filename().string();
     89   for (std::string::iterator it = mangled_name.begin(),
     90     ie = mangled_name.end(); it != ie; ++it) {
     91     if (isalnum(*it) == 0)
     92       *it = '_';
     93   }
     94 
     95   // symbol: _start
     96   m_Builder.AddSymbol(pInput,
     97                       "_binary_" + mangled_name + "_start",
     98                       ResolveInfo::NoType,
     99                       ResolveInfo::Define,
    100                       ResolveInfo::Global,
    101                       0x0,
    102                       0x0,
    103                       data_sect);
    104 
    105   // symbol: _end
    106   m_Builder.AddSymbol(pInput,
    107                       "_binary_" + mangled_name + "_end",
    108                       ResolveInfo::NoType,
    109                       ResolveInfo::Define,
    110                       ResolveInfo::Global,
    111                       0x0,
    112                       data_size,
    113                       data_sect);
    114 
    115   // symbol: _size
    116   m_Builder.AddSymbol(pInput,
    117                       "_binary_" + mangled_name + "_size",
    118                       ResolveInfo::NoType,
    119                       ResolveInfo::Define,
    120                       ResolveInfo::Global,
    121                       0x0,
    122                       data_size,
    123                       data_sect);
    124 
    125   // section: .strtab
    126   m_Builder.CreateELFHeader(pInput,
    127                             ".strtab",
    128                             LDFileFormat::NamePool,
    129                             llvm::ELF::SHT_STRTAB,
    130                             0x1);
    131 
    132   return true;
    133 }
    134