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 using 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 }
35
isMyFormat(Input & pInput,bool & pContinue) const36 bool ELFBinaryReader::isMyFormat(Input& pInput, bool &pContinue) const
37 {
38 pContinue = true;
39 return m_Config.options().isBinaryInput();
40 }
41
readBinary(Input & pInput)42 bool 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