aboutsummaryrefslogtreecommitdiff
path: root/lib/DebugInfo/Symbolize/Symbolize.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-20 20:50:12 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-20 20:50:12 +0000
commite6d1592492a3a379186bfb02bd0f4eda0669c0d5 (patch)
tree599ab169a01f1c86eda9adc774edaedde2f2db5b /lib/DebugInfo/Symbolize/Symbolize.cpp
parent1a56a5ead7a2e84bee8240f5f6b033b5f1707154 (diff)
downloadsrc-e6d1592492a3a379186bfb02bd0f4eda0669c0d5.tar.gz
src-e6d1592492a3a379186bfb02bd0f4eda0669c0d5.zip
Vendor import of stripped llvm trunk r366426 (just before the release_90vendor/llvm/llvm-trunk-r366426
Notes
Notes: svn path=/vendor/llvm/dist/; revision=351278 svn path=/vendor/llvm/llvm-trunk-r366426/; revision=351279; tag=vendor/llvm/llvm-trunk-r366426
Diffstat (limited to 'lib/DebugInfo/Symbolize/Symbolize.cpp')
-rw-r--r--lib/DebugInfo/Symbolize/Symbolize.cpp223
1 files changed, 136 insertions, 87 deletions
diff --git a/lib/DebugInfo/Symbolize/Symbolize.cpp b/lib/DebugInfo/Symbolize/Symbolize.cpp
index 59a85d6c3fcf..6a619f8f2f37 100644
--- a/lib/DebugInfo/Symbolize/Symbolize.cpp
+++ b/lib/DebugInfo/Symbolize/Symbolize.cpp
@@ -1,9 +1,8 @@
//===-- LLVMSymbolize.cpp -------------------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -17,7 +16,6 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/BinaryFormat/COFF.h"
-#include "llvm/Config/config.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/PDB/PDB.h"
#include "llvm/DebugInfo/PDB/PDBContext.h"
@@ -25,6 +23,7 @@
#include "llvm/Object/COFF.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/MachOUniversal.h"
+#include "llvm/Support/CRC.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/DataExtractor.h"
@@ -34,7 +33,6 @@
#include "llvm/Support/Path.h"
#include <algorithm>
#include <cassert>
-#include <cstdlib>
#include <cstring>
#if defined(_MSC_VER)
@@ -54,14 +52,8 @@ namespace llvm {
namespace symbolize {
Expected<DILineInfo>
-LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
- uint64_t ModuleOffset, StringRef DWPName) {
- SymbolizableModule *Info;
- if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName, DWPName))
- Info = InfoOrErr.get();
- else
- return InfoOrErr.takeError();
-
+LLVMSymbolizer::symbolizeCodeCommon(SymbolizableModule *Info,
+ object::SectionedAddress ModuleOffset) {
// A null module means an error has already been reported. Return an empty
// result.
if (!Info)
@@ -70,7 +62,7 @@ LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
// If the user is giving us relative addresses, add the preferred base of the
// object to the offset before we do the query. It's what DIContext expects.
if (Opts.RelativeAddresses)
- ModuleOffset += Info->getModulePreferredBase();
+ ModuleOffset.Address += Info->getModulePreferredBase();
DILineInfo LineInfo = Info->symbolizeCode(ModuleOffset, Opts.PrintFunctions,
Opts.UseSymbolTable);
@@ -79,11 +71,37 @@ LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
return LineInfo;
}
+Expected<DILineInfo>
+LLVMSymbolizer::symbolizeCode(const ObjectFile &Obj,
+ object::SectionedAddress ModuleOffset) {
+ StringRef ModuleName = Obj.getFileName();
+ auto I = Modules.find(ModuleName);
+ if (I != Modules.end())
+ return symbolizeCodeCommon(I->second.get(), ModuleOffset);
+
+ std::unique_ptr<DIContext> Context =
+ DWARFContext::create(Obj, nullptr, DWARFContext::defaultErrorHandler);
+ Expected<SymbolizableModule *> InfoOrErr =
+ createModuleInfo(&Obj, std::move(Context), ModuleName);
+ if (!InfoOrErr)
+ return InfoOrErr.takeError();
+ return symbolizeCodeCommon(*InfoOrErr, ModuleOffset);
+}
+
+Expected<DILineInfo>
+LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
+ object::SectionedAddress ModuleOffset) {
+ Expected<SymbolizableModule *> InfoOrErr = getOrCreateModuleInfo(ModuleName);
+ if (!InfoOrErr)
+ return InfoOrErr.takeError();
+ return symbolizeCodeCommon(*InfoOrErr, ModuleOffset);
+}
+
Expected<DIInliningInfo>
LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName,
- uint64_t ModuleOffset, StringRef DWPName) {
+ object::SectionedAddress ModuleOffset) {
SymbolizableModule *Info;
- if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName, DWPName))
+ if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName))
Info = InfoOrErr.get();
else
return InfoOrErr.takeError();
@@ -96,7 +114,7 @@ LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName,
// If the user is giving us relative addresses, add the preferred base of the
// object to the offset before we do the query. It's what DIContext expects.
if (Opts.RelativeAddresses)
- ModuleOffset += Info->getModulePreferredBase();
+ ModuleOffset.Address += Info->getModulePreferredBase();
DIInliningInfo InlinedContext = Info->symbolizeInlinedCode(
ModuleOffset, Opts.PrintFunctions, Opts.UseSymbolTable);
@@ -109,8 +127,9 @@ LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName,
return InlinedContext;
}
-Expected<DIGlobal> LLVMSymbolizer::symbolizeData(const std::string &ModuleName,
- uint64_t ModuleOffset) {
+Expected<DIGlobal>
+LLVMSymbolizer::symbolizeData(const std::string &ModuleName,
+ object::SectionedAddress ModuleOffset) {
SymbolizableModule *Info;
if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName))
Info = InfoOrErr.get();
@@ -126,7 +145,7 @@ Expected<DIGlobal> LLVMSymbolizer::symbolizeData(const std::string &ModuleName,
// the object to the offset before we do the query. It's what DIContext
// expects.
if (Opts.RelativeAddresses)
- ModuleOffset += Info->getModulePreferredBase();
+ ModuleOffset.Address += Info->getModulePreferredBase();
DIGlobal Global = Info->symbolizeData(ModuleOffset);
if (Opts.Demangle)
@@ -134,6 +153,29 @@ Expected<DIGlobal> LLVMSymbolizer::symbolizeData(const std::string &ModuleName,
return Global;
}
+Expected<std::vector<DILocal>>
+LLVMSymbolizer::symbolizeFrame(const std::string &ModuleName,
+ object::SectionedAddress ModuleOffset) {
+ SymbolizableModule *Info;
+ if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName))
+ Info = InfoOrErr.get();
+ else
+ return InfoOrErr.takeError();
+
+ // A null module means an error has already been reported. Return an empty
+ // result.
+ if (!Info)
+ return std::vector<DILocal>();
+
+ // If the user is giving us relative addresses, add the preferred base of
+ // the object to the offset before we do the query. It's what DIContext
+ // expects.
+ if (Opts.RelativeAddresses)
+ ModuleOffset.Address += Info->getModulePreferredBase();
+
+ return Info->symbolizeFrame(ModuleOffset);
+}
+
void LLVMSymbolizer::flush() {
ObjectForUBPathAndArch.clear();
BinaryForPath.clear();
@@ -163,42 +205,45 @@ bool checkFileCRC(StringRef Path, uint32_t CRCHash) {
MemoryBuffer::getFileOrSTDIN(Path);
if (!MB)
return false;
- return !zlib::isAvailable() || CRCHash == zlib::crc32(MB.get()->getBuffer());
+ return CRCHash == llvm::crc32(0, MB.get()->getBuffer());
}
bool findDebugBinary(const std::string &OrigPath,
const std::string &DebuglinkName, uint32_t CRCHash,
+ const std::string &FallbackDebugPath,
std::string &Result) {
- std::string OrigRealPath = OrigPath;
-#if defined(HAVE_REALPATH)
- if (char *RP = realpath(OrigPath.c_str(), nullptr)) {
- OrigRealPath = RP;
- free(RP);
- }
-#endif
- SmallString<16> OrigDir(OrigRealPath);
+ SmallString<16> OrigDir(OrigPath);
llvm::sys::path::remove_filename(OrigDir);
SmallString<16> DebugPath = OrigDir;
- // Try /path/to/original_binary/debuglink_name
+ // Try relative/path/to/original_binary/debuglink_name
llvm::sys::path::append(DebugPath, DebuglinkName);
if (checkFileCRC(DebugPath, CRCHash)) {
Result = DebugPath.str();
return true;
}
- // Try /path/to/original_binary/.debug/debuglink_name
+ // Try relative/path/to/original_binary/.debug/debuglink_name
DebugPath = OrigDir;
llvm::sys::path::append(DebugPath, ".debug", DebuglinkName);
if (checkFileCRC(DebugPath, CRCHash)) {
Result = DebugPath.str();
return true;
}
+ // Make the path absolute so that lookups will go to
+ // "/usr/lib/debug/full/path/to/debug", not
+ // "/usr/lib/debug/to/debug"
+ llvm::sys::fs::make_absolute(OrigDir);
+ if (!FallbackDebugPath.empty()) {
+ // Try <FallbackDebugPath>/absolute/path/to/original_binary/debuglink_name
+ DebugPath = FallbackDebugPath;
+ } else {
#if defined(__NetBSD__)
- // Try /usr/libdata/debug/path/to/original_binary/debuglink_name
- DebugPath = "/usr/libdata/debug";
+ // Try /usr/libdata/debug/absolute/path/to/original_binary/debuglink_name
+ DebugPath = "/usr/libdata/debug";
#else
- // Try /usr/lib/debug/path/to/original_binary/debuglink_name
- DebugPath = "/usr/lib/debug";
+ // Try /usr/lib/debug/absolute/path/to/original_binary/debuglink_name
+ DebugPath = "/usr/lib/debug";
#endif
+ }
llvm::sys::path::append(DebugPath, llvm::sys::path::relative_path(OrigDir),
DebuglinkName);
if (checkFileCRC(DebugPath, CRCHash)) {
@@ -217,9 +262,12 @@ bool getGNUDebuglinkContents(const ObjectFile *Obj, std::string &DebugName,
Section.getName(Name);
Name = Name.substr(Name.find_first_not_of("._"));
if (Name == "gnu_debuglink") {
- StringRef Data;
- Section.getContents(Data);
- DataExtractor DE(Data, Obj->isLittleEndian(), 0);
+ Expected<StringRef> ContentsOrErr = Section.getContents();
+ if (!ContentsOrErr) {
+ consumeError(ContentsOrErr.takeError());
+ return false;
+ }
+ DataExtractor DE(*ContentsOrErr, Obj->isLittleEndian(), 0);
uint32_t Offset = 0;
if (const char *DebugNameStr = DE.getCStr(&Offset)) {
// 4-byte align the offset.
@@ -284,7 +332,8 @@ ObjectFile *LLVMSymbolizer::lookUpDebuglinkObject(const std::string &Path,
std::string DebugBinaryPath;
if (!getGNUDebuglinkContents(Obj, DebuglinkName, CRCHash))
return nullptr;
- if (!findDebugBinary(Path, DebuglinkName, CRCHash, DebugBinaryPath))
+ if (!findDebugBinary(Path, DebuglinkName, CRCHash, Opts.FallbackDebugPath,
+ DebugBinaryPath))
return nullptr;
auto DbgObjOrErr = getOrCreateObject(DebugBinaryPath, ArchName);
if (!DbgObjOrErr) {
@@ -298,15 +347,14 @@ ObjectFile *LLVMSymbolizer::lookUpDebuglinkObject(const std::string &Path,
Expected<LLVMSymbolizer::ObjectPair>
LLVMSymbolizer::getOrCreateObjectPair(const std::string &Path,
const std::string &ArchName) {
- const auto &I = ObjectPairForPathArch.find(std::make_pair(Path, ArchName));
- if (I != ObjectPairForPathArch.end()) {
+ auto I = ObjectPairForPathArch.find(std::make_pair(Path, ArchName));
+ if (I != ObjectPairForPathArch.end())
return I->second;
- }
auto ObjOrErr = getOrCreateObject(Path, ArchName);
if (!ObjOrErr) {
- ObjectPairForPathArch.insert(std::make_pair(std::make_pair(Path, ArchName),
- ObjectPair(nullptr, nullptr)));
+ ObjectPairForPathArch.emplace(std::make_pair(Path, ArchName),
+ ObjectPair(nullptr, nullptr));
return ObjOrErr.takeError();
}
@@ -321,46 +369,43 @@ LLVMSymbolizer::getOrCreateObjectPair(const std::string &Path,
if (!DbgObj)
DbgObj = Obj;
ObjectPair Res = std::make_pair(Obj, DbgObj);
- ObjectPairForPathArch.insert(
- std::make_pair(std::make_pair(Path, ArchName), Res));
+ ObjectPairForPathArch.emplace(std::make_pair(Path, ArchName), Res);
return Res;
}
Expected<ObjectFile *>
LLVMSymbolizer::getOrCreateObject(const std::string &Path,
const std::string &ArchName) {
- const auto &I = BinaryForPath.find(Path);
- Binary *Bin = nullptr;
- if (I == BinaryForPath.end()) {
+ Binary *Bin;
+ auto Pair = BinaryForPath.emplace(Path, OwningBinary<Binary>());
+ if (!Pair.second) {
+ Bin = Pair.first->second.getBinary();
+ } else {
Expected<OwningBinary<Binary>> BinOrErr = createBinary(Path);
- if (!BinOrErr) {
- BinaryForPath.insert(std::make_pair(Path, OwningBinary<Binary>()));
+ if (!BinOrErr)
return BinOrErr.takeError();
- }
- Bin = BinOrErr->getBinary();
- BinaryForPath.insert(std::make_pair(Path, std::move(BinOrErr.get())));
- } else {
- Bin = I->second.getBinary();
+ Pair.first->second = std::move(BinOrErr.get());
+ Bin = Pair.first->second.getBinary();
}
if (!Bin)
return static_cast<ObjectFile *>(nullptr);
if (MachOUniversalBinary *UB = dyn_cast_or_null<MachOUniversalBinary>(Bin)) {
- const auto &I = ObjectForUBPathAndArch.find(std::make_pair(Path, ArchName));
- if (I != ObjectForUBPathAndArch.end()) {
+ auto I = ObjectForUBPathAndArch.find(std::make_pair(Path, ArchName));
+ if (I != ObjectForUBPathAndArch.end())
return I->second.get();
- }
+
Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
UB->getObjectForArch(ArchName);
if (!ObjOrErr) {
- ObjectForUBPathAndArch.insert(std::make_pair(
- std::make_pair(Path, ArchName), std::unique_ptr<ObjectFile>()));
+ ObjectForUBPathAndArch.emplace(std::make_pair(Path, ArchName),
+ std::unique_ptr<ObjectFile>());
return ObjOrErr.takeError();
}
ObjectFile *Res = ObjOrErr->get();
- ObjectForUBPathAndArch.insert(std::make_pair(std::make_pair(Path, ArchName),
- std::move(ObjOrErr.get())));
+ ObjectForUBPathAndArch.emplace(std::make_pair(Path, ArchName),
+ std::move(ObjOrErr.get()));
return Res;
}
if (Bin->isObject()) {
@@ -370,12 +415,28 @@ LLVMSymbolizer::getOrCreateObject(const std::string &Path,
}
Expected<SymbolizableModule *>
-LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName,
- StringRef DWPName) {
- const auto &I = Modules.find(ModuleName);
- if (I != Modules.end()) {
+LLVMSymbolizer::createModuleInfo(const ObjectFile *Obj,
+ std::unique_ptr<DIContext> Context,
+ StringRef ModuleName) {
+ auto InfoOrErr =
+ SymbolizableObjectFile::create(Obj, std::move(Context));
+ std::unique_ptr<SymbolizableModule> SymMod;
+ if (InfoOrErr)
+ SymMod = std::move(*InfoOrErr);
+ auto InsertResult =
+ Modules.insert(std::make_pair(ModuleName, std::move(SymMod)));
+ assert(InsertResult.second);
+ if (std::error_code EC = InfoOrErr.getError())
+ return errorCodeToError(EC);
+ return InsertResult.first->second.get();
+}
+
+Expected<SymbolizableModule *>
+LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) {
+ auto I = Modules.find(ModuleName);
+ if (I != Modules.end())
return I->second.get();
- }
+
std::string BinaryName = ModuleName;
std::string ArchName = Opts.DefaultArch;
size_t ColonPos = ModuleName.find_last_of(':');
@@ -390,8 +451,7 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName,
auto ObjectsOrErr = getOrCreateObjectPair(BinaryName, ArchName);
if (!ObjectsOrErr) {
// Failed to find valid object file.
- Modules.insert(
- std::make_pair(ModuleName, std::unique_ptr<SymbolizableModule>()));
+ Modules.emplace(ModuleName, std::unique_ptr<SymbolizableModule>());
return ObjectsOrErr.takeError();
}
ObjectPair Objects = ObjectsOrErr.get();
@@ -408,8 +468,7 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName,
std::unique_ptr<IPDBSession> Session;
if (auto Err = loadDataForEXE(PDB_ReaderType::DIA,
Objects.first->getFileName(), Session)) {
- Modules.insert(
- std::make_pair(ModuleName, std::unique_ptr<SymbolizableModule>()));
+ Modules.emplace(ModuleName, std::unique_ptr<SymbolizableModule>());
// Return along the PDB filename to provide more context
return createFileError(PDBFileName, std::move(Err));
}
@@ -417,20 +476,10 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName,
}
}
if (!Context)
- Context = DWARFContext::create(*Objects.second, nullptr,
- DWARFContext::defaultErrorHandler, DWPName);
- assert(Context);
- auto InfoOrErr =
- SymbolizableObjectFile::create(Objects.first, std::move(Context));
- std::unique_ptr<SymbolizableModule> SymMod;
- if (InfoOrErr)
- SymMod = std::move(InfoOrErr.get());
- auto InsertResult =
- Modules.insert(std::make_pair(ModuleName, std::move(SymMod)));
- assert(InsertResult.second);
- if (auto EC = InfoOrErr.getError())
- return errorCodeToError(EC);
- return InsertResult.first->second.get();
+ Context =
+ DWARFContext::create(*Objects.second, nullptr,
+ DWARFContext::defaultErrorHandler, Opts.DWPName);
+ return createModuleInfo(Objects.first, std::move(Context), ModuleName);
}
namespace {