X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fllvm-symbolizer%2FLLVMSymbolize.cpp;h=eaf0d08f1052f47884d566946d623c694082b394;hb=ca30411d989b7ceae3c3ea20cd31de7ec8bbf1fc;hp=c3988e136177ff5cd42cf47159cce2d766e1f9d6;hpb=45e7e93c6f04c9a59bafcbca3da0d6925fd7db71;p=oota-llvm.git diff --git a/tools/llvm-symbolizer/LLVMSymbolize.cpp b/tools/llvm-symbolizer/LLVMSymbolize.cpp index c3988e13617..eaf0d08f105 100644 --- a/tools/llvm-symbolizer/LLVMSymbolize.cpp +++ b/tools/llvm-symbolizer/LLVMSymbolize.cpp @@ -15,6 +15,8 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/Config/config.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" +#include "llvm/DebugInfo/PDB/PDB.h" +#include "llvm/DebugInfo/PDB/PDBContext.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/MachO.h" #include "llvm/Support/Casting.h" @@ -27,6 +29,11 @@ #include #include +#if defined(_MSC_VER) +#include +#include +#endif + namespace llvm { namespace symbolize { @@ -70,10 +77,9 @@ ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx) bool NoSymbolTable = (Module->symbol_begin() == Module->symbol_end()); if (NoSymbolTable && Module->isELF()) { // Fallback to dynamic symbol table, if regular symbol table is stripped. - std::pair IDyn = - getELFDynamicSymbolIterators(Module); - for (symbol_iterator si = IDyn.first, se = IDyn.second; si != se; ++si) { - addSymbol(*si, OpdExtractor.get(), OpdAddress); + auto IDyn = cast(Module)->getDynamicSymbolIterators(); + for (SymbolRef Sym : IDyn) { + addSymbol(Sym, OpdExtractor.get(), OpdAddress); } } } @@ -87,7 +93,7 @@ void ModuleInfo::addSymbol(const SymbolRef &Symbol, DataExtractor *OpdExtractor, return; uint64_t SymbolAddress; if (error(Symbol.getAddress(SymbolAddress)) || - SymbolAddress == UnknownAddressOrSize) + SymbolAddress == UnknownAddress) return; if (OpdExtractor) { // For big-endian PowerPC64 ELF, symbols in the .opd section refer to @@ -102,13 +108,12 @@ void ModuleInfo::addSymbol(const SymbolRef &Symbol, DataExtractor *OpdExtractor, SymbolAddress = OpdExtractor->getAddress(&OpdOffset32); } uint64_t SymbolSize; - // Getting symbol size is linear for Mach-O files, so assume that symbol - // occupies the memory range up to the following symbol. - if (isa(Module)) + // Onyl ELF has a size for every symbol so assume that symbol occupies the + // memory range up to the following symbol. + if (auto *E = dyn_cast(Module)) + SymbolSize = E->getSymbolSize(Symbol); + else SymbolSize = 0; - else if (error(Symbol.getSize(SymbolSize)) || - SymbolSize == UnknownAddressOrSize) - return; StringRef SymbolName; if (error(Symbol.getName(SymbolName))) return; @@ -164,6 +169,7 @@ DILineInfo ModuleInfo::symbolizeCode( DIInliningInfo ModuleInfo::symbolizeInlinedCode( uint64_t ModuleOffset, const LLVMSymbolizer::Options &Opts) const { DIInliningInfo InlinedContext; + if (DebugInfoContext) { InlinedContext = DebugInfoContext->getInliningInfoForAddress( ModuleOffset, getDILineInfoSpecifier(Opts)); @@ -426,7 +432,7 @@ LLVMSymbolizer::getObjectFileFromBinary(Binary *Bin, if (I != ObjectFileForArch.end()) return I->second; ErrorOr> ParsedObj = - UB->getObjectForArch(Triple(ArchName).getArch()); + UB->getObjectForArch(ArchName); if (ParsedObj) { Res = ParsedObj.get().get(); ParsedBinariesAndObjects.push_back(std::move(ParsedObj.get())); @@ -461,7 +467,20 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) { Modules.insert(make_pair(ModuleName, (ModuleInfo *)nullptr)); return nullptr; } - DIContext *Context = new DWARFContextInMemory(*Objects.second); + DIContext *Context = nullptr; + if (auto CoffObject = dyn_cast(Objects.first)) { + // If this is a COFF object, assume it contains PDB debug information. If + // we don't find any we will fall back to the DWARF case. + std::unique_ptr Session; + PDB_ErrorCode Error = loadDataForEXE(PDB_ReaderType::DIA, + Objects.first->getFileName(), Session); + if (Error == PDB_ErrorCode::Success) { + Context = new PDBContext(*CoffObject, std::move(Session), + Opts.RelativeAddresses); + } + } + if (!Context) + Context = new DWARFContextInMemory(*Objects.second); assert(Context); ModuleInfo *Info = new ModuleInfo(Objects.first, Context); Modules.insert(make_pair(ModuleName, Info)); @@ -508,7 +527,17 @@ std::string LLVMSymbolizer::DemangleName(const std::string &Name) { free(DemangledName); return Result; #else - return Name; + 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); #endif }