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
ELFBinaryReader(IRBuilder & pBuilder,const LinkerConfig & pConfig)26 ELFBinaryReader::ELFBinaryReader(IRBuilder& pBuilder,
27                                  const LinkerConfig& pConfig)
28     : m_Builder(pBuilder), m_Config(pConfig) {
29 }
30 
31 /// destructor
~ELFBinaryReader()32 ELFBinaryReader::~ELFBinaryReader() {
33 }
34 
isMyFormat(Input & pInput,bool & pContinue) const35 bool ELFBinaryReader::isMyFormat(Input& pInput, bool& pContinue) const {
36   pContinue = true;
37   return m_Config.options().isBinaryInput();
38 }
39 
readBinary(Input & pInput)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