LLVMSymbolize.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
1c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov//===-- LLVMSymbolize.cpp -------------------------------------------------===// 2c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov// 3c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov// The LLVM Compiler Infrastructure 4c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov// 5c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov// This file is distributed under the University of Illinois Open Source 6c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov// License. See LICENSE.TXT for details. 7c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov// 8c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov//===----------------------------------------------------------------------===// 9c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov// 10c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov// Implementation for LLVM symbolization library. 11c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov// 12c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov//===----------------------------------------------------------------------===// 13c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov 14c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov#include "LLVMSymbolize.h" 1551283a1513648b235925e8f931707ebdea217359Alexey Samsonov#include "llvm/ADT/STLExtras.h" 168228a8dd91fbc4c1443bc3f15847ca8be24094a2Alexey Samsonov#include "llvm/Config/config.h" 1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Object/ELFObjectFile.h" 18c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov#include "llvm/Object/MachO.h" 19c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov#include "llvm/Support/Casting.h" 206889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov#include "llvm/Support/Compression.h" 216889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov#include "llvm/Support/DataExtractor.h" 22888ca964a45696a1b3e60940d3c9ad8ae677ef1cAlexey Samsonov#include "llvm/Support/FileSystem.h" 236889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov#include "llvm/Support/MemoryBuffer.h" 24c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov#include "llvm/Support/Path.h" 25c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov#include <sstream> 268228a8dd91fbc4c1443bc3f15847ca8be24094a2Alexey Samsonov#include <stdlib.h> 27c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov 28c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonovnamespace llvm { 29c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonovnamespace symbolize { 30c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov 31b181919d86bd46fdb6c21d782ccabf754167951aDmitry Vyukovstatic bool error(error_code ec) { 32c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonov if (!ec) 33c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonov return false; 34b181919d86bd46fdb6c21d782ccabf754167951aDmitry Vyukov errs() << "LLVMSymbolizer: error reading file: " << ec.message() << ".\n"; 35b181919d86bd46fdb6c21d782ccabf754167951aDmitry Vyukov return true; 36b181919d86bd46fdb6c21d782ccabf754167951aDmitry Vyukov} 37b181919d86bd46fdb6c21d782ccabf754167951aDmitry Vyukov 38c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonovstatic uint32_t 39c4439c3508aa705add9dc46106270f0b3763b882Alexey SamsonovgetDILineInfoSpecifierFlags(const LLVMSymbolizer::Options &Opts) { 40c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov uint32_t Flags = llvm::DILineInfoSpecifier::FileLineInfo | 41c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov llvm::DILineInfoSpecifier::AbsoluteFilePath; 42c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov if (Opts.PrintFunctions) 43c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov Flags |= llvm::DILineInfoSpecifier::FunctionName; 44c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov return Flags; 45c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov} 46c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov 47c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonovstatic void patchFunctionNameInDILineInfo(const std::string &NewFunctionName, 48c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov DILineInfo &LineInfo) { 49c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov std::string FileName = LineInfo.getFileName(); 50c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov LineInfo = DILineInfo(StringRef(FileName), StringRef(NewFunctionName), 51c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov LineInfo.getLine(), LineInfo.getColumn()); 52c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov} 53c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov 54b181919d86bd46fdb6c21d782ccabf754167951aDmitry VyukovModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx) 55c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonov : Module(Obj), DebugInfoContext(DICtx) { 5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const SymbolRef &Symbol : Module->symbols()) { 5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines addSymbol(Symbol); 5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool NoSymbolTable = (Module->symbol_begin() == Module->symbol_end()); 6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (NoSymbolTable && Module->isELF()) { 6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Fallback to dynamic symbol table, if regular symbol table is stripped. 6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::pair<symbol_iterator, symbol_iterator> IDyn = 6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getELFDynamicSymbolIterators(Module); 6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (symbol_iterator si = IDyn.first, se = IDyn.second; si != se; ++si) { 6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines addSymbol(*si); 6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 67b181919d86bd46fdb6c21d782ccabf754167951aDmitry Vyukov } 68b181919d86bd46fdb6c21d782ccabf754167951aDmitry Vyukov} 69b181919d86bd46fdb6c21d782ccabf754167951aDmitry Vyukov 7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ModuleInfo::addSymbol(const SymbolRef &Symbol) { 7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SymbolRef::Type SymbolType; 7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Symbol.getType(SymbolType))) 7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (SymbolType != SymbolRef::ST_Function && SymbolType != SymbolRef::ST_Data) 7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t SymbolAddress; 7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Symbol.getAddress(SymbolAddress)) || 7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SymbolAddress == UnknownAddressOrSize) 7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t SymbolSize; 8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Getting symbol size is linear for Mach-O files, so assume that symbol 8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // occupies the memory range up to the following symbol. 8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (isa<MachOObjectFile>(Module)) 8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SymbolSize = 0; 8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (error(Symbol.getSize(SymbolSize)) || 8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SymbolSize == UnknownAddressOrSize) 8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef SymbolName; 8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Symbol.getName(SymbolName))) 9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Mach-O symbol table names have leading underscore, skip it. 9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Module->isMachO() && SymbolName.size() > 0 && SymbolName[0] == '_') 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SymbolName = SymbolName.drop_front(); 9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // FIXME: If a function has alias, there are two entries in symbol table 9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // with same address size. Make sure we choose the correct one. 9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SymbolMapTy &M = SymbolType == SymbolRef::ST_Function ? Functions : Objects; 9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SymbolDesc SD = { SymbolAddress, SymbolSize }; 9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines M.insert(std::make_pair(SD, SymbolName)); 9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 101b181919d86bd46fdb6c21d782ccabf754167951aDmitry Vyukovbool ModuleInfo::getNameFromSymbolTable(SymbolRef::Type Type, uint64_t Address, 102b181919d86bd46fdb6c21d782ccabf754167951aDmitry Vyukov std::string &Name, uint64_t &Addr, 103b181919d86bd46fdb6c21d782ccabf754167951aDmitry Vyukov uint64_t &Size) const { 104c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonov const SymbolMapTy &M = Type == SymbolRef::ST_Function ? Functions : Objects; 105888ca964a45696a1b3e60940d3c9ad8ae677ef1cAlexey Samsonov if (M.empty()) 106b181919d86bd46fdb6c21d782ccabf754167951aDmitry Vyukov return false; 107888ca964a45696a1b3e60940d3c9ad8ae677ef1cAlexey Samsonov SymbolDesc SD = { Address, Address }; 108888ca964a45696a1b3e60940d3c9ad8ae677ef1cAlexey Samsonov SymbolMapTy::const_iterator it = M.upper_bound(SD); 109b6564648a5d1601bef26a1eb3c9ef04ee1d1745fAlexey Samsonov if (it == M.begin()) 110b6564648a5d1601bef26a1eb3c9ef04ee1d1745fAlexey Samsonov return false; 111888ca964a45696a1b3e60940d3c9ad8ae677ef1cAlexey Samsonov --it; 112b6564648a5d1601bef26a1eb3c9ef04ee1d1745fAlexey Samsonov if (it->first.Size != 0 && it->first.Addr + it->first.Size <= Address) 113b181919d86bd46fdb6c21d782ccabf754167951aDmitry Vyukov return false; 114b181919d86bd46fdb6c21d782ccabf754167951aDmitry Vyukov Name = it->second.str(); 115b181919d86bd46fdb6c21d782ccabf754167951aDmitry Vyukov Addr = it->first.Addr; 116b6564648a5d1601bef26a1eb3c9ef04ee1d1745fAlexey Samsonov Size = it->first.Size; 117b181919d86bd46fdb6c21d782ccabf754167951aDmitry Vyukov return true; 118b181919d86bd46fdb6c21d782ccabf754167951aDmitry Vyukov} 119b181919d86bd46fdb6c21d782ccabf754167951aDmitry Vyukov 120c4439c3508aa705add9dc46106270f0b3763b882Alexey SamsonovDILineInfo ModuleInfo::symbolizeCode( 121c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonov uint64_t ModuleOffset, const LLVMSymbolizer::Options &Opts) const { 122c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov DILineInfo LineInfo; 123c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov if (DebugInfoContext) { 124c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov LineInfo = DebugInfoContext->getLineInfoForAddress( 125c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov ModuleOffset, getDILineInfoSpecifierFlags(Opts)); 126c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov } 127c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov // Override function name from symbol table if necessary. 128c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov if (Opts.PrintFunctions && Opts.UseSymbolTable) { 129c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov std::string FunctionName; 130c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov uint64_t Start, Size; 131c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonov if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset, 132c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonov FunctionName, Start, Size)) { 133c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov patchFunctionNameInDILineInfo(FunctionName, LineInfo); 134c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov } 135c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov } 136c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov return LineInfo; 137c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov} 138c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov 139c4439c3508aa705add9dc46106270f0b3763b882Alexey SamsonovDIInliningInfo ModuleInfo::symbolizeInlinedCode( 140c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonov uint64_t ModuleOffset, const LLVMSymbolizer::Options &Opts) const { 141c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov DIInliningInfo InlinedContext; 142c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov if (DebugInfoContext) { 143c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov InlinedContext = DebugInfoContext->getInliningInfoForAddress( 144c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov ModuleOffset, getDILineInfoSpecifierFlags(Opts)); 145c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov } 146c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov // Make sure there is at least one frame in context. 147c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov if (InlinedContext.getNumberOfFrames() == 0) { 148c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov InlinedContext.addFrame(DILineInfo()); 149c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov } 150c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov // Override the function name in lower frame with name from symbol table. 151c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov if (Opts.PrintFunctions && Opts.UseSymbolTable) { 152c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov DIInliningInfo PatchedInlinedContext; 153c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonov for (uint32_t i = 0, n = InlinedContext.getNumberOfFrames(); i < n; i++) { 154c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov DILineInfo LineInfo = InlinedContext.getFrame(i); 155c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov if (i == n - 1) { 156c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov std::string FunctionName; 157c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov uint64_t Start, Size; 158c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonov if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset, 159c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonov FunctionName, Start, Size)) { 160c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov patchFunctionNameInDILineInfo(FunctionName, LineInfo); 161c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov } 162c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov } 163c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov PatchedInlinedContext.addFrame(LineInfo); 164c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov } 165c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov InlinedContext = PatchedInlinedContext; 166c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov } 167c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov return InlinedContext; 168c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov} 169c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov 170c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonovbool ModuleInfo::symbolizeData(uint64_t ModuleOffset, std::string &Name, 171c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov uint64_t &Start, uint64_t &Size) const { 172c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonov return getNameFromSymbolTable(SymbolRef::ST_Data, ModuleOffset, Name, Start, 173c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonov Size); 174c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov} 175c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov 176638c63ccf74807bbbff444d527a0acad592b3802Alexey Samsonovconst char LLVMSymbolizer::kBadString[] = "??"; 177c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov 178c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonovstd::string LLVMSymbolizer::symbolizeCode(const std::string &ModuleName, 179c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov uint64_t ModuleOffset) { 180c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov ModuleInfo *Info = getOrCreateModuleInfo(ModuleName); 181c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov if (Info == 0) 182c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov return printDILineInfo(DILineInfo()); 183c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov if (Opts.PrintInlining) { 184c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonov DIInliningInfo InlinedContext = 185c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonov Info->symbolizeInlinedCode(ModuleOffset, Opts); 186c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov uint32_t FramesNum = InlinedContext.getNumberOfFrames(); 187c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov assert(FramesNum > 0); 188c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov std::string Result; 189c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov for (uint32_t i = 0; i < FramesNum; i++) { 190c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov DILineInfo LineInfo = InlinedContext.getFrame(i); 191c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov Result += printDILineInfo(LineInfo); 192c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov } 193c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov return Result; 194c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov } 195c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov DILineInfo LineInfo = Info->symbolizeCode(ModuleOffset, Opts); 196c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov return printDILineInfo(LineInfo); 197c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov} 198c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov 199c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonovstd::string LLVMSymbolizer::symbolizeData(const std::string &ModuleName, 200c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov uint64_t ModuleOffset) { 201c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov std::string Name = kBadString; 202c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov uint64_t Start = 0; 203c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov uint64_t Size = 0; 204c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov if (Opts.UseSymbolTable) { 205c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov if (ModuleInfo *Info = getOrCreateModuleInfo(ModuleName)) { 206c071f89a770d6c66e6b29fdf013fa88454fc0ac6Alexey Samsonov if (Info->symbolizeData(ModuleOffset, Name, Start, Size) && Opts.Demangle) 20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Name = DemangleName(Name); 208c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov } 209c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov } 210c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov std::stringstream ss; 211c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov ss << Name << "\n" << Start << " " << Size << "\n"; 212c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov return ss.str(); 213c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov} 214c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov 215e9e10d18df7ba3ec65c37eaa25131fbd5c1b130eDmitry Vyukovvoid LLVMSymbolizer::flush() { 21651283a1513648b235925e8f931707ebdea217359Alexey Samsonov DeleteContainerSeconds(Modules); 2178175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov DeleteContainerPointers(ParsedBinariesAndObjects); 2180ed872cdd1e5d7d60983854ea49aff13aa3280c1Alexey Samsonov BinaryForPath.clear(); 2190ed872cdd1e5d7d60983854ea49aff13aa3280c1Alexey Samsonov ObjectFileForArch.clear(); 220e9e10d18df7ba3ec65c37eaa25131fbd5c1b130eDmitry Vyukov} 221e9e10d18df7ba3ec65c37eaa25131fbd5c1b130eDmitry Vyukov 2228175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonovstatic std::string getDarwinDWARFResourceForPath(const std::string &Path) { 223c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov StringRef Basename = sys::path::filename(Path); 224c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov const std::string &DSymDirectory = Path + ".dSYM"; 225c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov SmallString<16> ResourceName = StringRef(DSymDirectory); 226c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov sys::path::append(ResourceName, "Contents", "Resources", "DWARF"); 227c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov sys::path::append(ResourceName, Basename); 228c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov return ResourceName.str(); 229c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov} 230c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov 2316889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonovstatic bool checkFileCRC(StringRef Path, uint32_t CRCHash) { 23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<MemoryBuffer> MB; 2336889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov if (MemoryBuffer::getFileOrSTDIN(Path, MB)) 2346889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov return false; 2356889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov return !zlib::isAvailable() || CRCHash == zlib::crc32(MB->getBuffer()); 2366889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov} 2376889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov 2386889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonovstatic bool findDebugBinary(const std::string &OrigPath, 2396889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov const std::string &DebuglinkName, uint32_t CRCHash, 2406889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov std::string &Result) { 2418228a8dd91fbc4c1443bc3f15847ca8be24094a2Alexey Samsonov std::string OrigRealPath = OrigPath; 2428228a8dd91fbc4c1443bc3f15847ca8be24094a2Alexey Samsonov#if defined(HAVE_REALPATH) 2438228a8dd91fbc4c1443bc3f15847ca8be24094a2Alexey Samsonov if (char *RP = realpath(OrigPath.c_str(), NULL)) { 2448228a8dd91fbc4c1443bc3f15847ca8be24094a2Alexey Samsonov OrigRealPath = RP; 2458228a8dd91fbc4c1443bc3f15847ca8be24094a2Alexey Samsonov free(RP); 2468228a8dd91fbc4c1443bc3f15847ca8be24094a2Alexey Samsonov } 2478228a8dd91fbc4c1443bc3f15847ca8be24094a2Alexey Samsonov#endif 2488228a8dd91fbc4c1443bc3f15847ca8be24094a2Alexey Samsonov SmallString<16> OrigDir(OrigRealPath); 2496889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov llvm::sys::path::remove_filename(OrigDir); 2506889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov SmallString<16> DebugPath = OrigDir; 2516889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov // Try /path/to/original_binary/debuglink_name 2526889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov llvm::sys::path::append(DebugPath, DebuglinkName); 2536889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov if (checkFileCRC(DebugPath, CRCHash)) { 2546889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov Result = DebugPath.str(); 2556889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov return true; 2566889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov } 2576889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov // Try /path/to/original_binary/.debug/debuglink_name 2588228a8dd91fbc4c1443bc3f15847ca8be24094a2Alexey Samsonov DebugPath = OrigRealPath; 2596889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov llvm::sys::path::append(DebugPath, ".debug", DebuglinkName); 2606889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov if (checkFileCRC(DebugPath, CRCHash)) { 2616889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov Result = DebugPath.str(); 2626889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov return true; 2636889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov } 2646889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov // Try /usr/lib/debug/path/to/original_binary/debuglink_name 2656889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov DebugPath = "/usr/lib/debug"; 2666889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov llvm::sys::path::append(DebugPath, llvm::sys::path::relative_path(OrigDir), 2676889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov DebuglinkName); 2686889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov if (checkFileCRC(DebugPath, CRCHash)) { 2696889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov Result = DebugPath.str(); 2706889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov return true; 2716889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov } 2726889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov return false; 2736889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov} 2746889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov 2756889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonovstatic bool getGNUDebuglinkContents(const Binary *Bin, std::string &DebugName, 2766889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov uint32_t &CRCHash) { 2776889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov const ObjectFile *Obj = dyn_cast<ObjectFile>(Bin); 2786889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov if (!Obj) 2796889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov return false; 28036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const SectionRef &Section : Obj->sections()) { 2816889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov StringRef Name; 28236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Section.getName(Name); 2836889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov Name = Name.substr(Name.find_first_not_of("._")); 2846889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov if (Name == "gnu_debuglink") { 2856889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov StringRef Data; 28636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Section.getContents(Data); 2876889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov DataExtractor DE(Data, Obj->isLittleEndian(), 0); 2886889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov uint32_t Offset = 0; 2896889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov if (const char *DebugNameStr = DE.getCStr(&Offset)) { 2906889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov // 4-byte align the offset. 2916889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov Offset = (Offset + 3) & ~0x3; 2926889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov if (DE.isValidOffsetForDataOfSize(Offset, 4)) { 2936889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov DebugName = DebugNameStr; 2946889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov CRCHash = DE.getU32(&Offset); 2956889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov return true; 2966889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov } 2976889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov } 2986889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov break; 2996889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov } 3006889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov } 3016889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov return false; 3026889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov} 3036889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov 3048175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey SamsonovLLVMSymbolizer::BinaryPair 3058175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey SamsonovLLVMSymbolizer::getOrCreateBinary(const std::string &Path) { 3068175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov BinaryMapTy::iterator I = BinaryForPath.find(Path); 3078175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov if (I != BinaryForPath.end()) 3088175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov return I->second; 3098175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov Binary *Bin = 0; 3108175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov Binary *DbgBin = 0; 31136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ErrorOr<Binary *> BinaryOrErr = createBinary(Path); 31236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!error(BinaryOrErr.getError())) { 31336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Binary> ParsedBinary(BinaryOrErr.get()); 3148175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov // Check if it's a universal binary. 31536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Bin = ParsedBinary.release(); 3168175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov ParsedBinariesAndObjects.push_back(Bin); 3178175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov if (Bin->isMachO() || Bin->isMachOUniversalBinary()) { 3188175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov // On Darwin we may find DWARF in separate object file in 3198175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov // resource directory. 3208175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov const std::string &ResourcePath = 3218175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov getDarwinDWARFResourceForPath(Path); 32236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BinaryOrErr = createBinary(ResourcePath); 32336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines error_code EC = BinaryOrErr.getError(); 32436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (EC != errc::no_such_file_or_directory && !error(EC)) { 32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DbgBin = BinaryOrErr.get(); 3268175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov ParsedBinariesAndObjects.push_back(DbgBin); 3278175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov } 3288175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov } 3296889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov // Try to locate the debug binary using .gnu_debuglink section. 3306889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov if (DbgBin == 0) { 3316889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov std::string DebuglinkName; 3326889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov uint32_t CRCHash; 3336889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov std::string DebugBinaryPath; 3346889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov if (getGNUDebuglinkContents(Bin, DebuglinkName, CRCHash) && 33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines findDebugBinary(Path, DebuglinkName, CRCHash, DebugBinaryPath)) { 33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BinaryOrErr = createBinary(DebugBinaryPath); 33736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!error(BinaryOrErr.getError())) { 33836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DbgBin = BinaryOrErr.get(); 33936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ParsedBinariesAndObjects.push_back(DbgBin); 34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 3416889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov } 3426889483ca4bd5f2634c9041aa076aad01ac38b39Alexey Samsonov } 3438175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov } 3448175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov if (DbgBin == 0) 3458175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov DbgBin = Bin; 3468175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov BinaryPair Res = std::make_pair(Bin, DbgBin); 3478175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov BinaryForPath[Path] = Res; 3488175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov return Res; 3498175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov} 3508175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov 3518175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey SamsonovObjectFile * 3528175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey SamsonovLLVMSymbolizer::getObjectFileFromBinary(Binary *Bin, const std::string &ArchName) { 3538175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov if (Bin == 0) 3548175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov return 0; 3558175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov ObjectFile *Res = 0; 3568175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(Bin)) { 3578175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov ObjectFileForArchMapTy::iterator I = ObjectFileForArch.find( 3588175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov std::make_pair(UB, ArchName)); 3598175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov if (I != ObjectFileForArch.end()) 3608175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov return I->second; 36136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<ObjectFile> ParsedObj; 3628175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov if (!UB->getObjectForArch(Triple(ArchName).getArch(), ParsedObj)) { 36336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Res = ParsedObj.release(); 3648175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov ParsedBinariesAndObjects.push_back(Res); 3658175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov } 3668175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov ObjectFileForArch[std::make_pair(UB, ArchName)] = Res; 3678175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov } else if (Bin->isObject()) { 3688175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov Res = cast<ObjectFile>(Bin); 3698175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov } 3708175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov return Res; 3718175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov} 3728175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov 373c4439c3508aa705add9dc46106270f0b3763b882Alexey SamsonovModuleInfo * 374c4439c3508aa705add9dc46106270f0b3763b882Alexey SamsonovLLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) { 375c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov ModuleMapTy::iterator I = Modules.find(ModuleName); 376c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov if (I != Modules.end()) 377c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov return I->second; 3788175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov std::string BinaryName = ModuleName; 3798175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov std::string ArchName = Opts.DefaultArch; 380df959c70c935fb98cf5adadc3e712d54ca322a85Alexey Samsonov size_t ColonPos = ModuleName.find_last_of(':'); 381df959c70c935fb98cf5adadc3e712d54ca322a85Alexey Samsonov // Verify that substring after colon form a valid arch name. 3828175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov if (ColonPos != std::string::npos) { 383df959c70c935fb98cf5adadc3e712d54ca322a85Alexey Samsonov std::string ArchStr = ModuleName.substr(ColonPos + 1); 3841e65bf2628233e98f2406ec7acc901cd3b504915NAKAMURA Takumi if (Triple(ArchStr).getArch() != Triple::UnknownArch) { 385df959c70c935fb98cf5adadc3e712d54ca322a85Alexey Samsonov BinaryName = ModuleName.substr(0, ColonPos); 386df959c70c935fb98cf5adadc3e712d54ca322a85Alexey Samsonov ArchName = ArchStr; 387df959c70c935fb98cf5adadc3e712d54ca322a85Alexey Samsonov } 3888175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov } 3898175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov BinaryPair Binaries = getOrCreateBinary(BinaryName); 3908175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov ObjectFile *Obj = getObjectFileFromBinary(Binaries.first, ArchName); 3918175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov ObjectFile *DbgObj = getObjectFileFromBinary(Binaries.second, ArchName); 392c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov 393c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov if (Obj == 0) { 3948175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov // Failed to find valid object file. 395c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonov Modules.insert(make_pair(ModuleName, (ModuleInfo *)0)); 396c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov return 0; 397c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov } 3988175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov DIContext *Context = DIContext::getDWARFContext(DbgObj); 3998175bc3d3bc8567a90b9dd50d68c1423baffd63bAlexey Samsonov assert(Context); 400c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov ModuleInfo *Info = new ModuleInfo(Obj, Context); 401c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov Modules.insert(make_pair(ModuleName, Info)); 402c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov return Info; 403c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov} 404c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov 405c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonovstd::string LLVMSymbolizer::printDILineInfo(DILineInfo LineInfo) const { 406c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov // By default, DILineInfo contains "<invalid>" for function/filename it 407c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov // cannot fetch. We replace it to "??" to make our output closer to addr2line. 408c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov static const std::string kDILineInfoBadString = "<invalid>"; 409c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov std::stringstream Result; 410c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov if (Opts.PrintFunctions) { 411c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov std::string FunctionName = LineInfo.getFunctionName(); 412c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov if (FunctionName == kDILineInfoBadString) 413c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov FunctionName = kBadString; 414c071f89a770d6c66e6b29fdf013fa88454fc0ac6Alexey Samsonov else if (Opts.Demangle) 415c071f89a770d6c66e6b29fdf013fa88454fc0ac6Alexey Samsonov FunctionName = DemangleName(FunctionName); 416c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov Result << FunctionName << "\n"; 417c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov } 418c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov std::string Filename = LineInfo.getFileName(); 419c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov if (Filename == kDILineInfoBadString) 420c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov Filename = kBadString; 421c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonov Result << Filename << ":" << LineInfo.getLine() << ":" << LineInfo.getColumn() 422c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonov << "\n"; 423c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov return Result.str(); 424c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov} 425c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov 426c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov#if !defined(_MSC_VER) 427c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov// Assume that __cxa_demangle is provided by libcxxabi (except for Windows). 428c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonovextern "C" char *__cxa_demangle(const char *mangled_name, char *output_buffer, 429c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov size_t *length, int *status); 430c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov#endif 431c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov 432c071f89a770d6c66e6b29fdf013fa88454fc0ac6Alexey Samsonovstd::string LLVMSymbolizer::DemangleName(const std::string &Name) { 433c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov#if !defined(_MSC_VER) 43436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We can spoil names of symbols with C linkage, so use an heuristic 43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // approach to check if the name should be demangled. 43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Name.substr(0, 2) != "_Z") 43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Name; 438c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov int status = 0; 439c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov char *DemangledName = __cxa_demangle(Name.c_str(), 0, 0, &status); 440c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov if (status != 0) 441c071f89a770d6c66e6b29fdf013fa88454fc0ac6Alexey Samsonov return Name; 442c071f89a770d6c66e6b29fdf013fa88454fc0ac6Alexey Samsonov std::string Result = DemangledName; 443c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov free(DemangledName); 444c071f89a770d6c66e6b29fdf013fa88454fc0ac6Alexey Samsonov return Result; 445c071f89a770d6c66e6b29fdf013fa88454fc0ac6Alexey Samsonov#else 446c071f89a770d6c66e6b29fdf013fa88454fc0ac6Alexey Samsonov return Name; 447c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov#endif 448c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov} 449c4c7ea3184335259da63d973acbed2043e8a6523Alexey Samsonov 450c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonov} // namespace symbolize 451c4439c3508aa705add9dc46106270f0b3763b882Alexey Samsonov} // namespace llvm 452