LLVMSymbolizer::BinaryPair
LLVMSymbolizer::getOrCreateBinary(const std::string &Path) {
  BinaryMapTy::iterator I = BinaryForPath.find(Path);
  if (I != BinaryForPath.end())
    return I->second;
  Binary *Bin = 0;
  Binary *DbgBin = 0;
  OwningPtr<Binary> ParsedBinary;
  OwningPtr<Binary> ParsedDbgBinary;
  if (!error(createBinary(Path, ParsedBinary))) {
    // Check if it's a universal binary.
    Bin = ParsedBinary.take();
    ParsedBinariesAndObjects.push_back(Bin);
    if (Bin->isMachO() || Bin->isMachOUniversalBinary()) {
      // On Darwin we may find DWARF in separate object file in
      // resource directory.
      const std::string &ResourcePath =
          getDarwinDWARFResourceForPath(Path);
      bool ResourceFileExists = false;
      if (!sys::fs::exists(ResourcePath, ResourceFileExists) &&
          ResourceFileExists &&
          !error(createBinary(ResourcePath, ParsedDbgBinary))) {
        DbgBin = ParsedDbgBinary.take();
        ParsedBinariesAndObjects.push_back(DbgBin);
      }
    }
  }
  if (DbgBin == 0)
    DbgBin = Bin;
  BinaryPair Res = std::make_pair(Bin, DbgBin);
  BinaryForPath[Path] = Res;
  return Res;
}
Example #2
0
LLVMSymbolizer::BinaryPair
LLVMSymbolizer::getOrCreateBinary(const std::string &Path) {
  BinaryMapTy::iterator I = BinaryForPath.find(Path);
  if (I != BinaryForPath.end())
    return I->second;
  Binary *Bin = nullptr;
  Binary *DbgBin = nullptr;
  ErrorOr<Binary *> BinaryOrErr = createBinary(Path);
  if (!error(BinaryOrErr.getError())) {
    std::unique_ptr<Binary> ParsedBinary(BinaryOrErr.get());
    // Check if it's a universal binary.
    Bin = ParsedBinary.get();
    ParsedBinariesAndObjects.push_back(std::move(ParsedBinary));
    if (Bin->isMachO() || Bin->isMachOUniversalBinary()) {
      // On Darwin we may find DWARF in separate object file in
      // resource directory.
      const std::string &ResourcePath =
          getDarwinDWARFResourceForPath(Path);
      BinaryOrErr = createBinary(ResourcePath);
      error_code EC = BinaryOrErr.getError();
      if (EC != std::errc::no_such_file_or_directory && !error(EC)) {
        DbgBin = BinaryOrErr.get();
        ParsedBinariesAndObjects.push_back(std::unique_ptr<Binary>(DbgBin));
      }
    }
    // Try to locate the debug binary using .gnu_debuglink section.
    if (!DbgBin) {
      std::string DebuglinkName;
      uint32_t CRCHash;
      std::string DebugBinaryPath;
      if (getGNUDebuglinkContents(Bin, DebuglinkName, CRCHash) &&
          findDebugBinary(Path, DebuglinkName, CRCHash, DebugBinaryPath)) {
        BinaryOrErr = createBinary(DebugBinaryPath);
        if (!error(BinaryOrErr.getError())) {
          DbgBin = BinaryOrErr.get();
          ParsedBinariesAndObjects.push_back(std::unique_ptr<Binary>(DbgBin));
        }
      }
    }
  }
  if (!DbgBin)
    DbgBin = Bin;
  BinaryPair Res = std::make_pair(Bin, DbgBin);
  BinaryForPath[Path] = Res;
  return Res;
}
Example #3
0
void ObjectFile::parse() {
  // Parse a memory buffer as a COFF file.
  std::unique_ptr<Binary> Bin =
      check(createBinary(MB), "failed to parse object file");

  if (auto *Obj = dyn_cast<COFFObjectFile>(Bin.get())) {
    Bin.release();
    COFFObj.reset(Obj);
  } else {
    fatal(getName() + " is not a COFF file");
  }

  // Read section and symbol tables.
  initializeChunks();
  initializeSymbols();
  initializeSEH();
}
Example #4
0
void ObjectFile::parse() {
  // Parse a memory buffer as a COFF file.
  auto BinOrErr = createBinary(MB);
  error(BinOrErr, "Failed to parse object file");
  std::unique_ptr<Binary> Bin = std::move(*BinOrErr);

  if (auto *Obj = dyn_cast<COFFObjectFile>(Bin.get())) {
    Bin.release();
    COFFObj.reset(Obj);
  } else {
    error(Twine(getName()) + " is not a COFF file.");
  }

  // Read section and symbol tables.
  initializeChunks();
  initializeSymbols();
  initializeSEH();
}