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;
}
Beispiel #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;
}