LLVM  3.7.0
IRObjectFile.cpp
Go to the documentation of this file.
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 
15 #include "RecordStreamer.h"
16 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/IR/GVMaterializer.h"
19 #include "llvm/IR/LLVMContext.h"
20 #include "llvm/IR/Mangler.h"
21 #include "llvm/IR/Module.h"
22 #include "llvm/MC/MCAsmInfo.h"
23 #include "llvm/MC/MCContext.h"
24 #include "llvm/MC/MCInstrInfo.h"
27 #include "llvm/MC/MCRegisterInfo.h"
30 #include "llvm/Object/ObjectFile.h"
32 #include "llvm/Support/SourceMgr.h"
35 using namespace llvm;
36 using namespace object;
37 
38 IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod)
39  : SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) {
40  Mang.reset(new Mangler());
41 
42  const std::string &InlineAsm = M->getModuleInlineAsm();
43  if (InlineAsm.empty())
44  return;
45 
46  Triple TT(M->getTargetTriple());
47  std::string Err;
48  const Target *T = TargetRegistry::lookupTarget(TT.str(), Err);
49  if (!T)
50  return;
51 
52  std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TT.str()));
53  if (!MRI)
54  return;
55 
56  std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str()));
57  if (!MAI)
58  return;
59 
60  std::unique_ptr<MCSubtargetInfo> STI(
61  T->createMCSubtargetInfo(TT.str(), "", ""));
62  if (!STI)
63  return;
64 
65  std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo());
66  if (!MCII)
67  return;
68 
69  MCObjectFileInfo MOFI;
70  MCContext MCCtx(MAI.get(), MRI.get(), &MOFI);
72  std::unique_ptr<RecordStreamer> Streamer(new RecordStreamer(MCCtx));
73  T->createNullTargetStreamer(*Streamer);
74 
75  std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm));
77  SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
78  std::unique_ptr<MCAsmParser> Parser(
79  createMCAsmParser(SrcMgr, MCCtx, *Streamer, *MAI));
80 
81  MCTargetOptions MCOptions;
82  std::unique_ptr<MCTargetAsmParser> TAP(
83  T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions));
84  if (!TAP)
85  return;
86 
87  Parser->setTargetParser(*TAP);
88  if (Parser->Run(false))
89  return;
90 
91  for (auto &KV : *Streamer) {
92  StringRef Key = KV.first();
93  RecordStreamer::State Value = KV.second;
94  uint32_t Res = BasicSymbolRef::SF_None;
95  switch (Value) {
97  llvm_unreachable("foo");
100  break;
102  break;
107  break;
108  }
109  AsmSymbols.push_back(
110  std::make_pair<std::string, uint32_t>(Key, std::move(Res)));
111  }
112 }
113 
115  }
116 
117 static GlobalValue *getGV(DataRefImpl &Symb) {
118  if ((Symb.p & 3) == 3)
119  return nullptr;
120 
121  return reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3));
122 }
123 
124 static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) {
125  if (I == M.alias_end())
126  return 3;
127  const GlobalValue *GV = &*I;
128  return reinterpret_cast<uintptr_t>(GV) | 2;
129 }
130 
131 static uintptr_t skipEmpty(Module::const_global_iterator I, const Module &M) {
132  if (I == M.global_end())
133  return skipEmpty(M.alias_begin(), M);
134  const GlobalValue *GV = &*I;
135  return reinterpret_cast<uintptr_t>(GV) | 1;
136 }
137 
138 static uintptr_t skipEmpty(Module::const_iterator I, const Module &M) {
139  if (I == M.end())
140  return skipEmpty(M.global_begin(), M);
141  const GlobalValue *GV = &*I;
142  return reinterpret_cast<uintptr_t>(GV) | 0;
143 }
144 
145 static unsigned getAsmSymIndex(DataRefImpl Symb) {
146  assert((Symb.p & uintptr_t(3)) == 3);
147  uintptr_t Index = Symb.p & ~uintptr_t(3);
148  Index >>= 2;
149  return Index;
150 }
151 
153  const GlobalValue *GV = getGV(Symb);
154  uintptr_t Res;
155 
156  switch (Symb.p & 3) {
157  case 0: {
158  Module::const_iterator Iter(static_cast<const Function*>(GV));
159  ++Iter;
160  Res = skipEmpty(Iter, *M);
161  break;
162  }
163  case 1: {
164  Module::const_global_iterator Iter(static_cast<const GlobalVariable*>(GV));
165  ++Iter;
166  Res = skipEmpty(Iter, *M);
167  break;
168  }
169  case 2: {
170  Module::const_alias_iterator Iter(static_cast<const GlobalAlias*>(GV));
171  ++Iter;
172  Res = skipEmpty(Iter, *M);
173  break;
174  }
175  case 3: {
176  unsigned Index = getAsmSymIndex(Symb);
177  assert(Index < AsmSymbols.size());
178  ++Index;
179  Res = (Index << 2) | 3;
180  break;
181  }
182  default:
183  llvm_unreachable("unreachable case");
184  }
185 
186  Symb.p = Res;
187 }
188 
190  DataRefImpl Symb) const {
191  const GlobalValue *GV = getGV(Symb);
192  if (!GV) {
193  unsigned Index = getAsmSymIndex(Symb);
194  assert(Index <= AsmSymbols.size());
195  OS << AsmSymbols[Index].first;
196  return std::error_code();
197  }
198 
199  if (GV->hasDLLImportStorageClass())
200  OS << "__imp_";
201 
202  if (Mang)
203  Mang->getNameWithPrefix(OS, GV, false);
204  else
205  OS << GV->getName();
206 
207  return std::error_code();
208 }
209 
211  const GlobalValue *GV = getGV(Symb);
212 
213  if (!GV) {
214  unsigned Index = getAsmSymIndex(Symb);
215  assert(Index <= AsmSymbols.size());
216  return AsmSymbols[Index].second;
217  }
218 
219  uint32_t Res = BasicSymbolRef::SF_None;
220  if (GV->isDeclarationForLinker())
222  if (GV->hasPrivateLinkage())
224  if (!GV->hasLocalLinkage())
226  if (GV->hasCommonLinkage())
228  if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage())
230 
231  if (GV->getName().startswith("llvm."))
233  else if (auto *Var = dyn_cast<GlobalVariable>(GV)) {
234  if (Var->getSection() == StringRef("llvm.metadata"))
236  }
237 
238  return Res;
239 }
240 
242 
243 std::unique_ptr<Module> IRObjectFile::takeModule() { return std::move(M); }
244 
246  Module::const_iterator I = M->begin();
248  Ret.p = skipEmpty(I, *M);
249  return basic_symbol_iterator(BasicSymbolRef(Ret, this));
250 }
251 
254  uint64_t NumAsm = AsmSymbols.size();
255  NumAsm <<= 2;
256  Ret.p = 3 | NumAsm;
257  return basic_symbol_iterator(BasicSymbolRef(Ret, this));
258 }
259 
261  for (const SectionRef &Sec : Obj.sections()) {
262  StringRef SecName;
263  if (std::error_code EC = Sec.getName(SecName))
264  return EC;
265  if (SecName == ".llvmbc") {
266  StringRef SecContents;
267  if (std::error_code EC = Sec.getContents(SecContents))
268  return EC;
269  return MemoryBufferRef(SecContents, Obj.getFileName());
270  }
271  }
272 
274 }
275 
278  switch (Type) {
280  return Object;
285  ObjectFile::createObjectFile(Object, Type);
286  if (!ObjFile)
287  return ObjFile.getError();
288  return findBitcodeInObject(*ObjFile->get());
289  }
290  default:
292  }
293 }
294 
297  LLVMContext &Context) {
298  ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
299  if (!BCOrErr)
300  return BCOrErr.getError();
301 
302  std::unique_ptr<MemoryBuffer> Buff(
303  MemoryBuffer::getMemBuffer(BCOrErr.get(), false));
304 
306  getLazyBitcodeModule(std::move(Buff), Context, nullptr,
307  /*ShouldLazyLoadMetadata*/ true);
308  if (std::error_code EC = MOrErr.getError())
309  return EC;
310 
311  std::unique_ptr<Module> &M = MOrErr.get();
312  return llvm::make_unique<IRObjectFile>(Object, std::move(M));
313 }
basic_symbol_iterator symbol_begin_impl() const override
basic_symbol_iterator symbol_end_impl() const override
std::error_code getError() const
Definition: ErrorOr.h:178
Represents either an error or a value T.
Definition: ErrorOr.h:82
IRObjectFile(MemoryBufferRef Object, std::unique_ptr< Module > M)
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:114
SourceMgr SrcMgr
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
MCRegisterInfo * createMCRegInfo(StringRef TT) const
createMCRegInfo - Create a MCRegisterInfo implementation.
static GlobalValue * getGV(DataRefImpl &Symb)
This class is the base class for all object file types.
Definition: ObjectFile.h:176
ELF Relocatable object file.
Definition: FileSystem.h:230
static const Target * lookupTarget(const std::string &Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:188
MCInstrInfo * createMCInstrInfo() const
createMCInstrInfo - Create a MCInstrInfo implementation.
MCSubtargetInfo * createMCSubtargetInfo(StringRef TheTriple, StringRef CPU, StringRef Features) const
createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
GlobalValue * getSymbolGV(DataRefImpl Symb)
bool hasCommonLinkage() const
Definition: GlobalValue.h:282
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
static ErrorOr< std::unique_ptr< IRObjectFile > > create(MemoryBufferRef Object, LLVMContext &Context)
std::unique_ptr< Module > takeModule()
bool hasPrivateLinkage() const
Definition: GlobalValue.h:279
global_iterator global_begin()
Definition: Module.h:552
Context object for machine code objects.
Definition: MCContext.h:48
static unsigned getAsmSymIndex(DataRefImpl Symb)
unsigned AddNewSourceBuffer(std::unique_ptr< MemoryBuffer > F, SMLoc IncludeLoc)
Add a new source buffer to this source manager.
Definition: SourceMgr.h:123
MCTargetAsmParser * createMCAsmParser(MCSubtargetInfo &STI, MCAsmParser &Parser, const MCInstrInfo &MII, const MCTargetOptions &Options) const
createMCAsmParser - Create a target specific assembly parser.
static ErrorOr< MemoryBufferRef > findBitcodeInMemBuffer(MemoryBufferRef Object)
Finds and returns bitcode in the given memory buffer (which may be either a bitcode file or a native ...
std::error_code printSymbolName(raw_ostream &OS, DataRefImpl Symb) const override
static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M)
MCAsmInfo * createMCAsmInfo(const MCRegisterInfo &MRI, StringRef TheTriple) const
createMCAsmInfo - Create a MCAsmInfo implementation for the specified target triple.
alias_iterator alias_end()
Definition: Module.h:593
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:41
MCAsmParser * createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &, const MCAsmInfo &)
Create an MCAsmParser instance.
Definition: AsmParser.cpp:4840
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling...
Definition: SourceMgr.h:35
section_iterator_range sections() const
Definition: ObjectFile.h:253
bool hasWeakLinkage() const
Definition: GlobalValue.h:268
StringRef getFileName() const
Definition: Binary.cpp:35
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
Definition: Path.cpp:900
global_iterator global_end()
Definition: Module.h:554
content_iterator< BasicSymbolRef > basic_symbol_iterator
Definition: SymbolicFile.h:116
bool hasDLLImportStorageClass() const
Definition: GlobalValue.h:167
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:215
StringRef getBuffer() const
Definition: MemoryBuffer.h:157
Module.h This file contains the declarations for the Module class.
MCTargetStreamer * createNullTargetStreamer(MCStreamer &S) const
alias_iterator alias_begin()
Definition: Module.h:591
void InitMCObjectFileInfo(const Triple &TT, Reloc::Model RM, CodeModel::Model CM, MCContext &ctx)
Target - Wrapper for Target specific information.
bool hasLinkOnceLinkage() const
Definition: GlobalValue.h:264
void moveSymbolNext(DataRefImpl &Symb) const override
file_magic - An "enum class" enumeration of file types based on magic (the first N bytes of the file)...
Definition: FileSystem.h:224
iterator end()
Definition: Module.h:571
#define I(x, y, z)
Definition: MD5.cpp:54
This is a value type class that represents a single symbol in the list of symbols in the object file...
Definition: SymbolicFile.h:78
iterator begin()
Definition: Module.h:569
bool hasLocalLinkage() const
Definition: GlobalValue.h:280
static ErrorOr< MemoryBufferRef > findBitcodeInObject(const ObjectFile &Obj)
Finds and returns bitcode embedded in the given object file, or an error code if not found...
LLVM Value Representation.
Definition: Value.h:69
ErrorOr< std::unique_ptr< Module > > getLazyBitcodeModule(std::unique_ptr< MemoryBuffer > &&Buffer, LLVMContext &Context, DiagnosticHandlerFunction DiagnosticHandler=nullptr, bool ShouldLazyLoadMetadata=false)
Read the header of the specified bitcode buffer and prepare for lazy deserialization of function bodi...
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38
static ErrorOr< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
Create ObjectFile from path.
Definition: ObjectFile.cpp:102
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
Represents a location in source code.
Definition: SMLoc.h:23
bool isDeclarationForLinker() const
Definition: GlobalValue.h:344
reference get()
Definition: ErrorOr.h:175
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:69
uint32_t getSymbolFlags(DataRefImpl Symb) const override