20 #include "llvm/Config/config.h" 45 #pragma comment(lib, "dbghelp.lib") 48 #ifdef IMAGE_FILE_MACHINE_I386 49 #undef IMAGE_FILE_MACHINE_I386 58 uint64_t ModuleOffset,
StringRef DWPName) {
60 if (
auto InfoOrErr = getOrCreateModuleInfo(ModuleName, DWPName))
61 Info = InfoOrErr.get();
63 return InfoOrErr.takeError();
84 uint64_t ModuleOffset,
StringRef DWPName) {
86 if (
auto InfoOrErr = getOrCreateModuleInfo(ModuleName, DWPName))
87 Info = InfoOrErr.get();
89 return InfoOrErr.takeError();
109 return InlinedContext;
113 uint64_t ModuleOffset) {
115 if (
auto InfoOrErr = getOrCreateModuleInfo(ModuleName))
116 Info = InfoOrErr.get();
118 return InfoOrErr.takeError();
138 ObjectForUBPathAndArch.clear();
139 BinaryForPath.clear();
140 ObjectPairForPathArch.clear();
150 std::string getDarwinDWARFResourceForPath(
151 const std::string &Path,
const std::string &Basename) {
154 ResourceName +=
".dSYM";
158 return ResourceName.
str();
169 bool findDebugBinary(
const std::string &OrigPath,
170 const std::string &DebuglinkName,
uint32_t CRCHash,
171 std::string &Result) {
172 std::string OrigRealPath = OrigPath;
173 #if defined(HAVE_REALPATH) 174 if (
char *
RP = realpath(OrigPath.c_str(),
nullptr)) {
184 if (checkFileCRC(DebugPath, CRCHash)) {
185 Result = DebugPath.
str();
191 if (checkFileCRC(DebugPath, CRCHash)) {
192 Result = DebugPath.
str();
195 #if defined(__NetBSD__) 197 DebugPath =
"/usr/libdata/debug";
200 DebugPath =
"/usr/lib/debug";
204 if (checkFileCRC(DebugPath, CRCHash)) {
205 Result = DebugPath.
str();
211 bool getGNUDebuglinkContents(
const ObjectFile *Obj, std::string &DebugName,
219 if (Name ==
"gnu_debuglink") {
224 if (
const char *DebugNameStr = DE.getCStr(&Offset)) {
226 Offset = (Offset + 3) & ~0x3;
227 if (DE.isValidOffsetForDataOfSize(Offset, 4)) {
228 DebugName = DebugNameStr;
229 CRCHash = DE.getU32(&Offset);
250 ObjectFile *LLVMSymbolizer::lookUpDsymFile(
const std::string &ExePath,
254 std::vector<std::string> DsymPaths;
256 DsymPaths.push_back(getDarwinDWARFResourceForPath(ExePath, Filename));
257 for (
const auto &Path : Opts.
DsymHints) {
258 DsymPaths.push_back(getDarwinDWARFResourceForPath(Path, Filename));
260 for (
const auto &Path : DsymPaths) {
261 auto DbgObjOrErr = getOrCreateObject(Path, ArchName);
273 if (darwinDsymMatchesBinary(MachDbgObj, MachExeObj))
279 ObjectFile *LLVMSymbolizer::lookUpDebuglinkObject(
const std::string &Path,
281 const std::string &ArchName) {
282 std::string DebuglinkName;
284 std::string DebugBinaryPath;
285 if (!getGNUDebuglinkContents(Obj, DebuglinkName, CRCHash))
287 if (!findDebugBinary(Path, DebuglinkName, CRCHash, DebugBinaryPath))
289 auto DbgObjOrErr = getOrCreateObject(DebugBinaryPath, ArchName);
295 return DbgObjOrErr.get();
299 LLVMSymbolizer::getOrCreateObjectPair(
const std::string &Path,
300 const std::string &ArchName) {
301 const auto &
I = ObjectPairForPathArch.find(std::make_pair(Path, ArchName));
302 if (
I != ObjectPairForPathArch.end()) {
306 auto ObjOrErr = getOrCreateObject(Path, ArchName);
308 ObjectPairForPathArch.insert(std::make_pair(std::make_pair(Path, ArchName),
309 ObjectPair(
nullptr,
nullptr)));
310 return ObjOrErr.takeError();
317 if (
auto MachObj = dyn_cast<const MachOObjectFile>(Obj))
318 DbgObj = lookUpDsymFile(Path, MachObj, ArchName);
320 DbgObj = lookUpDebuglinkObject(Path, Obj, ArchName);
323 ObjectPair Res = std::make_pair(Obj, DbgObj);
324 ObjectPairForPathArch.insert(
325 std::make_pair(std::make_pair(Path, ArchName), Res));
330 LLVMSymbolizer::getOrCreateObject(
const std::string &Path,
331 const std::string &ArchName) {
332 const auto &
I = BinaryForPath.find(Path);
334 if (
I == BinaryForPath.end()) {
340 Bin = BinOrErr->getBinary();
341 BinaryForPath.insert(std::make_pair(Path, std::move(BinOrErr.
get())));
343 Bin =
I->second.getBinary();
350 const auto &
I = ObjectForUBPathAndArch.find(std::make_pair(Path, ArchName));
351 if (
I != ObjectForUBPathAndArch.end()) {
352 return I->second.get();
355 UB->getObjectForArch(ArchName);
357 ObjectForUBPathAndArch.insert(std::make_pair(
358 std::make_pair(Path, ArchName), std::unique_ptr<ObjectFile>()));
362 ObjectForUBPathAndArch.insert(std::make_pair(std::make_pair(Path, ArchName),
363 std::move(ObjOrErr.
get())));
367 return cast<ObjectFile>(Bin);
373 LLVMSymbolizer::getOrCreateModuleInfo(
const std::string &ModuleName,
375 const auto &
I = Modules.find(ModuleName);
376 if (
I != Modules.end()) {
377 return I->second.get();
379 std::string BinaryName = ModuleName;
381 size_t ColonPos = ModuleName.find_last_of(
':');
383 if (ColonPos != std::string::npos) {
384 std::string ArchStr = ModuleName.substr(ColonPos + 1);
386 BinaryName = ModuleName.substr(0, ColonPos);
390 auto ObjectsOrErr = getOrCreateObjectPair(BinaryName, ArchName);
394 std::make_pair(ModuleName, std::unique_ptr<SymbolizableModule>()));
395 return ObjectsOrErr.takeError();
397 ObjectPair Objects = ObjectsOrErr.get();
399 std::unique_ptr<DIContext>
Context;
402 if (
auto CoffObject = dyn_cast<COFFObjectFile>(Objects.first)) {
405 auto EC = CoffObject->getDebugPDBInfo(DebugInfo, PDBFileName);
406 if (!EC && DebugInfo !=
nullptr && !PDBFileName.
empty()) {
408 std::unique_ptr<IPDBSession> Session;
410 Objects.first->getFileName(), Session)) {
412 std::make_pair(ModuleName, std::unique_ptr<SymbolizableModule>()));
416 Context.reset(
new PDBContext(*CoffObject, std::move(Session)));
425 std::unique_ptr<SymbolizableModule> SymMod;
427 SymMod = std::move(InfoOrErr.get());
429 Modules.insert(std::make_pair(ModuleName, std::move(SymMod)));
430 assert(InsertResult.second);
431 if (
auto EC = InfoOrErr.getError())
433 return InsertResult.first->second.get();
446 char Front = SymbolName.
empty() ?
'\0' : SymbolName[0];
447 if (Front ==
'_' || Front ==
'@')
452 size_t AtPos = SymbolName.
rfind(
'@');
455 [](
char C) {
return C >=
'0' &&
C <=
'9'; })) {
456 SymbolName = SymbolName.
substr(0, AtPos);
474 if (Name.substr(0, 2) ==
"_Z") {
479 std::string Result = DemangledName;
484 #if defined(_MSC_VER) 485 if (!Name.empty() && Name.front() ==
'?') {
487 char DemangledName[1024] = {0};
488 DWORD result = ::UnDecorateSymbolName(
489 Name.c_str(), DemangledName, 1023,
490 UNDNAME_NO_ACCESS_SPECIFIERS |
491 UNDNAME_NO_ALLOCATION_LANGUAGE |
492 UNDNAME_NO_THROW_SIGNATURES |
493 UNDNAME_NO_MEMBER_TYPE |
494 UNDNAME_NO_MS_KEYWORDS |
495 UNDNAME_NO_FUNCTION_RETURNS);
496 return (result == 0) ?
Name : std::string(DemangledName);
499 if (DbiModuleDescriptor && DbiModuleDescriptor->
isWin32Module())
500 return std::string(demanglePE32ExternCFunc(Name));
Represents either an error or a value T.
void remove_filename(SmallVectorImpl< char > &path, Style style=Style::native)
Remove the last component from path unless it is the root dir.
DILineInfo * getMutableFrame(unsigned Index)
char * itaniumDemangle(const char *mangled_name, char *buf, size_t *n, int *status)
This class represents lattice values for constants.
LLVM_NODISCARD size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
virtual DIGlobal symbolizeData(uint64_t ModuleOffset) const =0
This class is the base class for all object file types.
virtual DILineInfo symbolizeCode(uint64_t ModuleOffset, FunctionNameKind FNKind, bool UseSymbolTable) const =0
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
Error takeError()
Take ownership of the stored error.
virtual bool isWin32Module() const =0
A format-neutral container for source line information.
Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr)
Create a Binary from Source, autodetecting the file type.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
Tagged union holding either a T or a Error.
StringRef str() const
Explicit conversion to StringRef.
Error createFileError(std::string F, Error E)
Concatenate a source file path and/or name with an Error.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
section_iterator_range sections() const
uint32_t getNumberOfFrames() const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Analysis containing CSE Info
Error loadDataForEXE(PDB_ReaderType Type, StringRef Path, std::unique_ptr< IPDBSession > &Session)
std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
size_t size() const
size - Get the array size.
virtual DIInliningInfo symbolizeInlinedCode(uint64_t ModuleOffset, FunctionNameKind FNKind, bool UseSymbolTable) const =0
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
A format-neutral container for inlined code description.
LLVM_NODISCARD size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
std::vector< std::string > DsymHints
static ErrorPolicy defaultErrorHandler(Error E)
Function used to handle default error reporting policy.
Expected< DILineInfo > symbolizeCode(const std::string &ModuleName, uint64_t ModuleOffset, StringRef DWPName="")
FunctionNameKind PrintFunctions
void consumeError(Error Err)
Consume a Error without doing anything.
bool isLittleEndian() const
Triple - Helper class for working with autoconf configuration names.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
static std::unique_ptr< DWARFContext > create(const object::ObjectFile &Obj, const LoadedObjectInfo *L=nullptr, function_ref< ErrorPolicy(Error)> HandleError=defaultErrorHandler, std::string DWPName="")
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
static std::string DemangleName(const std::string &Name, const SymbolizableModule *DbiModuleDescriptor)
ArrayRef< uint8_t > getUuid() const
reference get()
Returns a reference to the stored T value.
uint32_t crc32(StringRef Buffer)
virtual uint64_t getModulePreferredBase() const =0
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileOrSTDIN(const Twine &Filename, int64_t FileSize=-1, bool RequiresNullTerminator=true)
Open the specified file as a MemoryBuffer, or open stdin if the Filename is "-".
Merge contiguous icmps into a memcmp
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Expected< DIInliningInfo > symbolizeInlinedCode(const std::string &ModuleName, uint64_t ModuleOffset, StringRef DWPName="")
StringRef relative_path(StringRef path, Style style=Style::native)
Get relative path.
StringRef - Represent a constant reference to a string, i.e.
static ErrorOr< std::unique_ptr< SymbolizableObjectFile > > create(object::ObjectFile *Obj, std::unique_ptr< DIContext > DICtx)
Expected< DIGlobal > symbolizeData(const std::string &ModuleName, uint64_t ModuleOffset)
Container for description of a global variable.
bool empty() const
empty - Check if the array is empty.
This is a value type class that represents a single section in the list of sections in the object fil...
StringRef extension(StringRef path, Style style=Style::native)
Get extension.