1*9880d681SAndroid Build Coastguard Worker //===-- LLVMSymbolize.cpp -------------------------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // Implementation for LLVM symbolization library.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/Symbolize/Symbolize.h"
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker #include "SymbolizableObjectFile.h"
17*9880d681SAndroid Build Coastguard Worker
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Config/config.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/DWARF/DWARFContext.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/PDB.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/PDBContext.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/COFF.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/ELFObjectFile.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/MachO.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/MachOUniversal.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/COFF.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Casting.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Compression.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/DataExtractor.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Errc.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FileSystem.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MemoryBuffer.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Path.h"
35*9880d681SAndroid Build Coastguard Worker #include <algorithm>
36*9880d681SAndroid Build Coastguard Worker #include <cassert>
37*9880d681SAndroid Build Coastguard Worker #include <cstdlib>
38*9880d681SAndroid Build Coastguard Worker #include <cstring>
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Worker #if defined(_MSC_VER)
41*9880d681SAndroid Build Coastguard Worker #include <Windows.h>
42*9880d681SAndroid Build Coastguard Worker #include <DbgHelp.h>
43*9880d681SAndroid Build Coastguard Worker #pragma comment(lib, "dbghelp.lib")
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Worker // Windows.h conflicts with our COFF header definitions.
46*9880d681SAndroid Build Coastguard Worker #ifdef IMAGE_FILE_MACHINE_I386
47*9880d681SAndroid Build Coastguard Worker #undef IMAGE_FILE_MACHINE_I386
48*9880d681SAndroid Build Coastguard Worker #endif
49*9880d681SAndroid Build Coastguard Worker #endif
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Worker namespace llvm {
52*9880d681SAndroid Build Coastguard Worker namespace symbolize {
53*9880d681SAndroid Build Coastguard Worker
symbolizeCode(const std::string & ModuleName,uint64_t ModuleOffset)54*9880d681SAndroid Build Coastguard Worker Expected<DILineInfo> LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
55*9880d681SAndroid Build Coastguard Worker uint64_t ModuleOffset) {
56*9880d681SAndroid Build Coastguard Worker SymbolizableModule *Info;
57*9880d681SAndroid Build Coastguard Worker if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName))
58*9880d681SAndroid Build Coastguard Worker Info = InfoOrErr.get();
59*9880d681SAndroid Build Coastguard Worker else
60*9880d681SAndroid Build Coastguard Worker return InfoOrErr.takeError();
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker // A null module means an error has already been reported. Return an empty
63*9880d681SAndroid Build Coastguard Worker // result.
64*9880d681SAndroid Build Coastguard Worker if (!Info)
65*9880d681SAndroid Build Coastguard Worker return DILineInfo();
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker // If the user is giving us relative addresses, add the preferred base of the
68*9880d681SAndroid Build Coastguard Worker // object to the offset before we do the query. It's what DIContext expects.
69*9880d681SAndroid Build Coastguard Worker if (Opts.RelativeAddresses)
70*9880d681SAndroid Build Coastguard Worker ModuleOffset += Info->getModulePreferredBase();
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Worker DILineInfo LineInfo = Info->symbolizeCode(ModuleOffset, Opts.PrintFunctions,
73*9880d681SAndroid Build Coastguard Worker Opts.UseSymbolTable);
74*9880d681SAndroid Build Coastguard Worker if (Opts.Demangle)
75*9880d681SAndroid Build Coastguard Worker LineInfo.FunctionName = DemangleName(LineInfo.FunctionName, Info);
76*9880d681SAndroid Build Coastguard Worker return LineInfo;
77*9880d681SAndroid Build Coastguard Worker }
78*9880d681SAndroid Build Coastguard Worker
79*9880d681SAndroid Build Coastguard Worker Expected<DIInliningInfo>
symbolizeInlinedCode(const std::string & ModuleName,uint64_t ModuleOffset)80*9880d681SAndroid Build Coastguard Worker LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName,
81*9880d681SAndroid Build Coastguard Worker uint64_t ModuleOffset) {
82*9880d681SAndroid Build Coastguard Worker SymbolizableModule *Info;
83*9880d681SAndroid Build Coastguard Worker if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName))
84*9880d681SAndroid Build Coastguard Worker Info = InfoOrErr.get();
85*9880d681SAndroid Build Coastguard Worker else
86*9880d681SAndroid Build Coastguard Worker return InfoOrErr.takeError();
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker // A null module means an error has already been reported. Return an empty
89*9880d681SAndroid Build Coastguard Worker // result.
90*9880d681SAndroid Build Coastguard Worker if (!Info)
91*9880d681SAndroid Build Coastguard Worker return DIInliningInfo();
92*9880d681SAndroid Build Coastguard Worker
93*9880d681SAndroid Build Coastguard Worker // If the user is giving us relative addresses, add the preferred base of the
94*9880d681SAndroid Build Coastguard Worker // object to the offset before we do the query. It's what DIContext expects.
95*9880d681SAndroid Build Coastguard Worker if (Opts.RelativeAddresses)
96*9880d681SAndroid Build Coastguard Worker ModuleOffset += Info->getModulePreferredBase();
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Worker DIInliningInfo InlinedContext = Info->symbolizeInlinedCode(
99*9880d681SAndroid Build Coastguard Worker ModuleOffset, Opts.PrintFunctions, Opts.UseSymbolTable);
100*9880d681SAndroid Build Coastguard Worker if (Opts.Demangle) {
101*9880d681SAndroid Build Coastguard Worker for (int i = 0, n = InlinedContext.getNumberOfFrames(); i < n; i++) {
102*9880d681SAndroid Build Coastguard Worker auto *Frame = InlinedContext.getMutableFrame(i);
103*9880d681SAndroid Build Coastguard Worker Frame->FunctionName = DemangleName(Frame->FunctionName, Info);
104*9880d681SAndroid Build Coastguard Worker }
105*9880d681SAndroid Build Coastguard Worker }
106*9880d681SAndroid Build Coastguard Worker return InlinedContext;
107*9880d681SAndroid Build Coastguard Worker }
108*9880d681SAndroid Build Coastguard Worker
symbolizeData(const std::string & ModuleName,uint64_t ModuleOffset)109*9880d681SAndroid Build Coastguard Worker Expected<DIGlobal> LLVMSymbolizer::symbolizeData(const std::string &ModuleName,
110*9880d681SAndroid Build Coastguard Worker uint64_t ModuleOffset) {
111*9880d681SAndroid Build Coastguard Worker SymbolizableModule *Info;
112*9880d681SAndroid Build Coastguard Worker if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName))
113*9880d681SAndroid Build Coastguard Worker Info = InfoOrErr.get();
114*9880d681SAndroid Build Coastguard Worker else
115*9880d681SAndroid Build Coastguard Worker return InfoOrErr.takeError();
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker // A null module means an error has already been reported. Return an empty
118*9880d681SAndroid Build Coastguard Worker // result.
119*9880d681SAndroid Build Coastguard Worker if (!Info)
120*9880d681SAndroid Build Coastguard Worker return DIGlobal();
121*9880d681SAndroid Build Coastguard Worker
122*9880d681SAndroid Build Coastguard Worker // If the user is giving us relative addresses, add the preferred base of
123*9880d681SAndroid Build Coastguard Worker // the object to the offset before we do the query. It's what DIContext
124*9880d681SAndroid Build Coastguard Worker // expects.
125*9880d681SAndroid Build Coastguard Worker if (Opts.RelativeAddresses)
126*9880d681SAndroid Build Coastguard Worker ModuleOffset += Info->getModulePreferredBase();
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Worker DIGlobal Global = Info->symbolizeData(ModuleOffset);
129*9880d681SAndroid Build Coastguard Worker if (Opts.Demangle)
130*9880d681SAndroid Build Coastguard Worker Global.Name = DemangleName(Global.Name, Info);
131*9880d681SAndroid Build Coastguard Worker return Global;
132*9880d681SAndroid Build Coastguard Worker }
133*9880d681SAndroid Build Coastguard Worker
flush()134*9880d681SAndroid Build Coastguard Worker void LLVMSymbolizer::flush() {
135*9880d681SAndroid Build Coastguard Worker ObjectForUBPathAndArch.clear();
136*9880d681SAndroid Build Coastguard Worker BinaryForPath.clear();
137*9880d681SAndroid Build Coastguard Worker ObjectPairForPathArch.clear();
138*9880d681SAndroid Build Coastguard Worker Modules.clear();
139*9880d681SAndroid Build Coastguard Worker }
140*9880d681SAndroid Build Coastguard Worker
141*9880d681SAndroid Build Coastguard Worker namespace {
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker // For Path="/path/to/foo" and Basename="foo" assume that debug info is in
144*9880d681SAndroid Build Coastguard Worker // /path/to/foo.dSYM/Contents/Resources/DWARF/foo.
145*9880d681SAndroid Build Coastguard Worker // For Path="/path/to/bar.dSYM" and Basename="foo" assume that debug info is in
146*9880d681SAndroid Build Coastguard Worker // /path/to/bar.dSYM/Contents/Resources/DWARF/foo.
getDarwinDWARFResourceForPath(const std::string & Path,const std::string & Basename)147*9880d681SAndroid Build Coastguard Worker std::string getDarwinDWARFResourceForPath(
148*9880d681SAndroid Build Coastguard Worker const std::string &Path, const std::string &Basename) {
149*9880d681SAndroid Build Coastguard Worker SmallString<16> ResourceName = StringRef(Path);
150*9880d681SAndroid Build Coastguard Worker if (sys::path::extension(Path) != ".dSYM") {
151*9880d681SAndroid Build Coastguard Worker ResourceName += ".dSYM";
152*9880d681SAndroid Build Coastguard Worker }
153*9880d681SAndroid Build Coastguard Worker sys::path::append(ResourceName, "Contents", "Resources", "DWARF");
154*9880d681SAndroid Build Coastguard Worker sys::path::append(ResourceName, Basename);
155*9880d681SAndroid Build Coastguard Worker return ResourceName.str();
156*9880d681SAndroid Build Coastguard Worker }
157*9880d681SAndroid Build Coastguard Worker
checkFileCRC(StringRef Path,uint32_t CRCHash)158*9880d681SAndroid Build Coastguard Worker bool checkFileCRC(StringRef Path, uint32_t CRCHash) {
159*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
160*9880d681SAndroid Build Coastguard Worker MemoryBuffer::getFileOrSTDIN(Path);
161*9880d681SAndroid Build Coastguard Worker if (!MB)
162*9880d681SAndroid Build Coastguard Worker return false;
163*9880d681SAndroid Build Coastguard Worker return !zlib::isAvailable() || CRCHash == zlib::crc32(MB.get()->getBuffer());
164*9880d681SAndroid Build Coastguard Worker }
165*9880d681SAndroid Build Coastguard Worker
findDebugBinary(const std::string & OrigPath,const std::string & DebuglinkName,uint32_t CRCHash,std::string & Result)166*9880d681SAndroid Build Coastguard Worker bool findDebugBinary(const std::string &OrigPath,
167*9880d681SAndroid Build Coastguard Worker const std::string &DebuglinkName, uint32_t CRCHash,
168*9880d681SAndroid Build Coastguard Worker std::string &Result) {
169*9880d681SAndroid Build Coastguard Worker std::string OrigRealPath = OrigPath;
170*9880d681SAndroid Build Coastguard Worker #if defined(HAVE_REALPATH)
171*9880d681SAndroid Build Coastguard Worker if (char *RP = realpath(OrigPath.c_str(), nullptr)) {
172*9880d681SAndroid Build Coastguard Worker OrigRealPath = RP;
173*9880d681SAndroid Build Coastguard Worker free(RP);
174*9880d681SAndroid Build Coastguard Worker }
175*9880d681SAndroid Build Coastguard Worker #endif
176*9880d681SAndroid Build Coastguard Worker SmallString<16> OrigDir(OrigRealPath);
177*9880d681SAndroid Build Coastguard Worker llvm::sys::path::remove_filename(OrigDir);
178*9880d681SAndroid Build Coastguard Worker SmallString<16> DebugPath = OrigDir;
179*9880d681SAndroid Build Coastguard Worker // Try /path/to/original_binary/debuglink_name
180*9880d681SAndroid Build Coastguard Worker llvm::sys::path::append(DebugPath, DebuglinkName);
181*9880d681SAndroid Build Coastguard Worker if (checkFileCRC(DebugPath, CRCHash)) {
182*9880d681SAndroid Build Coastguard Worker Result = DebugPath.str();
183*9880d681SAndroid Build Coastguard Worker return true;
184*9880d681SAndroid Build Coastguard Worker }
185*9880d681SAndroid Build Coastguard Worker // Try /path/to/original_binary/.debug/debuglink_name
186*9880d681SAndroid Build Coastguard Worker DebugPath = OrigRealPath;
187*9880d681SAndroid Build Coastguard Worker llvm::sys::path::append(DebugPath, ".debug", DebuglinkName);
188*9880d681SAndroid Build Coastguard Worker if (checkFileCRC(DebugPath, CRCHash)) {
189*9880d681SAndroid Build Coastguard Worker Result = DebugPath.str();
190*9880d681SAndroid Build Coastguard Worker return true;
191*9880d681SAndroid Build Coastguard Worker }
192*9880d681SAndroid Build Coastguard Worker // Try /usr/lib/debug/path/to/original_binary/debuglink_name
193*9880d681SAndroid Build Coastguard Worker DebugPath = "/usr/lib/debug";
194*9880d681SAndroid Build Coastguard Worker llvm::sys::path::append(DebugPath, llvm::sys::path::relative_path(OrigDir),
195*9880d681SAndroid Build Coastguard Worker DebuglinkName);
196*9880d681SAndroid Build Coastguard Worker if (checkFileCRC(DebugPath, CRCHash)) {
197*9880d681SAndroid Build Coastguard Worker Result = DebugPath.str();
198*9880d681SAndroid Build Coastguard Worker return true;
199*9880d681SAndroid Build Coastguard Worker }
200*9880d681SAndroid Build Coastguard Worker return false;
201*9880d681SAndroid Build Coastguard Worker }
202*9880d681SAndroid Build Coastguard Worker
getGNUDebuglinkContents(const ObjectFile * Obj,std::string & DebugName,uint32_t & CRCHash)203*9880d681SAndroid Build Coastguard Worker bool getGNUDebuglinkContents(const ObjectFile *Obj, std::string &DebugName,
204*9880d681SAndroid Build Coastguard Worker uint32_t &CRCHash) {
205*9880d681SAndroid Build Coastguard Worker if (!Obj)
206*9880d681SAndroid Build Coastguard Worker return false;
207*9880d681SAndroid Build Coastguard Worker for (const SectionRef &Section : Obj->sections()) {
208*9880d681SAndroid Build Coastguard Worker StringRef Name;
209*9880d681SAndroid Build Coastguard Worker Section.getName(Name);
210*9880d681SAndroid Build Coastguard Worker Name = Name.substr(Name.find_first_not_of("._"));
211*9880d681SAndroid Build Coastguard Worker if (Name == "gnu_debuglink") {
212*9880d681SAndroid Build Coastguard Worker StringRef Data;
213*9880d681SAndroid Build Coastguard Worker Section.getContents(Data);
214*9880d681SAndroid Build Coastguard Worker DataExtractor DE(Data, Obj->isLittleEndian(), 0);
215*9880d681SAndroid Build Coastguard Worker uint32_t Offset = 0;
216*9880d681SAndroid Build Coastguard Worker if (const char *DebugNameStr = DE.getCStr(&Offset)) {
217*9880d681SAndroid Build Coastguard Worker // 4-byte align the offset.
218*9880d681SAndroid Build Coastguard Worker Offset = (Offset + 3) & ~0x3;
219*9880d681SAndroid Build Coastguard Worker if (DE.isValidOffsetForDataOfSize(Offset, 4)) {
220*9880d681SAndroid Build Coastguard Worker DebugName = DebugNameStr;
221*9880d681SAndroid Build Coastguard Worker CRCHash = DE.getU32(&Offset);
222*9880d681SAndroid Build Coastguard Worker return true;
223*9880d681SAndroid Build Coastguard Worker }
224*9880d681SAndroid Build Coastguard Worker }
225*9880d681SAndroid Build Coastguard Worker break;
226*9880d681SAndroid Build Coastguard Worker }
227*9880d681SAndroid Build Coastguard Worker }
228*9880d681SAndroid Build Coastguard Worker return false;
229*9880d681SAndroid Build Coastguard Worker }
230*9880d681SAndroid Build Coastguard Worker
darwinDsymMatchesBinary(const MachOObjectFile * DbgObj,const MachOObjectFile * Obj)231*9880d681SAndroid Build Coastguard Worker bool darwinDsymMatchesBinary(const MachOObjectFile *DbgObj,
232*9880d681SAndroid Build Coastguard Worker const MachOObjectFile *Obj) {
233*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> dbg_uuid = DbgObj->getUuid();
234*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> bin_uuid = Obj->getUuid();
235*9880d681SAndroid Build Coastguard Worker if (dbg_uuid.empty() || bin_uuid.empty())
236*9880d681SAndroid Build Coastguard Worker return false;
237*9880d681SAndroid Build Coastguard Worker return !memcmp(dbg_uuid.data(), bin_uuid.data(), dbg_uuid.size());
238*9880d681SAndroid Build Coastguard Worker }
239*9880d681SAndroid Build Coastguard Worker
240*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
241*9880d681SAndroid Build Coastguard Worker
lookUpDsymFile(const std::string & ExePath,const MachOObjectFile * MachExeObj,const std::string & ArchName)242*9880d681SAndroid Build Coastguard Worker ObjectFile *LLVMSymbolizer::lookUpDsymFile(const std::string &ExePath,
243*9880d681SAndroid Build Coastguard Worker const MachOObjectFile *MachExeObj, const std::string &ArchName) {
244*9880d681SAndroid Build Coastguard Worker // On Darwin we may find DWARF in separate object file in
245*9880d681SAndroid Build Coastguard Worker // resource directory.
246*9880d681SAndroid Build Coastguard Worker std::vector<std::string> DsymPaths;
247*9880d681SAndroid Build Coastguard Worker StringRef Filename = sys::path::filename(ExePath);
248*9880d681SAndroid Build Coastguard Worker DsymPaths.push_back(getDarwinDWARFResourceForPath(ExePath, Filename));
249*9880d681SAndroid Build Coastguard Worker for (const auto &Path : Opts.DsymHints) {
250*9880d681SAndroid Build Coastguard Worker DsymPaths.push_back(getDarwinDWARFResourceForPath(Path, Filename));
251*9880d681SAndroid Build Coastguard Worker }
252*9880d681SAndroid Build Coastguard Worker for (const auto &Path : DsymPaths) {
253*9880d681SAndroid Build Coastguard Worker auto DbgObjOrErr = getOrCreateObject(Path, ArchName);
254*9880d681SAndroid Build Coastguard Worker if (!DbgObjOrErr) {
255*9880d681SAndroid Build Coastguard Worker // Ignore errors, the file might not exist.
256*9880d681SAndroid Build Coastguard Worker consumeError(DbgObjOrErr.takeError());
257*9880d681SAndroid Build Coastguard Worker continue;
258*9880d681SAndroid Build Coastguard Worker }
259*9880d681SAndroid Build Coastguard Worker ObjectFile *DbgObj = DbgObjOrErr.get();
260*9880d681SAndroid Build Coastguard Worker if (!DbgObj)
261*9880d681SAndroid Build Coastguard Worker continue;
262*9880d681SAndroid Build Coastguard Worker const MachOObjectFile *MachDbgObj = dyn_cast<const MachOObjectFile>(DbgObj);
263*9880d681SAndroid Build Coastguard Worker if (!MachDbgObj)
264*9880d681SAndroid Build Coastguard Worker continue;
265*9880d681SAndroid Build Coastguard Worker if (darwinDsymMatchesBinary(MachDbgObj, MachExeObj))
266*9880d681SAndroid Build Coastguard Worker return DbgObj;
267*9880d681SAndroid Build Coastguard Worker }
268*9880d681SAndroid Build Coastguard Worker return nullptr;
269*9880d681SAndroid Build Coastguard Worker }
270*9880d681SAndroid Build Coastguard Worker
lookUpDebuglinkObject(const std::string & Path,const ObjectFile * Obj,const std::string & ArchName)271*9880d681SAndroid Build Coastguard Worker ObjectFile *LLVMSymbolizer::lookUpDebuglinkObject(const std::string &Path,
272*9880d681SAndroid Build Coastguard Worker const ObjectFile *Obj,
273*9880d681SAndroid Build Coastguard Worker const std::string &ArchName) {
274*9880d681SAndroid Build Coastguard Worker std::string DebuglinkName;
275*9880d681SAndroid Build Coastguard Worker uint32_t CRCHash;
276*9880d681SAndroid Build Coastguard Worker std::string DebugBinaryPath;
277*9880d681SAndroid Build Coastguard Worker if (!getGNUDebuglinkContents(Obj, DebuglinkName, CRCHash))
278*9880d681SAndroid Build Coastguard Worker return nullptr;
279*9880d681SAndroid Build Coastguard Worker if (!findDebugBinary(Path, DebuglinkName, CRCHash, DebugBinaryPath))
280*9880d681SAndroid Build Coastguard Worker return nullptr;
281*9880d681SAndroid Build Coastguard Worker auto DbgObjOrErr = getOrCreateObject(DebugBinaryPath, ArchName);
282*9880d681SAndroid Build Coastguard Worker if (!DbgObjOrErr) {
283*9880d681SAndroid Build Coastguard Worker // Ignore errors, the file might not exist.
284*9880d681SAndroid Build Coastguard Worker consumeError(DbgObjOrErr.takeError());
285*9880d681SAndroid Build Coastguard Worker return nullptr;
286*9880d681SAndroid Build Coastguard Worker }
287*9880d681SAndroid Build Coastguard Worker return DbgObjOrErr.get();
288*9880d681SAndroid Build Coastguard Worker }
289*9880d681SAndroid Build Coastguard Worker
290*9880d681SAndroid Build Coastguard Worker Expected<LLVMSymbolizer::ObjectPair>
getOrCreateObjectPair(const std::string & Path,const std::string & ArchName)291*9880d681SAndroid Build Coastguard Worker LLVMSymbolizer::getOrCreateObjectPair(const std::string &Path,
292*9880d681SAndroid Build Coastguard Worker const std::string &ArchName) {
293*9880d681SAndroid Build Coastguard Worker const auto &I = ObjectPairForPathArch.find(std::make_pair(Path, ArchName));
294*9880d681SAndroid Build Coastguard Worker if (I != ObjectPairForPathArch.end()) {
295*9880d681SAndroid Build Coastguard Worker return I->second;
296*9880d681SAndroid Build Coastguard Worker }
297*9880d681SAndroid Build Coastguard Worker
298*9880d681SAndroid Build Coastguard Worker auto ObjOrErr = getOrCreateObject(Path, ArchName);
299*9880d681SAndroid Build Coastguard Worker if (!ObjOrErr) {
300*9880d681SAndroid Build Coastguard Worker ObjectPairForPathArch.insert(std::make_pair(std::make_pair(Path, ArchName),
301*9880d681SAndroid Build Coastguard Worker ObjectPair(nullptr, nullptr)));
302*9880d681SAndroid Build Coastguard Worker return ObjOrErr.takeError();
303*9880d681SAndroid Build Coastguard Worker }
304*9880d681SAndroid Build Coastguard Worker
305*9880d681SAndroid Build Coastguard Worker ObjectFile *Obj = ObjOrErr.get();
306*9880d681SAndroid Build Coastguard Worker assert(Obj != nullptr);
307*9880d681SAndroid Build Coastguard Worker ObjectFile *DbgObj = nullptr;
308*9880d681SAndroid Build Coastguard Worker
309*9880d681SAndroid Build Coastguard Worker if (auto MachObj = dyn_cast<const MachOObjectFile>(Obj))
310*9880d681SAndroid Build Coastguard Worker DbgObj = lookUpDsymFile(Path, MachObj, ArchName);
311*9880d681SAndroid Build Coastguard Worker if (!DbgObj)
312*9880d681SAndroid Build Coastguard Worker DbgObj = lookUpDebuglinkObject(Path, Obj, ArchName);
313*9880d681SAndroid Build Coastguard Worker if (!DbgObj)
314*9880d681SAndroid Build Coastguard Worker DbgObj = Obj;
315*9880d681SAndroid Build Coastguard Worker ObjectPair Res = std::make_pair(Obj, DbgObj);
316*9880d681SAndroid Build Coastguard Worker ObjectPairForPathArch.insert(
317*9880d681SAndroid Build Coastguard Worker std::make_pair(std::make_pair(Path, ArchName), Res));
318*9880d681SAndroid Build Coastguard Worker return Res;
319*9880d681SAndroid Build Coastguard Worker }
320*9880d681SAndroid Build Coastguard Worker
321*9880d681SAndroid Build Coastguard Worker Expected<ObjectFile *>
getOrCreateObject(const std::string & Path,const std::string & ArchName)322*9880d681SAndroid Build Coastguard Worker LLVMSymbolizer::getOrCreateObject(const std::string &Path,
323*9880d681SAndroid Build Coastguard Worker const std::string &ArchName) {
324*9880d681SAndroid Build Coastguard Worker const auto &I = BinaryForPath.find(Path);
325*9880d681SAndroid Build Coastguard Worker Binary *Bin = nullptr;
326*9880d681SAndroid Build Coastguard Worker if (I == BinaryForPath.end()) {
327*9880d681SAndroid Build Coastguard Worker Expected<OwningBinary<Binary>> BinOrErr = createBinary(Path);
328*9880d681SAndroid Build Coastguard Worker if (!BinOrErr) {
329*9880d681SAndroid Build Coastguard Worker BinaryForPath.insert(std::make_pair(Path, OwningBinary<Binary>()));
330*9880d681SAndroid Build Coastguard Worker return BinOrErr.takeError();
331*9880d681SAndroid Build Coastguard Worker }
332*9880d681SAndroid Build Coastguard Worker Bin = BinOrErr->getBinary();
333*9880d681SAndroid Build Coastguard Worker BinaryForPath.insert(std::make_pair(Path, std::move(BinOrErr.get())));
334*9880d681SAndroid Build Coastguard Worker } else {
335*9880d681SAndroid Build Coastguard Worker Bin = I->second.getBinary();
336*9880d681SAndroid Build Coastguard Worker }
337*9880d681SAndroid Build Coastguard Worker
338*9880d681SAndroid Build Coastguard Worker if (!Bin)
339*9880d681SAndroid Build Coastguard Worker return static_cast<ObjectFile *>(nullptr);
340*9880d681SAndroid Build Coastguard Worker
341*9880d681SAndroid Build Coastguard Worker if (MachOUniversalBinary *UB = dyn_cast_or_null<MachOUniversalBinary>(Bin)) {
342*9880d681SAndroid Build Coastguard Worker const auto &I = ObjectForUBPathAndArch.find(std::make_pair(Path, ArchName));
343*9880d681SAndroid Build Coastguard Worker if (I != ObjectForUBPathAndArch.end()) {
344*9880d681SAndroid Build Coastguard Worker return I->second.get();
345*9880d681SAndroid Build Coastguard Worker }
346*9880d681SAndroid Build Coastguard Worker Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
347*9880d681SAndroid Build Coastguard Worker UB->getObjectForArch(ArchName);
348*9880d681SAndroid Build Coastguard Worker if (!ObjOrErr) {
349*9880d681SAndroid Build Coastguard Worker ObjectForUBPathAndArch.insert(std::make_pair(
350*9880d681SAndroid Build Coastguard Worker std::make_pair(Path, ArchName), std::unique_ptr<ObjectFile>()));
351*9880d681SAndroid Build Coastguard Worker return ObjOrErr.takeError();
352*9880d681SAndroid Build Coastguard Worker }
353*9880d681SAndroid Build Coastguard Worker ObjectFile *Res = ObjOrErr->get();
354*9880d681SAndroid Build Coastguard Worker ObjectForUBPathAndArch.insert(std::make_pair(std::make_pair(Path, ArchName),
355*9880d681SAndroid Build Coastguard Worker std::move(ObjOrErr.get())));
356*9880d681SAndroid Build Coastguard Worker return Res;
357*9880d681SAndroid Build Coastguard Worker }
358*9880d681SAndroid Build Coastguard Worker if (Bin->isObject()) {
359*9880d681SAndroid Build Coastguard Worker return cast<ObjectFile>(Bin);
360*9880d681SAndroid Build Coastguard Worker }
361*9880d681SAndroid Build Coastguard Worker return errorCodeToError(object_error::arch_not_found);
362*9880d681SAndroid Build Coastguard Worker }
363*9880d681SAndroid Build Coastguard Worker
364*9880d681SAndroid Build Coastguard Worker Expected<SymbolizableModule *>
getOrCreateModuleInfo(const std::string & ModuleName)365*9880d681SAndroid Build Coastguard Worker LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) {
366*9880d681SAndroid Build Coastguard Worker const auto &I = Modules.find(ModuleName);
367*9880d681SAndroid Build Coastguard Worker if (I != Modules.end()) {
368*9880d681SAndroid Build Coastguard Worker return I->second.get();
369*9880d681SAndroid Build Coastguard Worker }
370*9880d681SAndroid Build Coastguard Worker std::string BinaryName = ModuleName;
371*9880d681SAndroid Build Coastguard Worker std::string ArchName = Opts.DefaultArch;
372*9880d681SAndroid Build Coastguard Worker size_t ColonPos = ModuleName.find_last_of(':');
373*9880d681SAndroid Build Coastguard Worker // Verify that substring after colon form a valid arch name.
374*9880d681SAndroid Build Coastguard Worker if (ColonPos != std::string::npos) {
375*9880d681SAndroid Build Coastguard Worker std::string ArchStr = ModuleName.substr(ColonPos + 1);
376*9880d681SAndroid Build Coastguard Worker if (Triple(ArchStr).getArch() != Triple::UnknownArch) {
377*9880d681SAndroid Build Coastguard Worker BinaryName = ModuleName.substr(0, ColonPos);
378*9880d681SAndroid Build Coastguard Worker ArchName = ArchStr;
379*9880d681SAndroid Build Coastguard Worker }
380*9880d681SAndroid Build Coastguard Worker }
381*9880d681SAndroid Build Coastguard Worker auto ObjectsOrErr = getOrCreateObjectPair(BinaryName, ArchName);
382*9880d681SAndroid Build Coastguard Worker if (!ObjectsOrErr) {
383*9880d681SAndroid Build Coastguard Worker // Failed to find valid object file.
384*9880d681SAndroid Build Coastguard Worker Modules.insert(
385*9880d681SAndroid Build Coastguard Worker std::make_pair(ModuleName, std::unique_ptr<SymbolizableModule>()));
386*9880d681SAndroid Build Coastguard Worker return ObjectsOrErr.takeError();
387*9880d681SAndroid Build Coastguard Worker }
388*9880d681SAndroid Build Coastguard Worker ObjectPair Objects = ObjectsOrErr.get();
389*9880d681SAndroid Build Coastguard Worker
390*9880d681SAndroid Build Coastguard Worker std::unique_ptr<DIContext> Context;
391*9880d681SAndroid Build Coastguard Worker // If this is a COFF object containing PDB info, use a PDBContext to
392*9880d681SAndroid Build Coastguard Worker // symbolize. Otherwise, use DWARF.
393*9880d681SAndroid Build Coastguard Worker if (auto CoffObject = dyn_cast<COFFObjectFile>(Objects.first)) {
394*9880d681SAndroid Build Coastguard Worker const debug_pdb_info *PDBInfo;
395*9880d681SAndroid Build Coastguard Worker StringRef PDBFileName;
396*9880d681SAndroid Build Coastguard Worker auto EC = CoffObject->getDebugPDBInfo(PDBInfo, PDBFileName);
397*9880d681SAndroid Build Coastguard Worker if (!EC && PDBInfo != nullptr) {
398*9880d681SAndroid Build Coastguard Worker using namespace pdb;
399*9880d681SAndroid Build Coastguard Worker std::unique_ptr<IPDBSession> Session;
400*9880d681SAndroid Build Coastguard Worker if (auto Err = loadDataForEXE(PDB_ReaderType::DIA,
401*9880d681SAndroid Build Coastguard Worker Objects.first->getFileName(), Session)) {
402*9880d681SAndroid Build Coastguard Worker Modules.insert(
403*9880d681SAndroid Build Coastguard Worker std::make_pair(ModuleName, std::unique_ptr<SymbolizableModule>()));
404*9880d681SAndroid Build Coastguard Worker return std::move(Err);
405*9880d681SAndroid Build Coastguard Worker }
406*9880d681SAndroid Build Coastguard Worker Context.reset(new PDBContext(*CoffObject, std::move(Session)));
407*9880d681SAndroid Build Coastguard Worker }
408*9880d681SAndroid Build Coastguard Worker }
409*9880d681SAndroid Build Coastguard Worker if (!Context)
410*9880d681SAndroid Build Coastguard Worker Context.reset(new DWARFContextInMemory(*Objects.second));
411*9880d681SAndroid Build Coastguard Worker assert(Context);
412*9880d681SAndroid Build Coastguard Worker auto InfoOrErr =
413*9880d681SAndroid Build Coastguard Worker SymbolizableObjectFile::create(Objects.first, std::move(Context));
414*9880d681SAndroid Build Coastguard Worker std::unique_ptr<SymbolizableModule> SymMod;
415*9880d681SAndroid Build Coastguard Worker if (InfoOrErr)
416*9880d681SAndroid Build Coastguard Worker SymMod = std::move(InfoOrErr.get());
417*9880d681SAndroid Build Coastguard Worker auto InsertResult =
418*9880d681SAndroid Build Coastguard Worker Modules.insert(std::make_pair(ModuleName, std::move(SymMod)));
419*9880d681SAndroid Build Coastguard Worker assert(InsertResult.second);
420*9880d681SAndroid Build Coastguard Worker if (auto EC = InfoOrErr.getError())
421*9880d681SAndroid Build Coastguard Worker return errorCodeToError(EC);
422*9880d681SAndroid Build Coastguard Worker return InsertResult.first->second.get();
423*9880d681SAndroid Build Coastguard Worker }
424*9880d681SAndroid Build Coastguard Worker
425*9880d681SAndroid Build Coastguard Worker namespace {
426*9880d681SAndroid Build Coastguard Worker
427*9880d681SAndroid Build Coastguard Worker // Undo these various manglings for Win32 extern "C" functions:
428*9880d681SAndroid Build Coastguard Worker // cdecl - _foo
429*9880d681SAndroid Build Coastguard Worker // stdcall - _foo@12
430*9880d681SAndroid Build Coastguard Worker // fastcall - @foo@12
431*9880d681SAndroid Build Coastguard Worker // vectorcall - foo@@12
432*9880d681SAndroid Build Coastguard Worker // These are all different linkage names for 'foo'.
demanglePE32ExternCFunc(StringRef SymbolName)433*9880d681SAndroid Build Coastguard Worker StringRef demanglePE32ExternCFunc(StringRef SymbolName) {
434*9880d681SAndroid Build Coastguard Worker // Remove any '_' or '@' prefix.
435*9880d681SAndroid Build Coastguard Worker char Front = SymbolName.empty() ? '\0' : SymbolName[0];
436*9880d681SAndroid Build Coastguard Worker if (Front == '_' || Front == '@')
437*9880d681SAndroid Build Coastguard Worker SymbolName = SymbolName.drop_front();
438*9880d681SAndroid Build Coastguard Worker
439*9880d681SAndroid Build Coastguard Worker // Remove any '@[0-9]+' suffix.
440*9880d681SAndroid Build Coastguard Worker if (Front != '?') {
441*9880d681SAndroid Build Coastguard Worker size_t AtPos = SymbolName.rfind('@');
442*9880d681SAndroid Build Coastguard Worker if (AtPos != StringRef::npos &&
443*9880d681SAndroid Build Coastguard Worker std::all_of(SymbolName.begin() + AtPos + 1, SymbolName.end(),
444*9880d681SAndroid Build Coastguard Worker [](char C) { return C >= '0' && C <= '9'; })) {
445*9880d681SAndroid Build Coastguard Worker SymbolName = SymbolName.substr(0, AtPos);
446*9880d681SAndroid Build Coastguard Worker }
447*9880d681SAndroid Build Coastguard Worker }
448*9880d681SAndroid Build Coastguard Worker
449*9880d681SAndroid Build Coastguard Worker // Remove any ending '@' for vectorcall.
450*9880d681SAndroid Build Coastguard Worker if (SymbolName.endswith("@"))
451*9880d681SAndroid Build Coastguard Worker SymbolName = SymbolName.drop_back();
452*9880d681SAndroid Build Coastguard Worker
453*9880d681SAndroid Build Coastguard Worker return SymbolName;
454*9880d681SAndroid Build Coastguard Worker }
455*9880d681SAndroid Build Coastguard Worker
456*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
457*9880d681SAndroid Build Coastguard Worker
458*9880d681SAndroid Build Coastguard Worker #if !defined(_MSC_VER)
459*9880d681SAndroid Build Coastguard Worker // Assume that __cxa_demangle is provided by libcxxabi (except for Windows).
460*9880d681SAndroid Build Coastguard Worker extern "C" char *__cxa_demangle(const char *mangled_name, char *output_buffer,
461*9880d681SAndroid Build Coastguard Worker size_t *length, int *status);
462*9880d681SAndroid Build Coastguard Worker #endif
463*9880d681SAndroid Build Coastguard Worker
DemangleName(const std::string & Name,const SymbolizableModule * ModInfo)464*9880d681SAndroid Build Coastguard Worker std::string LLVMSymbolizer::DemangleName(const std::string &Name,
465*9880d681SAndroid Build Coastguard Worker const SymbolizableModule *ModInfo) {
466*9880d681SAndroid Build Coastguard Worker #if !defined(_MSC_VER)
467*9880d681SAndroid Build Coastguard Worker // We can spoil names of symbols with C linkage, so use an heuristic
468*9880d681SAndroid Build Coastguard Worker // approach to check if the name should be demangled.
469*9880d681SAndroid Build Coastguard Worker if (Name.substr(0, 2) == "_Z") {
470*9880d681SAndroid Build Coastguard Worker int status = 0;
471*9880d681SAndroid Build Coastguard Worker char *DemangledName = __cxa_demangle(Name.c_str(), nullptr, nullptr, &status);
472*9880d681SAndroid Build Coastguard Worker if (status != 0)
473*9880d681SAndroid Build Coastguard Worker return Name;
474*9880d681SAndroid Build Coastguard Worker std::string Result = DemangledName;
475*9880d681SAndroid Build Coastguard Worker free(DemangledName);
476*9880d681SAndroid Build Coastguard Worker return Result;
477*9880d681SAndroid Build Coastguard Worker }
478*9880d681SAndroid Build Coastguard Worker #else
479*9880d681SAndroid Build Coastguard Worker if (!Name.empty() && Name.front() == '?') {
480*9880d681SAndroid Build Coastguard Worker // Only do MSVC C++ demangling on symbols starting with '?'.
481*9880d681SAndroid Build Coastguard Worker char DemangledName[1024] = {0};
482*9880d681SAndroid Build Coastguard Worker DWORD result = ::UnDecorateSymbolName(
483*9880d681SAndroid Build Coastguard Worker Name.c_str(), DemangledName, 1023,
484*9880d681SAndroid Build Coastguard Worker UNDNAME_NO_ACCESS_SPECIFIERS | // Strip public, private, protected
485*9880d681SAndroid Build Coastguard Worker UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall, etc
486*9880d681SAndroid Build Coastguard Worker UNDNAME_NO_THROW_SIGNATURES | // Strip throw() specifications
487*9880d681SAndroid Build Coastguard Worker UNDNAME_NO_MEMBER_TYPE | // Strip virtual, static, etc specifiers
488*9880d681SAndroid Build Coastguard Worker UNDNAME_NO_MS_KEYWORDS | // Strip all MS extension keywords
489*9880d681SAndroid Build Coastguard Worker UNDNAME_NO_FUNCTION_RETURNS); // Strip function return types
490*9880d681SAndroid Build Coastguard Worker return (result == 0) ? Name : std::string(DemangledName);
491*9880d681SAndroid Build Coastguard Worker }
492*9880d681SAndroid Build Coastguard Worker #endif
493*9880d681SAndroid Build Coastguard Worker if (ModInfo && ModInfo->isWin32Module())
494*9880d681SAndroid Build Coastguard Worker return std::string(demanglePE32ExternCFunc(Name));
495*9880d681SAndroid Build Coastguard Worker return Name;
496*9880d681SAndroid Build Coastguard Worker }
497*9880d681SAndroid Build Coastguard Worker
498*9880d681SAndroid Build Coastguard Worker } // namespace symbolize
499*9880d681SAndroid Build Coastguard Worker } // namespace llvm
500