• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
ELFBinaryReader(GNULDBackend & pBackend,IRBuilder & pBuilder,const LinkerConfig & pConfig)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
~ELFBinaryReader()37 ELFBinaryReader::~ELFBinaryReader()
38 {
39 }
40 
readBinary(Input & pInput)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