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