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