diff options
Diffstat (limited to 'lib/DebugInfo/Symbolize')
-rw-r--r-- | lib/DebugInfo/Symbolize/DIPrinter.cpp | 17 | ||||
-rw-r--r-- | lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp | 32 | ||||
-rw-r--r-- | lib/DebugInfo/Symbolize/SymbolizableObjectFile.h | 7 | ||||
-rw-r--r-- | lib/DebugInfo/Symbolize/Symbolize.cpp | 52 |
4 files changed, 52 insertions, 56 deletions
diff --git a/lib/DebugInfo/Symbolize/DIPrinter.cpp b/lib/DebugInfo/Symbolize/DIPrinter.cpp index b2bfef251485..b1a80cbc4580 100644 --- a/lib/DebugInfo/Symbolize/DIPrinter.cpp +++ b/lib/DebugInfo/Symbolize/DIPrinter.cpp @@ -30,11 +30,6 @@ namespace llvm { namespace symbolize { -// By default, DILineInfo contains "<invalid>" for function/filename it -// cannot fetch. We replace it to "??" to make our output closer to addr2line. -static const char kDILineInfoBadString[] = "<invalid>"; -static const char kBadString[] = "??"; - // Prints source code around in the FileName the Line. void DIPrinter::printContext(const std::string &FileName, int64_t Line) { if (PrintSourceContext <= 0) @@ -68,16 +63,16 @@ void DIPrinter::printContext(const std::string &FileName, int64_t Line) { void DIPrinter::print(const DILineInfo &Info, bool Inlined) { if (PrintFunctionNames) { std::string FunctionName = Info.FunctionName; - if (FunctionName == kDILineInfoBadString) - FunctionName = kBadString; + if (FunctionName == DILineInfo::BadString) + FunctionName = DILineInfo::Addr2LineBadString; StringRef Delimiter = PrintPretty ? " at " : "\n"; StringRef Prefix = (PrintPretty && Inlined) ? " (inlined by) " : ""; OS << Prefix << FunctionName << Delimiter; } std::string Filename = Info.FileName; - if (Filename == kDILineInfoBadString) - Filename = kBadString; + if (Filename == DILineInfo::BadString) + Filename = DILineInfo::Addr2LineBadString; else if (Basenames) Filename = llvm::sys::path::filename(Filename); if (!Verbose) { @@ -115,8 +110,8 @@ DIPrinter &DIPrinter::operator<<(const DIInliningInfo &Info) { DIPrinter &DIPrinter::operator<<(const DIGlobal &Global) { std::string Name = Global.Name; - if (Name == kDILineInfoBadString) - Name = kBadString; + if (Name == DILineInfo::BadString) + Name = DILineInfo::Addr2LineBadString; OS << Name << "\n"; OS << Global.Start << " " << Global.Size << "\n"; return *this; diff --git a/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp b/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp index 2765bf44d504..b4d49d9ff958 100644 --- a/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp +++ b/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp @@ -43,20 +43,22 @@ getDILineInfoSpecifier(FunctionNameKind FNKind) { ErrorOr<std::unique_ptr<SymbolizableObjectFile>> SymbolizableObjectFile::create(const object::ObjectFile *Obj, - std::unique_ptr<DIContext> DICtx) { + std::unique_ptr<DIContext> DICtx, + bool UntagAddresses) { assert(DICtx); std::unique_ptr<SymbolizableObjectFile> res( - new SymbolizableObjectFile(Obj, std::move(DICtx))); + new SymbolizableObjectFile(Obj, std::move(DICtx), UntagAddresses)); std::unique_ptr<DataExtractor> OpdExtractor; uint64_t OpdAddress = 0; // Find the .opd (function descriptor) section if any, for big-endian // PowerPC64 ELF. if (Obj->getArch() == Triple::ppc64) { for (section_iterator Section : Obj->sections()) { - StringRef Name; - if (auto EC = Section->getName(Name)) - return EC; - if (Name == ".opd") { + Expected<StringRef> NameOrErr = Section->getName(); + if (!NameOrErr) + return errorToErrorCode(NameOrErr.takeError()); + + if (*NameOrErr == ".opd") { Expected<StringRef> E = Section->getContents(); if (!E) return errorToErrorCode(E.takeError()); @@ -103,8 +105,10 @@ SymbolizableObjectFile::create(const object::ObjectFile *Obj, } SymbolizableObjectFile::SymbolizableObjectFile(const ObjectFile *Obj, - std::unique_ptr<DIContext> DICtx) - : Module(Obj), DebugInfoContext(std::move(DICtx)) {} + std::unique_ptr<DIContext> DICtx, + bool UntagAddresses) + : Module(Obj), DebugInfoContext(std::move(DICtx)), + UntagAddresses(UntagAddresses) {} namespace { @@ -172,6 +176,12 @@ std::error_code SymbolizableObjectFile::addSymbol(const SymbolRef &Symbol, if (!SymbolAddressOrErr) return errorToErrorCode(SymbolAddressOrErr.takeError()); uint64_t SymbolAddress = *SymbolAddressOrErr; + if (UntagAddresses) { + // For kernel addresses, bits 56-63 need to be set, so we sign extend bit 55 + // into bits 56-63 instead of masking them out. + SymbolAddress &= (1ull << 56) - 1; + SymbolAddress = (int64_t(SymbolAddress) << 8) >> 8; + } if (OpdExtractor) { // For big-endian PowerPC64 ELF, symbols in the .opd section refer to // function descriptors. The first word of the descriptor is a pointer to @@ -179,10 +189,8 @@ std::error_code SymbolizableObjectFile::addSymbol(const SymbolRef &Symbol, // For the purposes of symbolization, pretend the symbol's address is that // of the function's code, not the descriptor. uint64_t OpdOffset = SymbolAddress - OpdAddress; - uint32_t OpdOffset32 = OpdOffset; - if (OpdOffset == OpdOffset32 && - OpdExtractor->isValidOffsetForAddress(OpdOffset32)) - SymbolAddress = OpdExtractor->getAddress(&OpdOffset32); + if (OpdExtractor->isValidOffsetForAddress(OpdOffset)) + SymbolAddress = OpdExtractor->getAddress(&OpdOffset); } Expected<StringRef> SymbolNameOrErr = Symbol.getName(); if (!SymbolNameOrErr) diff --git a/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h b/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h index 9cab94178c1b..b5b9793a44d9 100644 --- a/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h +++ b/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h @@ -31,7 +31,8 @@ namespace symbolize { class SymbolizableObjectFile : public SymbolizableModule { public: static ErrorOr<std::unique_ptr<SymbolizableObjectFile>> - create(const object::ObjectFile *Obj, std::unique_ptr<DIContext> DICtx); + create(const object::ObjectFile *Obj, std::unique_ptr<DIContext> DICtx, + bool UntagAddresses); DILineInfo symbolizeCode(object::SectionedAddress ModuleOffset, FunctionNameKind FNKind, @@ -70,6 +71,7 @@ private: const object::ObjectFile *Module; std::unique_ptr<DIContext> DebugInfoContext; + bool UntagAddresses; struct SymbolDesc { uint64_t Addr; @@ -85,7 +87,8 @@ private: std::vector<std::pair<SymbolDesc, StringRef>> Objects; SymbolizableObjectFile(const object::ObjectFile *Obj, - std::unique_ptr<DIContext> DICtx); + std::unique_ptr<DIContext> DICtx, + bool UntagAddresses); }; } // end namespace symbolize diff --git a/lib/DebugInfo/Symbolize/Symbolize.cpp b/lib/DebugInfo/Symbolize/Symbolize.cpp index 6a619f8f2f37..be79d9e637c1 100644 --- a/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -35,19 +35,6 @@ #include <cassert> #include <cstring> -#if defined(_MSC_VER) -#include <Windows.h> - -// This must be included after windows.h. -#include <DbgHelp.h> -#pragma comment(lib, "dbghelp.lib") - -// Windows.h conflicts with our COFF header definitions. -#ifdef IMAGE_FILE_MACHINE_I386 -#undef IMAGE_FILE_MACHINE_I386 -#endif -#endif - namespace llvm { namespace symbolize { @@ -205,7 +192,7 @@ bool checkFileCRC(StringRef Path, uint32_t CRCHash) { MemoryBuffer::getFileOrSTDIN(Path); if (!MB) return false; - return CRCHash == llvm::crc32(0, MB.get()->getBuffer()); + return CRCHash == llvm::crc32(arrayRefFromStringRef(MB.get()->getBuffer())); } bool findDebugBinary(const std::string &OrigPath, @@ -259,7 +246,11 @@ bool getGNUDebuglinkContents(const ObjectFile *Obj, std::string &DebugName, return false; for (const SectionRef &Section : Obj->sections()) { StringRef Name; - Section.getName(Name); + if (Expected<StringRef> NameOrErr = Section.getName()) + Name = *NameOrErr; + else + consumeError(NameOrErr.takeError()); + Name = Name.substr(Name.find_first_not_of("._")); if (Name == "gnu_debuglink") { Expected<StringRef> ContentsOrErr = Section.getContents(); @@ -268,7 +259,7 @@ bool getGNUDebuglinkContents(const ObjectFile *Obj, std::string &DebugName, return false; } DataExtractor DE(*ContentsOrErr, Obj->isLittleEndian(), 0); - uint32_t Offset = 0; + uint64_t Offset = 0; if (const char *DebugNameStr = DE.getCStr(&Offset)) { // 4-byte align the offset. Offset = (Offset + 3) & ~0x3; @@ -397,7 +388,7 @@ LLVMSymbolizer::getOrCreateObject(const std::string &Path, return I->second.get(); Expected<std::unique_ptr<ObjectFile>> ObjOrErr = - UB->getObjectForArch(ArchName); + UB->getMachOObjectForArch(ArchName); if (!ObjOrErr) { ObjectForUBPathAndArch.emplace(std::make_pair(Path, ArchName), std::unique_ptr<ObjectFile>()); @@ -418,8 +409,8 @@ Expected<SymbolizableModule *> LLVMSymbolizer::createModuleInfo(const ObjectFile *Obj, std::unique_ptr<DIContext> Context, StringRef ModuleName) { - auto InfoOrErr = - SymbolizableObjectFile::create(Obj, std::move(Context)); + auto InfoOrErr = SymbolizableObjectFile::create(Obj, std::move(Context), + Opts.UntagAddresses); std::unique_ptr<SymbolizableModule> SymMod; if (InfoOrErr) SymMod = std::move(*InfoOrErr); @@ -530,21 +521,20 @@ LLVMSymbolizer::DemangleName(const std::string &Name, return Result; } -#if defined(_MSC_VER) if (!Name.empty() && Name.front() == '?') { // Only do MSVC C++ demangling on symbols starting with '?'. - char DemangledName[1024] = {0}; - DWORD result = ::UnDecorateSymbolName( - Name.c_str(), DemangledName, 1023, - UNDNAME_NO_ACCESS_SPECIFIERS | // Strip public, private, protected - UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall, etc - UNDNAME_NO_THROW_SIGNATURES | // Strip throw() specifications - UNDNAME_NO_MEMBER_TYPE | // Strip virtual, static, etc specifiers - UNDNAME_NO_MS_KEYWORDS | // Strip all MS extension keywords - UNDNAME_NO_FUNCTION_RETURNS); // Strip function return types - return (result == 0) ? Name : std::string(DemangledName); + int status = 0; + char *DemangledName = microsoftDemangle( + Name.c_str(), nullptr, nullptr, &status, + MSDemangleFlags(MSDF_NoAccessSpecifier | MSDF_NoCallingConvention | + MSDF_NoMemberType | MSDF_NoReturnType)); + if (status != 0) + return Name; + std::string Result = DemangledName; + free(DemangledName); + return Result; } -#endif + if (DbiModuleDescriptor && DbiModuleDescriptor->isWin32Module()) return std::string(demanglePE32ExternCFunc(Name)); return Name; |