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