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