Beispiel #1
0
Expected<std::unique_ptr<IRObjectFile>>
IRObjectFile::create(MemoryBufferRef Object, LLVMContext &Context) {
  Expected<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
  if (!BCOrErr)
    return BCOrErr.takeError();

  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));
  }

  return std::unique_ptr<IRObjectFile>(
      new IRObjectFile(*BCOrErr, std::move(Mods)));
}
Beispiel #2
0
Error GSIStreamBuilder::finalizeMsfLayout() {
  // First we write public symbol records, then we write global symbol records.
  uint32_t PSHZero = 0;
  uint32_t GSHZero = PSH->calculateRecordByteSize();

  PSH->finalizeBuckets(PSHZero);
  GSH->finalizeBuckets(GSHZero);

  Expected<uint32_t> Idx = Msf.addStream(calculateGlobalsHashStreamSize());
  if (!Idx)
    return Idx.takeError();
  GSH->StreamIndex = *Idx;
  Idx = Msf.addStream(calculatePublicsHashStreamSize());
  if (!Idx)
    return Idx.takeError();
  PSH->StreamIndex = *Idx;

  uint32_t RecordBytes =
      GSH->calculateRecordByteSize() + PSH->calculateRecordByteSize();

  Idx = Msf.addStream(RecordBytes);
  if (!Idx)
    return Idx.takeError();
  RecordStreamIdx = *Idx;
  return Error::success();
}
Beispiel #3
0
void printDynamicSection(const ELFFile<ELFT> *Elf, StringRef Filename) {
  ArrayRef<typename ELFT::Dyn> DynamicEntries =
      unwrapOrError(Elf->dynamicEntries(), Filename);
  outs() << "Dynamic Section:\n";
  for (const typename ELFT::Dyn &Dyn : DynamicEntries) {
    if (Dyn.d_tag == ELF::DT_NULL)
      continue;

    std::string Str = Elf->getDynamicTagAsString(Dyn.d_tag);
    outs() << format("  %-21s", Str.c_str());

    const char *Fmt =
        ELFT::Is64Bits ? "0x%016" PRIx64 "\n" : "0x%08" PRIx64 "\n";
    if (Dyn.d_tag == ELF::DT_NEEDED || Dyn.d_tag == ELF::DT_RPATH ||
        Dyn.d_tag == ELF::DT_RUNPATH || Dyn.d_tag == ELF::DT_SONAME ||
        Dyn.d_tag == ELF::DT_AUXILIARY || Dyn.d_tag == ELF::DT_FILTER) {
      Expected<StringRef> StrTabOrErr = getDynamicStrTab(Elf);
      if (StrTabOrErr) {
        const char *Data = StrTabOrErr.get().data();
        outs() << (Data + Dyn.d_un.d_val) << "\n";
        continue;
      }
      warn(toString(StrTabOrErr.takeError()));
      consumeError(StrTabOrErr.takeError());
    }
    outs() << format(Fmt, (uint64_t)Dyn.d_un.d_val);
  }
}
Beispiel #4
0
// Implement the 'x' operation. This function extracts files back to the file
// system.
static void doExtract(StringRef Name, const object::Archive::Child &C) {
  // Retain the original mode.
  Expected<sys::fs::perms> ModeOrErr = C.getAccessMode();
  failIfError(ModeOrErr.takeError());
  sys::fs::perms Mode = ModeOrErr.get();

  int FD;
  failIfError(sys::fs::openFileForWrite(Name, FD, sys::fs::F_None, Mode), Name);

  {
    raw_fd_ostream file(FD, false);

    // Get the data and its length
    Expected<StringRef> BufOrErr = C.getBuffer();
    failIfError(BufOrErr.takeError());
    StringRef Data = BufOrErr.get();

    // Write the data.
    file.write(Data.data(), Data.size());
  }

  // If we're supposed to retain the original modification times, etc. do so
  // now.
  if (OriginalDates) {
    Expected<sys::TimeValue> ModTimeOrErr = C.getLastModified();
    failIfError(ModTimeOrErr.takeError());
    failIfError(
        sys::fs::setLastModificationAndAccessTime(FD, ModTimeOrErr.get()));
  }

  if (close(FD))
    fail("Could not close the file");
}
Beispiel #5
0
static bool doImportingForModule(Module &M, const ModuleSummaryIndex *Index) {
  if (SummaryFile.empty() && !Index)
    report_fatal_error("error: -function-import requires -summary-file or "
                       "file from frontend\n");
  std::unique_ptr<ModuleSummaryIndex> IndexPtr;
  if (!SummaryFile.empty()) {
    if (Index)
      report_fatal_error("error: -summary-file and index from frontend\n");
    Expected<std::unique_ptr<ModuleSummaryIndex>> IndexPtrOrErr =
        getModuleSummaryIndexForFile(SummaryFile);
    if (!IndexPtrOrErr) {
      logAllUnhandledErrors(IndexPtrOrErr.takeError(), errs(),
                            "Error loading file '" + SummaryFile + "': ");
      return false;
    }
    IndexPtr = std::move(*IndexPtrOrErr);
    Index = IndexPtr.get();
  }

  // First step is collecting the import list.
  FunctionImporter::ImportMapTy ImportList;
  ComputeCrossModuleImportForModule(M.getModuleIdentifier(), *Index,
                                    ImportList);

  // Conservatively mark all internal values as promoted. This interface is
  // only used when doing importing via the function importing pass. The pass
  // is only enabled when testing importing via the 'opt' tool, which does
  // not do the ThinLink that would normally determine what values to promote.
  for (auto &I : *Index) {
    for (auto &S : I.second) {
      if (GlobalValue::isLocalLinkage(S->linkage()))
        S->setLinkage(GlobalValue::ExternalLinkage);
    }
  }

  // Next we need to promote to global scope and rename any local values that
  // are potentially exported to other modules.
  if (renameModuleForThinLTO(M, *Index, nullptr)) {
    errs() << "Error renaming module\n";
    return false;
  }

  // Perform the import now.
  auto ModuleLoader = [&M](StringRef Identifier) {
    return loadFile(Identifier, M.getContext());
  };
  FunctionImporter Importer(*Index, ModuleLoader);
  Expected<bool> Result = Importer.importFunctions(
      M, ImportList, !DontForceImportReferencedDiscardableSymbols);

  // FIXME: Probably need to propagate Errors through the pass manager.
  if (!Result) {
    logAllUnhandledErrors(Result.takeError(), errs(),
                          "Error importing module: ");
    return false;
  }

  return *Result;
}
Beispiel #6
0
std::unique_ptr<llvm::Module> CodeGenAction::loadModule(MemoryBufferRef MBRef) {
  CompilerInstance &CI = getCompilerInstance();
  SourceManager &SM = CI.getSourceManager();

  // For ThinLTO backend invocations, ensure that the context
  // merges types based on ODR identifiers. We also need to read
  // the correct module out of a multi-module bitcode file.
  if (!CI.getCodeGenOpts().ThinLTOIndexFile.empty()) {
    VMContext->enableDebugTypeODRUniquing();

    auto DiagErrors = [&](Error E) -> std::unique_ptr<llvm::Module> {
      unsigned DiagID =
          CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0");
      handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
        CI.getDiagnostics().Report(DiagID) << EIB.message();
      });
      return {};
    };

    Expected<llvm::BitcodeModule> BMOrErr = FindThinLTOModule(MBRef);
    if (!BMOrErr)
      return DiagErrors(BMOrErr.takeError());

    Expected<std::unique_ptr<llvm::Module>> MOrErr =
        BMOrErr->parseModule(*VMContext);
    if (!MOrErr)
      return DiagErrors(MOrErr.takeError());
    return std::move(*MOrErr);
  }

  llvm::SMDiagnostic Err;
  if (std::unique_ptr<llvm::Module> M = parseIR(MBRef, Err, *VMContext))
    return M;

  // Translate from the diagnostic info to the SourceManager location if
  // available.
  // TODO: Unify this with ConvertBackendLocation()
  SourceLocation Loc;
  if (Err.getLineNo() > 0) {
    assert(Err.getColumnNo() >= 0);
    Loc = SM.translateFileLineCol(SM.getFileEntryForID(SM.getMainFileID()),
                                  Err.getLineNo(), Err.getColumnNo() + 1);
  }

  // Strip off a leading diagnostic code if there is one.
  StringRef Msg = Err.getMessage();
  if (Msg.startswith("error: "))
    Msg = Msg.substr(7);

  unsigned DiagID =
      CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0");

  CI.getDiagnostics().Report(Loc, DiagID) << Msg;
  return {};
}
Beispiel #7
0
extern "C" LLVMRustResult
LLVMRustWriteArchive(char *Dst,
                     size_t NumMembers,
                     const LLVMRustArchiveMemberRef *NewMembers,
                     bool WriteSymbtab,
                     LLVMRustArchiveKind rust_kind) {

#if LLVM_VERSION_LE(3, 8)
  std::vector<NewArchiveIterator> Members;
#else
  std::vector<NewArchiveMember> Members;
#endif
  auto Kind = from_rust(rust_kind);

  for (size_t i = 0; i < NumMembers; i++) {
    auto Member = NewMembers[i];
    assert(Member->name);
    if (Member->filename) {
#if LLVM_VERSION_GE(3, 9)
      Expected<NewArchiveMember> MOrErr = NewArchiveMember::getFile(Member->filename, true);
      if (!MOrErr) {
        LLVMRustSetLastError(toString(MOrErr.takeError()).c_str());
        return LLVMRustResult::Failure;
      }
      Members.push_back(std::move(*MOrErr));
#elif LLVM_VERSION_EQ(3, 8)
      Members.push_back(NewArchiveIterator(Member->filename));
#else
      Members.push_back(NewArchiveIterator(Member->filename, Member->name));
#endif
    } else {
#if LLVM_VERSION_LE(3, 8)
      Members.push_back(NewArchiveIterator(Member->child, Member->name));
#else
      Expected<NewArchiveMember> MOrErr = NewArchiveMember::getOldMember(Member->child, true);
      if (!MOrErr) {
        LLVMRustSetLastError(toString(MOrErr.takeError()).c_str());
        return LLVMRustResult::Failure;
      }
      Members.push_back(std::move(*MOrErr));
#endif
    }
  }
#if LLVM_VERSION_GE(3, 8)
  auto pair = writeArchive(Dst, Members, WriteSymbtab, Kind, true, false);
#else
  auto pair = writeArchive(Dst, Members, WriteSymbtab, Kind, true);
#endif
  if (!pair.second)
    return LLVMRustResult::Success;
  LLVMRustSetLastError(pair.second.message().c_str());
  return LLVMRustResult::Failure;
}
Beispiel #8
0
static Expected<CompileUnitIdentifiers> getCUIdentifiers(StringRef Abbrev,
                                                         StringRef Info,
                                                         StringRef StrOffsets,
                                                         StringRef Str) {
  uint32_t Offset = 0;
  DataExtractor InfoData(Info, true, 0);
  InfoData.getU32(&Offset); // Length
  uint16_t Version = InfoData.getU16(&Offset);
  InfoData.getU32(&Offset); // Abbrev offset (should be zero)
  uint8_t AddrSize = InfoData.getU8(&Offset);

  uint32_t AbbrCode = InfoData.getULEB128(&Offset);

  DataExtractor AbbrevData(Abbrev, true, 0);
  uint32_t AbbrevOffset = getCUAbbrev(Abbrev, AbbrCode);
  uint64_t Tag = AbbrevData.getULEB128(&AbbrevOffset);
  if (Tag != dwarf::DW_TAG_compile_unit)
    return make_error<DWPError>("top level DIE is not a compile unit");
  // DW_CHILDREN
  AbbrevData.getU8(&AbbrevOffset);
  uint32_t Name;
  uint32_t Form;
  CompileUnitIdentifiers ID;
  while ((Name = AbbrevData.getULEB128(&AbbrevOffset)) |
             (Form = AbbrevData.getULEB128(&AbbrevOffset)) &&
         (Name != 0 || Form != 0)) {
    switch (Name) {
    case dwarf::DW_AT_name: {
      Expected<const char *> EName =
          getIndexedString(Form, InfoData, Offset, StrOffsets, Str);
      if (!EName)
        return EName.takeError();
      ID.Name = *EName;
      break;
    }
    case dwarf::DW_AT_GNU_dwo_name: {
      Expected<const char *> EName =
          getIndexedString(Form, InfoData, Offset, StrOffsets, Str);
      if (!EName)
        return EName.takeError();
      ID.DWOName = *EName;
      break;
    }
    case dwarf::DW_AT_GNU_dwo_id:
      ID.Signature = InfoData.getU64(&Offset);
      break;
    default:
      DWARFFormValue::skipValue(Form, InfoData, &Offset, Version, AddrSize);
    }
  }
  return ID;
}
Beispiel #9
0
/// Dumps each object file in \a MachO Universal Binary;
static void dumpMachOUniversalBinary(const MachOUniversalBinary *UBinary,
                                     ScopedPrinter &Writer) {
  for (const MachOUniversalBinary::ObjectForArch &Obj : UBinary->objects()) {
    Expected<std::unique_ptr<MachOObjectFile>> ObjOrErr = Obj.getAsObjectFile();
    if (ObjOrErr)
      dumpObject(&*ObjOrErr.get(), Writer);
    else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) {
      reportError(UBinary->getFileName(), ObjOrErr.takeError());
    }
    else if (Expected<std::unique_ptr<Archive>> AOrErr = Obj.getAsArchive())
      dumpArchive(&*AOrErr.get(), Writer);
  }
}
Beispiel #10
0
// Given a symbol sym this functions returns the address and section of it.
static std::error_code
resolveSectionAndAddress(const COFFObjectFile *Obj, const SymbolRef &Sym,
                         const coff_section *&ResolvedSection,
                         uint64_t &ResolvedAddr) {
  Expected<uint64_t> ResolvedAddrOrErr = Sym.getAddress();
  if (!ResolvedAddrOrErr)
    return errorToErrorCode(ResolvedAddrOrErr.takeError());
  ResolvedAddr = *ResolvedAddrOrErr;
  Expected<section_iterator> Iter = Sym.getSection();
  if (!Iter)
    return errorToErrorCode(Iter.takeError());
  ResolvedSection = Obj->getCOFFSection(**Iter);
  return std::error_code();
}
static bool error(Expected<T> &ResOrErr) {
  if (ResOrErr)
    return false;
  logAllUnhandledErrors(ResOrErr.takeError(), errs(),
                        "LLVMSymbolizer: error reading file: ");
  return true;
}
Beispiel #12
0
static std::string formatSymbol(const Dumper::Context &Ctx,
                                const coff_section *Section, uint64_t Offset,
                                uint32_t Displacement) {
  std::string Buffer;
  raw_string_ostream OS(Buffer);

  SymbolRef Symbol;
  if (!Ctx.ResolveSymbol(Section, Offset, Symbol, Ctx.UserData)) {
    Expected<StringRef> Name = Symbol.getName();
    if (Name) {
      OS << *Name;
      if (Displacement > 0)
        OS << format(" +0x%X (0x%" PRIX64 ")", Displacement, Offset);
      else
        OS << format(" (0x%" PRIX64 ")", Offset);
      return OS.str();
    } else {
      // TODO: Actually report errors helpfully.
      consumeError(Name.takeError());
    }
  }

  OS << format(" (0x%" PRIX64 ")", Offset);
  return OS.str();
}
Beispiel #13
0
// Upgrade a vector of bitcode modules created by an old version of LLVM by
// creating an irsymtab for them in the current format.
static Expected<FileContents> upgrade(ArrayRef<BitcodeModule> BMs) {
  FileContents FC;

  LLVMContext Ctx;
  std::vector<Module *> Mods;
  std::vector<std::unique_ptr<Module>> OwnedMods;
  for (auto BM : BMs) {
    Expected<std::unique_ptr<Module>> MOrErr =
        BM.getLazyModule(Ctx, /*ShouldLazyLoadMetadata*/ true,
                         /*IsImporting*/ false);
    if (!MOrErr)
      return MOrErr.takeError();

    Mods.push_back(MOrErr->get());
    OwnedMods.push_back(std::move(*MOrErr));
  }

  StringTableBuilder StrtabBuilder(StringTableBuilder::RAW);
  BumpPtrAllocator Alloc;
  if (Error E = build(Mods, FC.Symtab, StrtabBuilder, Alloc))
    return std::move(E);

  StrtabBuilder.finalizeInOrder();
  FC.Strtab.resize(StrtabBuilder.getSize());
  StrtabBuilder.write((uint8_t *)FC.Strtab.data());

  FC.TheReader = {{FC.Symtab.data(), FC.Symtab.size()},
                  {FC.Strtab.data(), FC.Strtab.size()}};
  return std::move(FC);
}
Beispiel #14
0
/// @brief Dumps each object file in \a MachO Universal Binary;
static void dumpMachOUniversalBinary(const MachOUniversalBinary *UBinary) {
  for (const MachOUniversalBinary::ObjectForArch &Obj : UBinary->objects()) {
    Expected<std::unique_ptr<MachOObjectFile>> ObjOrErr = Obj.getAsObjectFile();
    if (ObjOrErr)
      dumpObject(&*ObjOrErr.get());
    else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) {
      std::string Buf;
      raw_string_ostream OS(Buf);
      logAllUnhandledErrors(ObjOrErr.takeError(), OS, "");
      OS.flush();
      reportError(UBinary->getFileName(), Buf);
    }
    else if (Expected<std::unique_ptr<Archive>> AOrErr = Obj.getAsArchive())
      dumpArchive(&*AOrErr.get());
  }
}
Beispiel #15
0
/// Load the current object file symbols into CurrentObjectAddresses.
void MachODebugMapParser::loadCurrentObjectFileSymbols(
    const object::MachOObjectFile &Obj) {
  CurrentObjectAddresses.clear();

  for (auto Sym : Obj.symbols()) {
    uint64_t Addr = Sym.getValue();
    Expected<StringRef> Name = Sym.getName();
    if (!Name) {
      // TODO: Actually report errors helpfully.
      consumeError(Name.takeError());
      continue;
    }
    // The value of some categories of symbols isn't meaningful. For
    // example common symbols store their size in the value field, not
    // their address. Absolute symbols have a fixed address that can
    // conflict with standard symbols. These symbols (especially the
    // common ones), might still be referenced by relocations. These
    // relocations will use the symbol itself, and won't need an
    // object file address. The object file address field is optional
    // in the DebugMap, leave it unassigned for these symbols.
    if (Sym.getFlags() & (SymbolRef::SF_Absolute | SymbolRef::SF_Common))
      CurrentObjectAddresses[*Name] = None;
    else
      CurrentObjectAddresses[*Name] = Addr;
  }
}
Beispiel #16
0
std::unique_ptr<ASTConsumer>
CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
  BackendAction BA = static_cast<BackendAction>(Act);
  std::unique_ptr<raw_pwrite_stream> OS = GetOutputStream(CI, InFile, BA);
  if (BA != Backend_EmitNothing && !OS)
    return nullptr;

  // Load bitcode modules to link with, if we need to.
  if (LinkModules.empty())
    for (const CodeGenOptions::BitcodeFileToLink &F :
         CI.getCodeGenOpts().LinkBitcodeFiles) {
      auto BCBuf = CI.getFileManager().getBufferForFile(F.Filename);
      if (!BCBuf) {
        CI.getDiagnostics().Report(diag::err_cannot_open_file)
            << F.Filename << BCBuf.getError().message();
        LinkModules.clear();
        return nullptr;
      }

      Expected<std::unique_ptr<llvm::Module>> ModuleOrErr =
          getOwningLazyBitcodeModule(std::move(*BCBuf), *VMContext);
      if (!ModuleOrErr) {
        handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) {
          CI.getDiagnostics().Report(diag::err_cannot_open_file)
              << F.Filename << EIB.message();
        });
        LinkModules.clear();
        return nullptr;
      }
      LinkModules.push_back({std::move(ModuleOrErr.get()), F.PropagateAttrs,
                             F.Internalize, F.LinkFlags});
    }

  CoverageSourceInfo *CoverageInfo = nullptr;
  // Add the preprocessor callback only when the coverage mapping is generated.
  if (CI.getCodeGenOpts().CoverageMapping) {
    CoverageInfo = new CoverageSourceInfo;
    CI.getPreprocessor().addPPCallbacks(
                                    std::unique_ptr<PPCallbacks>(CoverageInfo));
  }

  std::unique_ptr<BackendConsumer> Result(new BackendConsumer(
      BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(),
      CI.getPreprocessorOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(),
      CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, InFile,
      std::move(LinkModules), std::move(OS), *VMContext, CoverageInfo));
  BEConsumer = Result.get();

  // Enable generating macro debug info only when debug info is not disabled and
  // also macro debug info is enabled.
  if (CI.getCodeGenOpts().getDebugInfo() != codegenoptions::NoDebugInfo &&
      CI.getCodeGenOpts().MacroDebugInfo) {
    std::unique_ptr<PPCallbacks> Callbacks =
        llvm::make_unique<MacroPPCallbacks>(BEConsumer->getCodeGenerator(),
                                            CI.getPreprocessor());
    CI.getPreprocessor().addPPCallbacks(std::move(Callbacks));
  }

  return std::move(Result);
}
Beispiel #17
0
  void HandleOneRename(ASTContext &Context, const std::string &NewName,
                       const std::string &PrevName,
                       const std::vector<std::string> &USRs) {
    const SourceManager &SourceMgr = Context.getSourceManager();

    SymbolOccurrences Occurrences = tooling::getOccurrencesOfUSRs(
        USRs, PrevName, Context.getTranslationUnitDecl());
    if (PrintLocations) {
      for (const auto &Occurrence : Occurrences) {
        FullSourceLoc FullLoc(Occurrence.getNameRanges()[0].getBegin(),
                              SourceMgr);
        errs() << "clang-rename: renamed at: " << SourceMgr.getFilename(FullLoc)
               << ":" << FullLoc.getSpellingLineNumber() << ":"
               << FullLoc.getSpellingColumnNumber() << "\n";
      }
    }
    // FIXME: Support multi-piece names.
    // FIXME: better error handling (propagate error out).
    StringRef NewNameRef = NewName;
    Expected<std::vector<AtomicChange>> Change =
        createRenameReplacements(Occurrences, SourceMgr, NewNameRef);
    if (!Change) {
      llvm::errs() << "Failed to create renaming replacements for '" << PrevName
                   << "'! " << llvm::toString(Change.takeError()) << "\n";
      return;
    }
    convertChangesToFileReplacements(*Change, &FileToReplaces);
  }
Beispiel #18
0
extern "C" bool
LLVMRustLinkerAdd(RustLinker *L, char *BC, size_t Len) {
  std::unique_ptr<MemoryBuffer> Buf =
      MemoryBuffer::getMemBufferCopy(StringRef(BC, Len));

#if LLVM_VERSION_GE(4, 0)
  Expected<std::unique_ptr<Module>> SrcOrError =
      llvm::getLazyBitcodeModule(Buf->getMemBufferRef(), L->Ctx);
  if (!SrcOrError) {
    LLVMRustSetLastError(toString(SrcOrError.takeError()).c_str());
    return false;
  }

  auto Src = std::move(*SrcOrError);
#else
  ErrorOr<std::unique_ptr<Module>> Src =
      llvm::getLazyBitcodeModule(std::move(Buf), L->Ctx);
  if (!Src) {
    LLVMRustSetLastError(Src.getError().message().c_str());
    return false;
  }
#endif

#if LLVM_VERSION_GE(4, 0)
  if (L->L.linkInModule(std::move(Src))) {
#else
  if (L->L.linkInModule(std::move(Src.get()))) {
#endif
    LLVMRustSetLastError("");
    return false;
  }
  return true;
}
Beispiel #19
0
std::error_code ELFDumper<ELFT>::dumpRelocation(const RelT *Rel,
                                                const Elf_Shdr *SymTab,
                                                ELFYAML::Relocation &R) {
  R.Type = Rel->getType(Obj.isMips64EL());
  R.Offset = Rel->r_offset;
  R.Addend = 0;

  auto SymOrErr = Obj.getRelocationSymbol(Rel, SymTab);
  if (!SymOrErr)
    return errorToErrorCode(SymOrErr.takeError());
  const Elf_Sym *Sym = *SymOrErr;
  auto StrTabSec = Obj.getSection(SymTab->sh_link);
  if (!StrTabSec)
    return errorToErrorCode(StrTabSec.takeError());
  auto StrTabOrErr = Obj.getStringTable(*StrTabSec);
  if (!StrTabOrErr)
    return errorToErrorCode(StrTabOrErr.takeError());
  StringRef StrTab = *StrTabOrErr;

  if (Sym) {
    Expected<StringRef> NameOrErr = getSymbolName(Sym, StrTab, SymTab);
    if (!NameOrErr)
      return errorToErrorCode(NameOrErr.takeError());
    R.Symbol = NameOrErr.get();
  } else {
    // We have some edge cases of relocations without a symbol associated,
    // e.g. an object containing the invalid (according to the System V
    // ABI) R_X86_64_NONE reloc. Create a symbol with an empty name instead
    // of crashing.
    R.Symbol = "";
  }

  return obj2yaml_error::success;
}
Beispiel #20
0
/// diffProgram - This method executes the specified module and diffs the
/// output against the file specified by ReferenceOutputFile.  If the output
/// is different, 1 is returned.  If there is a problem with the code
/// generator (e.g., llc crashes), this will set ErrMsg.
///
Expected<bool> BugDriver::diffProgram(const Module *Program,
                                      const std::string &BitcodeFile,
                                      const std::string &SharedObject,
                                      bool RemoveBitcode) const {
  // Execute the program, generating an output file...
  Expected<std::string> Output =
      executeProgram(Program, "", BitcodeFile, SharedObject, nullptr);
  if (Error E = Output.takeError())
    return std::move(E);

  std::string Error;
  bool FilesDifferent = false;
  if (int Diff = DiffFilesWithTolerance(ReferenceOutputFile, *Output,
                                        AbsTolerance, RelTolerance, &Error)) {
    if (Diff == 2) {
      errs() << "While diffing output: " << Error << '\n';
      exit(1);
    }
    FilesDifferent = true;
  } else {
    // Remove the generated output if there are no differences.
    sys::fs::remove(*Output);
  }

  // Remove the bitcode file if we are supposed to.
  if (RemoveBitcode)
    sys::fs::remove(BitcodeFile);
  return FilesDifferent;
}
Beispiel #21
0
static bool verify(llvm::StringRef OutputFile, llvm::StringRef Arch) {
  if (OutputFile == "-") {
    llvm::errs() << "warning: verification skipped for " << Arch
                 << "because writing to stdout.\n";
    return true;
  }

  Expected<OwningBinary<Binary>> BinOrErr = createBinary(OutputFile);
  if (!BinOrErr) {
    errs() << OutputFile << ": " << toString(BinOrErr.takeError());
    return false;
  }

  Binary &Binary = *BinOrErr.get().getBinary();
  if (auto *Obj = dyn_cast<MachOObjectFile>(&Binary)) {
    raw_ostream &os = Verbose ? errs() : nulls();
    os << "Verifying DWARF for architecture: " << Arch << "\n";
    std::unique_ptr<DWARFContext> DICtx = DWARFContext::create(*Obj);
    DIDumpOptions DumpOpts;
    bool success = DICtx->verify(os, DumpOpts.noImplicitRecursion());
    if (!success)
      errs() << "error: verification failed for " << Arch << '\n';
    return success;
  }

  return false;
}
void CounterMappingContext::dump(const Counter &C, raw_ostream &OS) const {
  switch (C.getKind()) {
  case Counter::Zero:
    OS << '0';
    return;
  case Counter::CounterValueReference:
    OS << '#' << C.getCounterID();
    break;
  case Counter::Expression: {
    if (C.getExpressionID() >= Expressions.size())
      return;
    const auto &E = Expressions[C.getExpressionID()];
    OS << '(';
    dump(E.LHS, OS);
    OS << (E.Kind == CounterExpression::Subtract ? " - " : " + ");
    dump(E.RHS, OS);
    OS << ')';
    break;
  }
  }
  if (CounterValues.empty())
    return;
  Expected<int64_t> Value = evaluate(C);
  if (auto E = Value.takeError()) {
    consumeError(std::move(E));
    return;
  }
  OS << '[' << *Value << ']';
}
Beispiel #23
0
Error RawInstrProfReader<IntPtrT>::readValueProfilingData(
    InstrProfRecord &Record) {

  Record.clearValueData();
  CurValueDataSize = 0;
  // Need to match the logic in value profile dumper code in compiler-rt:
  uint32_t NumValueKinds = 0;
  for (uint32_t I = 0; I < IPVK_Last + 1; I++)
    NumValueKinds += (Data->NumValueSites[I] != 0);

  if (!NumValueKinds)
    return success();

  Expected<std::unique_ptr<ValueProfData>> VDataPtrOrErr =
      ValueProfData::getValueProfData(
          ValueDataStart, (const unsigned char *)DataBuffer->getBufferEnd(),
          getDataEndianness());

  if (Error E = VDataPtrOrErr.takeError())
    return E;

  // Note that besides deserialization, this also performs the conversion for
  // indirect call targets.  The function pointers from the raw profile are
  // remapped into function name hashes.
  VDataPtrOrErr.get()->deserializeTo(Record, &Symtab->getAddrHashMap());
  CurValueDataSize = VDataPtrOrErr.get()->getSize();
  return success();
}
Beispiel #24
0
std::error_code ELFDumper<ELFT>::dumpRelocation(const RelT *Rel,
                                                const Elf_Shdr *SymTab,
                                                ELFYAML::Relocation &R) {
  R.Type = Rel->getType(Obj.isMips64EL());
  R.Offset = Rel->r_offset;
  R.Addend = 0;

  auto SymOrErr = Obj.getRelocationSymbol(Rel, SymTab);
  if (std::error_code EC = SymOrErr.getError())
    return EC;
  const Elf_Sym *Sym = *SymOrErr;
  ErrorOr<const Elf_Shdr *> StrTabSec = Obj.getSection(SymTab->sh_link);
  if (std::error_code EC = StrTabSec.getError())
    return EC;
  ErrorOr<StringRef> StrTabOrErr = Obj.getStringTable(*StrTabSec);
  if (std::error_code EC = StrTabOrErr.getError())
    return EC;
  StringRef StrTab = *StrTabOrErr;

  Expected<StringRef> NameOrErr = Sym->getName(StrTab);
  if (!NameOrErr)
    return errorToErrorCode(NameOrErr.takeError());
  R.Symbol = NameOrErr.get();

  return obj2yaml_error::success;
}
Beispiel #25
0
static void doList(opt::InputArgList& Args) {
  // lib.exe prints the contents of the first archive file.
  std::unique_ptr<MemoryBuffer> B;
  for (auto *Arg : Args.filtered(OPT_INPUT)) {
    // Create or open the archive object.
    ErrorOr<std::unique_ptr<MemoryBuffer>> MaybeBuf =
        MemoryBuffer::getFile(Arg->getValue(), -1, false);
    fatalOpenError(errorCodeToError(MaybeBuf.getError()), Arg->getValue());

    if (identify_magic(MaybeBuf.get()->getBuffer()) == file_magic::archive) {
      B = std::move(MaybeBuf.get());
      break;
    }
  }

  // lib.exe doesn't print an error if no .lib files are passed.
  if (!B)
    return;

  Error Err = Error::success();
  object::Archive Archive(B.get()->getMemBufferRef(), Err);
  fatalOpenError(std::move(Err), B->getBufferIdentifier());

  for (auto &C : Archive.children(Err)) {
    Expected<StringRef> NameOrErr = C.getName();
    fatalOpenError(NameOrErr.takeError(), B->getBufferIdentifier());
    StringRef Name = NameOrErr.get();
    llvm::outs() << Name << '\n';
  }
  fatalOpenError(std::move(Err), B->getBufferIdentifier());
}
Beispiel #26
0
std::error_code
ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
                            StringRef StrTable, ELFYAML::Symbol &S) {
  S.Type = Sym->getType();
  S.Value = Sym->st_value;
  S.Size = Sym->st_size;
  S.Other = Sym->st_other;

  Expected<StringRef> SymbolNameOrErr = Sym->getName(StrTable);
  if (!SymbolNameOrErr)
    return errorToErrorCode(SymbolNameOrErr.takeError());
  S.Name = SymbolNameOrErr.get();

  ErrorOr<const Elf_Shdr *> ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable);
  if (std::error_code EC = ShdrOrErr.getError())
    return EC;
  const Elf_Shdr *Shdr = *ShdrOrErr;
  if (!Shdr)
    return obj2yaml_error::success;

  ErrorOr<StringRef> NameOrErr = Obj.getSectionName(Shdr);
  if (std::error_code EC = NameOrErr.getError())
    return EC;
  S.Section = NameOrErr.get();

  return obj2yaml_error::success;
}
Beispiel #27
0
/// Opens \a File and dumps it.
static void dumpInput(StringRef File) {
  ScopedPrinter Writer(outs());

  // Attempt to open the binary.
  Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(File);
  if (!BinaryOrErr)
    reportError(File, BinaryOrErr.takeError());
  Binary &Binary = *BinaryOrErr.get().getBinary();

  if (Archive *Arc = dyn_cast<Archive>(&Binary))
    dumpArchive(Arc, Writer);
  else if (MachOUniversalBinary *UBinary =
               dyn_cast<MachOUniversalBinary>(&Binary))
    dumpMachOUniversalBinary(UBinary, Writer);
  else if (ObjectFile *Obj = dyn_cast<ObjectFile>(&Binary))
    dumpObject(Obj, Writer);
  else if (COFFImportFile *Import = dyn_cast<COFFImportFile>(&Binary))
    dumpCOFFImportFile(Import, Writer);
  else if (WindowsResource *WinRes = dyn_cast<WindowsResource>(&Binary))
    dumpWindowsResourceFile(WinRes);
  else
    reportError(File, readobj_error::unrecognized_file_format);

  CVTypes.Binaries.push_back(std::move(*BinaryOrErr));
}
Beispiel #28
0
std::error_code ObjectFile::printSymbolName(raw_ostream &OS,
                                            DataRefImpl Symb) const {
  Expected<StringRef> Name = getSymbolName(Symb);
  if (!Name)
    return errorToErrorCode(Name.takeError());
  OS << *Name;
  return std::error_code();
}
Beispiel #29
0
bool LTOModule::isThinLTO() {
  Expected<BitcodeLTOInfo> Result = getBitcodeLTOInfo(MBRef);
  if (!Result) {
    logAllUnhandledErrors(Result.takeError(), errs(), "");
    return false;
  }
  return Result->IsThinLTO;
}
static DbiStream *getDbiStreamPtr(NativeSession &Session) {
  Expected<DbiStream &> DbiS = Session.getPDBFile().getPDBDbiStream();
  if (DbiS)
    return &DbiS.get();

  consumeError(DbiS.takeError());
  return nullptr;
}