ELFBinaryReader.cpp revision 37b74a387bb3993387029859c2d9d051c41c724e
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
20namespace 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
35bool ELFBinaryReader::isMyFormat(Input& pInput, bool& pContinue) const {
36  pContinue = true;
37  return m_Config.options().isBinaryInput();
38}
39
40bool 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