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
21 using namespace mcld;
22
23 //===----------------------------------------------------------------------===//
24 // ELFBinaryReader
25 //===----------------------------------------------------------------------===//
26 /// constructor
ELFBinaryReader(GNULDBackend & pBackend,IRBuilder & pBuilder,const LinkerConfig & pConfig)27 ELFBinaryReader::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
~ELFBinaryReader()37 ELFBinaryReader::~ELFBinaryReader()
38 {
39 }
40
readBinary(Input & pInput)41 bool 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