diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:17:04 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:17:04 +0000 | 
| commit | b915e9e0fc85ba6f398b3fab0db6a81a8913af94 (patch) | |
| tree | 98b8f811c7aff2547cab8642daf372d6c59502fb /lib/Object/IRObjectFile.cpp | |
| parent | 6421cca32f69ac849537a3cff78c352195e99f1b (diff) | |
Notes
Diffstat (limited to 'lib/Object/IRObjectFile.cpp')
| -rw-r--r-- | lib/Object/IRObjectFile.cpp | 276 | 
1 files changed, 44 insertions, 232 deletions
| diff --git a/lib/Object/IRObjectFile.cpp b/lib/Object/IRObjectFile.cpp index 42c8ecd62da8..adbf0de6d1bc 100644 --- a/lib/Object/IRObjectFile.cpp +++ b/lib/Object/IRObjectFile.cpp @@ -14,7 +14,7 @@  #include "llvm/Object/IRObjectFile.h"  #include "RecordStreamer.h"  #include "llvm/ADT/STLExtras.h" -#include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/Bitcode/BitcodeReader.h"  #include "llvm/IR/GVMaterializer.h"  #include "llvm/IR/LLVMContext.h"  #include "llvm/IR/Mangler.h" @@ -35,246 +35,52 @@  using namespace llvm;  using namespace object; -IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod) -    : SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) { -  Mang.reset(new Mangler()); -  CollectAsmUndefinedRefs(Triple(M->getTargetTriple()), M->getModuleInlineAsm(), -                          [this](StringRef Name, BasicSymbolRef::Flags Flags) { -                            AsmSymbols.emplace_back(Name, std::move(Flags)); -                          }); +IRObjectFile::IRObjectFile(MemoryBufferRef Object, +                           std::vector<std::unique_ptr<Module>> Mods) +    : SymbolicFile(Binary::ID_IR, Object), Mods(std::move(Mods)) { +  for (auto &M : this->Mods) +    SymTab.addModule(M.get());  } -// Parse inline ASM and collect the list of symbols that are not defined in -// the current module. This is inspired from IRObjectFile. -void IRObjectFile::CollectAsmUndefinedRefs( -    const Triple &TT, StringRef InlineAsm, -    function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmUndefinedRefs) { -  if (InlineAsm.empty()) -    return; +IRObjectFile::~IRObjectFile() {} -  std::string Err; -  const Target *T = TargetRegistry::lookupTarget(TT.str(), Err); -  if (!T) -    return; - -  std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TT.str())); -  if (!MRI) -    return; - -  std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str())); -  if (!MAI) -    return; - -  std::unique_ptr<MCSubtargetInfo> STI( -      T->createMCSubtargetInfo(TT.str(), "", "")); -  if (!STI) -    return; - -  std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo()); -  if (!MCII) -    return; - -  MCObjectFileInfo MOFI; -  MCContext MCCtx(MAI.get(), MRI.get(), &MOFI); -  MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, CodeModel::Default, MCCtx); -  std::unique_ptr<RecordStreamer> Streamer(new RecordStreamer(MCCtx)); -  T->createNullTargetStreamer(*Streamer); - -  std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); -  SourceMgr SrcMgr; -  SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); -  std::unique_ptr<MCAsmParser> Parser( -      createMCAsmParser(SrcMgr, MCCtx, *Streamer, *MAI)); - -  MCTargetOptions MCOptions; -  std::unique_ptr<MCTargetAsmParser> TAP( -      T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); -  if (!TAP) -    return; - -  Parser->setTargetParser(*TAP); -  if (Parser->Run(false)) -    return; - -  for (auto &KV : *Streamer) { -    StringRef Key = KV.first(); -    RecordStreamer::State Value = KV.second; -    uint32_t Res = BasicSymbolRef::SF_None; -    switch (Value) { -    case RecordStreamer::NeverSeen: -      llvm_unreachable("foo"); -    case RecordStreamer::DefinedGlobal: -      Res |= BasicSymbolRef::SF_Global; -      break; -    case RecordStreamer::Defined: -      break; -    case RecordStreamer::Global: -    case RecordStreamer::Used: -      Res |= BasicSymbolRef::SF_Undefined; -      Res |= BasicSymbolRef::SF_Global; -      break; -    case RecordStreamer::GlobalWeak: -      Res |= BasicSymbolRef::SF_Weak; -      Res |= BasicSymbolRef::SF_Global; -      break; -    } -    AsmUndefinedRefs(Key, BasicSymbolRef::Flags(Res)); -  } -} - -IRObjectFile::~IRObjectFile() { - } - -static GlobalValue *getGV(DataRefImpl &Symb) { -  if ((Symb.p & 3) == 3) -    return nullptr; - -  return reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3)); -} - -static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) { -  if (I == M.alias_end()) -    return 3; -  const GlobalValue *GV = &*I; -  return reinterpret_cast<uintptr_t>(GV) | 2; -} - -static uintptr_t skipEmpty(Module::const_global_iterator I, const Module &M) { -  if (I == M.global_end()) -    return skipEmpty(M.alias_begin(), M); -  const GlobalValue *GV = &*I; -  return reinterpret_cast<uintptr_t>(GV) | 1; -} - -static uintptr_t skipEmpty(Module::const_iterator I, const Module &M) { -  if (I == M.end()) -    return skipEmpty(M.global_begin(), M); -  const GlobalValue *GV = &*I; -  return reinterpret_cast<uintptr_t>(GV) | 0; -} - -static unsigned getAsmSymIndex(DataRefImpl Symb) { -  assert((Symb.p & uintptr_t(3)) == 3); -  uintptr_t Index = Symb.p & ~uintptr_t(3); -  Index >>= 2; -  return Index; +static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb) { +  return *reinterpret_cast<ModuleSymbolTable::Symbol *>(Symb.p);  }  void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const { -  const GlobalValue *GV = getGV(Symb); -  uintptr_t Res; - -  switch (Symb.p & 3) { -  case 0: { -    Module::const_iterator Iter(static_cast<const Function*>(GV)); -    ++Iter; -    Res = skipEmpty(Iter, *M); -    break; -  } -  case 1: { -    Module::const_global_iterator Iter(static_cast<const GlobalVariable*>(GV)); -    ++Iter; -    Res = skipEmpty(Iter, *M); -    break; -  } -  case 2: { -    Module::const_alias_iterator Iter(static_cast<const GlobalAlias*>(GV)); -    ++Iter; -    Res = skipEmpty(Iter, *M); -    break; -  } -  case 3: { -    unsigned Index = getAsmSymIndex(Symb); -    assert(Index < AsmSymbols.size()); -    ++Index; -    Res = (Index << 2) | 3; -    break; -  } -  default: -    llvm_unreachable("unreachable case"); -  } - -  Symb.p = Res; +  Symb.p += sizeof(ModuleSymbolTable::Symbol);  }  std::error_code IRObjectFile::printSymbolName(raw_ostream &OS,                                                DataRefImpl Symb) const { -  const GlobalValue *GV = getGV(Symb); -  if (!GV) { -    unsigned Index = getAsmSymIndex(Symb); -    assert(Index <= AsmSymbols.size()); -    OS << AsmSymbols[Index].first; -    return std::error_code(); -  } - -  if (GV->hasDLLImportStorageClass()) -    OS << "__imp_"; - -  if (Mang) -    Mang->getNameWithPrefix(OS, GV, false); -  else -    OS << GV->getName(); - +  SymTab.printSymbolName(OS, getSym(Symb));    return std::error_code();  }  uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { -  const GlobalValue *GV = getGV(Symb); - -  if (!GV) { -    unsigned Index = getAsmSymIndex(Symb); -    assert(Index <= AsmSymbols.size()); -    return AsmSymbols[Index].second; -  } - -  uint32_t Res = BasicSymbolRef::SF_None; -  if (GV->isDeclarationForLinker()) -    Res |= BasicSymbolRef::SF_Undefined; -  else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage()) -    Res |= BasicSymbolRef::SF_Hidden; -  if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { -    if (GVar->isConstant()) -      Res |= BasicSymbolRef::SF_Const; -  } -  if (GV->hasPrivateLinkage()) -    Res |= BasicSymbolRef::SF_FormatSpecific; -  if (!GV->hasLocalLinkage()) -    Res |= BasicSymbolRef::SF_Global; -  if (GV->hasCommonLinkage()) -    Res |= BasicSymbolRef::SF_Common; -  if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() || -      GV->hasExternalWeakLinkage()) -    Res |= BasicSymbolRef::SF_Weak; - -  if (GV->getName().startswith("llvm.")) -    Res |= BasicSymbolRef::SF_FormatSpecific; -  else if (auto *Var = dyn_cast<GlobalVariable>(GV)) { -    if (Var->getSection() == "llvm.metadata") -      Res |= BasicSymbolRef::SF_FormatSpecific; -  } - -  return Res; +  return SymTab.getSymbolFlags(getSym(Symb));  } -GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) { return getGV(Symb); } - -std::unique_ptr<Module> IRObjectFile::takeModule() { return std::move(M); } - -basic_symbol_iterator IRObjectFile::symbol_begin_impl() const { -  Module::const_iterator I = M->begin(); +basic_symbol_iterator IRObjectFile::symbol_begin() const {    DataRefImpl Ret; -  Ret.p = skipEmpty(I, *M); +  Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data());    return basic_symbol_iterator(BasicSymbolRef(Ret, this));  } -basic_symbol_iterator IRObjectFile::symbol_end_impl() const { +basic_symbol_iterator IRObjectFile::symbol_end() const {    DataRefImpl Ret; -  uint64_t NumAsm = AsmSymbols.size(); -  NumAsm <<= 2; -  Ret.p = 3 | NumAsm; +  Ret.p = reinterpret_cast<uintptr_t>(SymTab.symbols().data() + +                                      SymTab.symbols().size());    return basic_symbol_iterator(BasicSymbolRef(Ret, this));  } +StringRef IRObjectFile::getTargetTriple() const { +  // Each module must have the same target triple, so we arbitrarily access the +  // first one. +  return Mods[0]->getTargetTriple(); +} +  ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) {    for (const SectionRef &Sec : Obj.sections()) {      if (Sec.isBitcode()) { @@ -307,22 +113,28 @@ ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Ob    }  } -ErrorOr<std::unique_ptr<IRObjectFile>> -llvm::object::IRObjectFile::create(MemoryBufferRef Object, -                                   LLVMContext &Context) { +Expected<std::unique_ptr<IRObjectFile>> +IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) {    ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);    if (!BCOrErr) -    return BCOrErr.getError(); - -  std::unique_ptr<MemoryBuffer> Buff = -      MemoryBuffer::getMemBuffer(BCOrErr.get(), false); - -  ErrorOr<std::unique_ptr<Module>> MOrErr = -      getLazyBitcodeModule(std::move(Buff), Context, -                           /*ShouldLazyLoadMetadata*/ true); -  if (std::error_code EC = MOrErr.getError()) -    return EC; +    return errorCodeToError(BCOrErr.getError()); + +  Expected<std::vector<BitcodeModule>> BMsOrErr = +      getBitcodeModuleList(*BCOrErr); +  if (!BMsOrErr) +    return BMsOrErr.takeError(); + +  std::vector<std::unique_ptr<Module>> Mods; +  for (auto BM : *BMsOrErr) { +    Expected<std::unique_ptr<Module>> MOrErr = +        BM.getLazyModule(Context, /*ShouldLazyLoadMetadata*/ true, +                         /*IsImporting*/ false); +    if (!MOrErr) +      return MOrErr.takeError(); + +    Mods.push_back(std::move(*MOrErr)); +  } -  std::unique_ptr<Module> &M = MOrErr.get(); -  return llvm::make_unique<IRObjectFile>(Object, std::move(M)); +  return std::unique_ptr<IRObjectFile>( +      new IRObjectFile(*BCOrErr, std::move(Mods)));  } | 
