ELFBinaryReader.cpp revision f7ac0f19a1c8d0ad14bcf6456ce368b830fea886
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
21using namespace mcld;
22
23//===----------------------------------------------------------------------===//
24// ELFBinaryReader
25//===----------------------------------------------------------------------===//
26/// constructor
27ELFBinaryReader::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
37ELFBinaryReader::~ELFBinaryReader()
38{
39}
40
41bool 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