File: | lib/Object/IRObjectFile.cpp |
Location: | line 186, column 10 |
Description: | Assigned value is garbage or undefined |
1 | //===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===// | |||
2 | // | |||
3 | // The LLVM Compiler Infrastructure | |||
4 | // | |||
5 | // This file is distributed under the University of Illinois Open Source | |||
6 | // License. See LICENSE.TXT for details. | |||
7 | // | |||
8 | //===----------------------------------------------------------------------===// | |||
9 | // | |||
10 | // Part of the IRObjectFile class implementation. | |||
11 | // | |||
12 | //===----------------------------------------------------------------------===// | |||
13 | ||||
14 | #include "llvm/Object/IRObjectFile.h" | |||
15 | #include "RecordStreamer.h" | |||
16 | #include "llvm/Bitcode/ReaderWriter.h" | |||
17 | #include "llvm/IR/LLVMContext.h" | |||
18 | #include "llvm/IR/GVMaterializer.h" | |||
19 | #include "llvm/IR/Mangler.h" | |||
20 | #include "llvm/IR/Module.h" | |||
21 | #include "llvm/MC/MCRegisterInfo.h" | |||
22 | #include "llvm/MC/MCAsmInfo.h" | |||
23 | #include "llvm/MC/MCContext.h" | |||
24 | #include "llvm/MC/MCInstrInfo.h" | |||
25 | #include "llvm/MC/MCObjectFileInfo.h" | |||
26 | #include "llvm/MC/MCTargetAsmParser.h" | |||
27 | #include "llvm/MC/MCParser/MCAsmParser.h" | |||
28 | #include "llvm/Object/ObjectFile.h" | |||
29 | #include "llvm/Support/MemoryBuffer.h" | |||
30 | #include "llvm/Support/SourceMgr.h" | |||
31 | #include "llvm/Support/TargetRegistry.h" | |||
32 | #include "llvm/Support/raw_ostream.h" | |||
33 | using namespace llvm; | |||
34 | using namespace object; | |||
35 | ||||
36 | IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod) | |||
37 | : SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) { | |||
38 | // If we have a DataLayout, setup a mangler. | |||
39 | const DataLayout *DL = M->getDataLayout(); | |||
40 | if (!DL) | |||
41 | return; | |||
42 | ||||
43 | Mang.reset(new Mangler(DL)); | |||
44 | ||||
45 | const std::string &InlineAsm = M->getModuleInlineAsm(); | |||
46 | if (InlineAsm.empty()) | |||
47 | return; | |||
48 | ||||
49 | StringRef Triple = M->getTargetTriple(); | |||
50 | std::string Err; | |||
51 | const Target *T = TargetRegistry::lookupTarget(Triple, Err); | |||
52 | if (!T) | |||
53 | return; | |||
54 | ||||
55 | std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(Triple)); | |||
56 | if (!MRI) | |||
57 | return; | |||
58 | ||||
59 | std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, Triple)); | |||
60 | if (!MAI) | |||
61 | return; | |||
62 | ||||
63 | std::unique_ptr<MCSubtargetInfo> STI( | |||
64 | T->createMCSubtargetInfo(Triple, "", "")); | |||
65 | if (!STI) | |||
66 | return; | |||
67 | ||||
68 | std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo()); | |||
69 | if (!MCII) | |||
70 | return; | |||
71 | ||||
72 | MCObjectFileInfo MOFI; | |||
73 | MCContext MCCtx(MAI.get(), MRI.get(), &MOFI); | |||
74 | MOFI.InitMCObjectFileInfo(Triple, Reloc::Default, CodeModel::Default, MCCtx); | |||
75 | std::unique_ptr<RecordStreamer> Streamer(new RecordStreamer(MCCtx)); | |||
76 | ||||
77 | std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); | |||
78 | SourceMgr SrcMgr; | |||
79 | SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); | |||
80 | std::unique_ptr<MCAsmParser> Parser( | |||
81 | createMCAsmParser(SrcMgr, MCCtx, *Streamer, *MAI)); | |||
82 | ||||
83 | MCTargetOptions MCOptions; | |||
84 | std::unique_ptr<MCTargetAsmParser> TAP( | |||
85 | T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); | |||
86 | if (!TAP) | |||
87 | return; | |||
88 | ||||
89 | Parser->setTargetParser(*TAP); | |||
90 | if (Parser->Run(false)) | |||
91 | return; | |||
92 | ||||
93 | for (auto &KV : *Streamer) { | |||
94 | StringRef Key = KV.first(); | |||
95 | RecordStreamer::State Value = KV.second; | |||
96 | uint32_t Res = BasicSymbolRef::SF_None; | |||
97 | switch (Value) { | |||
98 | case RecordStreamer::NeverSeen: | |||
99 | llvm_unreachable("foo")::llvm::llvm_unreachable_internal("foo", "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224240/lib/Object/IRObjectFile.cpp" , 99); | |||
100 | case RecordStreamer::DefinedGlobal: | |||
101 | Res |= BasicSymbolRef::SF_Global; | |||
102 | break; | |||
103 | case RecordStreamer::Defined: | |||
104 | break; | |||
105 | case RecordStreamer::Global: | |||
106 | case RecordStreamer::Used: | |||
107 | Res |= BasicSymbolRef::SF_Undefined; | |||
108 | Res |= BasicSymbolRef::SF_Global; | |||
109 | break; | |||
110 | } | |||
111 | AsmSymbols.push_back( | |||
112 | std::make_pair<std::string, uint32_t>(Key, std::move(Res))); | |||
113 | } | |||
114 | } | |||
115 | ||||
116 | IRObjectFile::~IRObjectFile() { | |||
117 | } | |||
118 | ||||
119 | static GlobalValue *getGV(DataRefImpl &Symb) { | |||
120 | if ((Symb.p & 3) == 3) | |||
121 | return nullptr; | |||
122 | ||||
123 | return reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3)); | |||
124 | } | |||
125 | ||||
126 | static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) { | |||
127 | if (I == M.alias_end()) | |||
128 | return 3; | |||
129 | const GlobalValue *GV = &*I; | |||
130 | return reinterpret_cast<uintptr_t>(GV) | 2; | |||
131 | } | |||
132 | ||||
133 | static uintptr_t skipEmpty(Module::const_global_iterator I, const Module &M) { | |||
134 | if (I == M.global_end()) | |||
135 | return skipEmpty(M.alias_begin(), M); | |||
136 | const GlobalValue *GV = &*I; | |||
137 | return reinterpret_cast<uintptr_t>(GV) | 1; | |||
138 | } | |||
139 | ||||
140 | static uintptr_t skipEmpty(Module::const_iterator I, const Module &M) { | |||
141 | if (I == M.end()) | |||
142 | return skipEmpty(M.global_begin(), M); | |||
143 | const GlobalValue *GV = &*I; | |||
144 | return reinterpret_cast<uintptr_t>(GV) | 0; | |||
145 | } | |||
146 | ||||
147 | static unsigned getAsmSymIndex(DataRefImpl Symb) { | |||
148 | assert((Symb.p & uintptr_t(3)) == 3)(((Symb.p & uintptr_t(3)) == 3) ? static_cast<void> (0) : __assert_fail ("(Symb.p & uintptr_t(3)) == 3", "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224240/lib/Object/IRObjectFile.cpp" , 148, __PRETTY_FUNCTION__)); | |||
149 | uintptr_t Index = Symb.p & ~uintptr_t(3); | |||
150 | Index >>= 2; | |||
151 | return Index; | |||
152 | } | |||
153 | ||||
154 | void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const { | |||
155 | const GlobalValue *GV = getGV(Symb); | |||
156 | uintptr_t Res; | |||
| ||||
157 | ||||
158 | switch (Symb.p & 3) { | |||
159 | case 0: { | |||
160 | Module::const_iterator Iter(static_cast<const Function*>(GV)); | |||
161 | ++Iter; | |||
162 | Res = skipEmpty(Iter, *M); | |||
163 | break; | |||
164 | } | |||
165 | case 1: { | |||
166 | Module::const_global_iterator Iter(static_cast<const GlobalVariable*>(GV)); | |||
167 | ++Iter; | |||
168 | Res = skipEmpty(Iter, *M); | |||
169 | break; | |||
170 | } | |||
171 | case 2: { | |||
172 | Module::const_alias_iterator Iter(static_cast<const GlobalAlias*>(GV)); | |||
173 | ++Iter; | |||
174 | Res = skipEmpty(Iter, *M); | |||
175 | break; | |||
176 | } | |||
177 | case 3: { | |||
178 | unsigned Index = getAsmSymIndex(Symb); | |||
179 | assert(Index < AsmSymbols.size())((Index < AsmSymbols.size()) ? static_cast<void> (0) : __assert_fail ("Index < AsmSymbols.size()", "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224240/lib/Object/IRObjectFile.cpp" , 179, __PRETTY_FUNCTION__)); | |||
180 | ++Index; | |||
181 | Res = (Index << 2) | 3; | |||
182 | break; | |||
183 | } | |||
184 | } | |||
185 | ||||
186 | Symb.p = Res; | |||
| ||||
187 | } | |||
188 | ||||
189 | std::error_code IRObjectFile::printSymbolName(raw_ostream &OS, | |||
190 | DataRefImpl Symb) const { | |||
191 | const GlobalValue *GV = getGV(Symb); | |||
192 | if (!GV) { | |||
193 | unsigned Index = getAsmSymIndex(Symb); | |||
194 | assert(Index <= AsmSymbols.size())((Index <= AsmSymbols.size()) ? static_cast<void> (0 ) : __assert_fail ("Index <= AsmSymbols.size()", "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224240/lib/Object/IRObjectFile.cpp" , 194, __PRETTY_FUNCTION__)); | |||
195 | OS << AsmSymbols[Index].first; | |||
196 | return object_error::success;; | |||
197 | } | |||
198 | ||||
199 | if (Mang) | |||
200 | Mang->getNameWithPrefix(OS, GV, false); | |||
201 | else | |||
202 | OS << GV->getName(); | |||
203 | ||||
204 | return object_error::success; | |||
205 | } | |||
206 | ||||
207 | uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { | |||
208 | const GlobalValue *GV = getGV(Symb); | |||
209 | ||||
210 | if (!GV) { | |||
211 | unsigned Index = getAsmSymIndex(Symb); | |||
212 | assert(Index <= AsmSymbols.size())((Index <= AsmSymbols.size()) ? static_cast<void> (0 ) : __assert_fail ("Index <= AsmSymbols.size()", "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224240/lib/Object/IRObjectFile.cpp" , 212, __PRETTY_FUNCTION__)); | |||
213 | return AsmSymbols[Index].second; | |||
214 | } | |||
215 | ||||
216 | uint32_t Res = BasicSymbolRef::SF_None; | |||
217 | if (GV->isDeclarationForLinker()) | |||
218 | Res |= BasicSymbolRef::SF_Undefined; | |||
219 | if (GV->hasPrivateLinkage()) | |||
220 | Res |= BasicSymbolRef::SF_FormatSpecific; | |||
221 | if (!GV->hasLocalLinkage()) | |||
222 | Res |= BasicSymbolRef::SF_Global; | |||
223 | if (GV->hasCommonLinkage()) | |||
224 | Res |= BasicSymbolRef::SF_Common; | |||
225 | if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage()) | |||
226 | Res |= BasicSymbolRef::SF_Weak; | |||
227 | ||||
228 | if (GV->getName().startswith("llvm.")) | |||
229 | Res |= BasicSymbolRef::SF_FormatSpecific; | |||
230 | else if (auto *Var = dyn_cast<GlobalVariable>(GV)) { | |||
231 | if (Var->getSection() == StringRef("llvm.metadata")) | |||
232 | Res |= BasicSymbolRef::SF_FormatSpecific; | |||
233 | } | |||
234 | ||||
235 | return Res; | |||
236 | } | |||
237 | ||||
238 | GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) { return getGV(Symb); } | |||
239 | ||||
240 | std::unique_ptr<Module> IRObjectFile::takeModule() { return std::move(M); } | |||
241 | ||||
242 | basic_symbol_iterator IRObjectFile::symbol_begin_impl() const { | |||
243 | Module::const_iterator I = M->begin(); | |||
244 | DataRefImpl Ret; | |||
245 | Ret.p = skipEmpty(I, *M); | |||
246 | return basic_symbol_iterator(BasicSymbolRef(Ret, this)); | |||
247 | } | |||
248 | ||||
249 | basic_symbol_iterator IRObjectFile::symbol_end_impl() const { | |||
250 | DataRefImpl Ret; | |||
251 | uint64_t NumAsm = AsmSymbols.size(); | |||
252 | NumAsm <<= 2; | |||
253 | Ret.p = 3 | NumAsm; | |||
254 | return basic_symbol_iterator(BasicSymbolRef(Ret, this)); | |||
255 | } | |||
256 | ||||
257 | ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) { | |||
258 | for (const SectionRef &Sec : Obj.sections()) { | |||
259 | StringRef SecName; | |||
260 | if (std::error_code EC = Sec.getName(SecName)) | |||
261 | return EC; | |||
262 | if (SecName == ".llvmbc") { | |||
263 | StringRef SecContents; | |||
264 | if (std::error_code EC = Sec.getContents(SecContents)) | |||
265 | return EC; | |||
266 | return MemoryBufferRef(SecContents, Obj.getFileName()); | |||
267 | } | |||
268 | } | |||
269 | ||||
270 | return object_error::bitcode_section_not_found; | |||
271 | } | |||
272 | ||||
273 | ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) { | |||
274 | sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer()); | |||
275 | switch (Type) { | |||
276 | case sys::fs::file_magic::bitcode: | |||
277 | return Object; | |||
278 | case sys::fs::file_magic::elf_relocatable: | |||
279 | case sys::fs::file_magic::macho_object: | |||
280 | case sys::fs::file_magic::coff_object: { | |||
281 | ErrorOr<std::unique_ptr<ObjectFile>> ObjFile = | |||
282 | ObjectFile::createObjectFile(Object, Type); | |||
283 | if (!ObjFile) | |||
284 | return ObjFile.getError(); | |||
285 | return findBitcodeInObject(*ObjFile->get()); | |||
286 | } | |||
287 | default: | |||
288 | return object_error::invalid_file_type; | |||
289 | } | |||
290 | } | |||
291 | ||||
292 | ErrorOr<std::unique_ptr<IRObjectFile>> | |||
293 | llvm::object::IRObjectFile::create(MemoryBufferRef Object, | |||
294 | LLVMContext &Context) { | |||
295 | ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object); | |||
296 | if (!BCOrErr) | |||
297 | return BCOrErr.getError(); | |||
298 | ||||
299 | std::unique_ptr<MemoryBuffer> Buff( | |||
300 | MemoryBuffer::getMemBuffer(BCOrErr.get(), false)); | |||
301 | ||||
302 | ErrorOr<Module *> MOrErr = getLazyBitcodeModule(std::move(Buff), Context); | |||
303 | if (std::error_code EC = MOrErr.getError()) | |||
304 | return EC; | |||
305 | ||||
306 | std::unique_ptr<Module> M(MOrErr.get()); | |||
307 | return llvm::make_unique<IRObjectFile>(Object, std::move(M)); | |||
308 | } |