Home | History | Annotate | Download | only in Object
      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/ADT/STLExtras.h"
     17 #include "llvm/Bitcode/ReaderWriter.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"
     25 #include "llvm/MC/MCObjectFileInfo.h"
     26 #include "llvm/MC/MCParser/MCAsmParser.h"
     27 #include "llvm/MC/MCRegisterInfo.h"
     28 #include "llvm/MC/MCSubtargetInfo.h"
     29 #include "llvm/MC/MCTargetAsmParser.h"
     30 #include "llvm/Object/ObjectFile.h"
     31 #include "llvm/Support/MemoryBuffer.h"
     32 #include "llvm/Support/SourceMgr.h"
     33 #include "llvm/Support/TargetRegistry.h"
     34 #include "llvm/Support/raw_ostream.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);
     71   MOFI.InitMCObjectFileInfo(TT, Reloc::Default, CodeModel::Default, MCCtx);
     72   std::unique_ptr<RecordStreamer> Streamer(new RecordStreamer(MCCtx));
     73   T->createNullTargetStreamer(*Streamer);
     74 
     75   std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm));
     76   SourceMgr SrcMgr;
     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) {
     96     case RecordStreamer::NeverSeen:
     97       llvm_unreachable("foo");
     98     case RecordStreamer::DefinedGlobal:
     99       Res |= BasicSymbolRef::SF_Global;
    100       break;
    101     case RecordStreamer::Defined:
    102       break;
    103     case RecordStreamer::Global:
    104     case RecordStreamer::Used:
    105       Res |= BasicSymbolRef::SF_Undefined;
    106       Res |= BasicSymbolRef::SF_Global;
    107       break;
    108     }
    109     AsmSymbols.push_back(
    110         std::make_pair<std::string, uint32_t>(Key, std::move(Res)));
    111   }
    112 }
    113 
    114 IRObjectFile::~IRObjectFile() {
    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 
    152 void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
    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 
    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());
    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 
    210 uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
    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())
    221     Res |= BasicSymbolRef::SF_Undefined;
    222   else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage())
    223     Res |= BasicSymbolRef::SF_Hidden;
    224   if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) {
    225     if (GVar->isConstant())
    226       Res |= BasicSymbolRef::SF_Const;
    227   }
    228   if (GV->hasPrivateLinkage())
    229     Res |= BasicSymbolRef::SF_FormatSpecific;
    230   if (!GV->hasLocalLinkage())
    231     Res |= BasicSymbolRef::SF_Global;
    232   if (GV->hasCommonLinkage())
    233     Res |= BasicSymbolRef::SF_Common;
    234   if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage())
    235     Res |= BasicSymbolRef::SF_Weak;
    236 
    237   if (GV->getName().startswith("llvm."))
    238     Res |= BasicSymbolRef::SF_FormatSpecific;
    239   else if (auto *Var = dyn_cast<GlobalVariable>(GV)) {
    240     if (Var->getSection() == StringRef("llvm.metadata"))
    241       Res |= BasicSymbolRef::SF_FormatSpecific;
    242   }
    243 
    244   return Res;
    245 }
    246 
    247 GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) { return getGV(Symb); }
    248 
    249 std::unique_ptr<Module> IRObjectFile::takeModule() { return std::move(M); }
    250 
    251 basic_symbol_iterator IRObjectFile::symbol_begin_impl() const {
    252   Module::const_iterator I = M->begin();
    253   DataRefImpl Ret;
    254   Ret.p = skipEmpty(I, *M);
    255   return basic_symbol_iterator(BasicSymbolRef(Ret, this));
    256 }
    257 
    258 basic_symbol_iterator IRObjectFile::symbol_end_impl() const {
    259   DataRefImpl Ret;
    260   uint64_t NumAsm = AsmSymbols.size();
    261   NumAsm <<= 2;
    262   Ret.p = 3 | NumAsm;
    263   return basic_symbol_iterator(BasicSymbolRef(Ret, this));
    264 }
    265 
    266 ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
    267   for (const SectionRef &Sec : Obj.sections()) {
    268     StringRef SecName;
    269     if (std::error_code EC = Sec.getName(SecName))
    270       return EC;
    271     if (SecName == ".llvmbc") {
    272       StringRef SecContents;
    273       if (std::error_code EC = Sec.getContents(SecContents))
    274         return EC;
    275       return MemoryBufferRef(SecContents, Obj.getFileName());
    276     }
    277   }
    278 
    279   return object_error::bitcode_section_not_found;
    280 }
    281 
    282 ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
    283   sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
    284   switch (Type) {
    285   case sys::fs::file_magic::bitcode:
    286     return Object;
    287   case sys::fs::file_magic::elf_relocatable:
    288   case sys::fs::file_magic::macho_object:
    289   case sys::fs::file_magic::coff_object: {
    290     ErrorOr<std::unique_ptr<ObjectFile>> ObjFile =
    291         ObjectFile::createObjectFile(Object, Type);
    292     if (!ObjFile)
    293       return ObjFile.getError();
    294     return findBitcodeInObject(*ObjFile->get());
    295   }
    296   default:
    297     return object_error::invalid_file_type;
    298   }
    299 }
    300 
    301 ErrorOr<std::unique_ptr<IRObjectFile>>
    302 llvm::object::IRObjectFile::create(MemoryBufferRef Object,
    303                                    LLVMContext &Context) {
    304   ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
    305   if (!BCOrErr)
    306     return BCOrErr.getError();
    307 
    308   std::unique_ptr<MemoryBuffer> Buff(
    309       MemoryBuffer::getMemBuffer(BCOrErr.get(), false));
    310 
    311   ErrorOr<std::unique_ptr<Module>> MOrErr =
    312       getLazyBitcodeModule(std::move(Buff), Context,
    313                            /*ShouldLazyLoadMetadata*/ true);
    314   if (std::error_code EC = MOrErr.getError())
    315     return EC;
    316 
    317   std::unique_ptr<Module> &M = MOrErr.get();
    318   return llvm::make_unique<IRObjectFile>(Object, std::move(M));
    319 }
    320