Re-sort #include lines again, prior to moving headers around.
[oota-llvm.git] / tools / llvm-symbolizer / LLVMSymbolize.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 "LLVMSymbolize.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/Config/config.h"
17 #include "llvm/Object/MachO.h"
18 #include "llvm/Support/Casting.h"
19 #include "llvm/Support/Compression.h"
20 #include "llvm/Support/DataExtractor.h"
21 #include "llvm/Support/FileSystem.h"
22 #include "llvm/Support/MemoryBuffer.h"
23 #include "llvm/Support/Path.h"
24 #include <sstream>
25 #include <stdlib.h>
26
27 namespace llvm {
28 namespace symbolize {
29
30 static bool error(error_code ec) {
31   if (!ec)
32     return false;
33   errs() << "LLVMSymbolizer: error reading file: " << ec.message() << ".\n";
34   return true;
35 }
36
37 static uint32_t
38 getDILineInfoSpecifierFlags(const LLVMSymbolizer::Options &Opts) {
39   uint32_t Flags = llvm::DILineInfoSpecifier::FileLineInfo |
40                    llvm::DILineInfoSpecifier::AbsoluteFilePath;
41   if (Opts.PrintFunctions)
42     Flags |= llvm::DILineInfoSpecifier::FunctionName;
43   return Flags;
44 }
45
46 static void patchFunctionNameInDILineInfo(const std::string &NewFunctionName,
47                                           DILineInfo &LineInfo) {
48   std::string FileName = LineInfo.getFileName();
49   LineInfo = DILineInfo(StringRef(FileName), StringRef(NewFunctionName),
50                         LineInfo.getLine(), LineInfo.getColumn());
51 }
52
53 ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
54     : Module(Obj), DebugInfoContext(DICtx) {
55   error_code ec;
56   for (symbol_iterator si = Module->begin_symbols(), se = Module->end_symbols();
57        si != se; si.increment(ec)) {
58     if (error(ec))
59       return;
60     SymbolRef::Type SymbolType;
61     if (error(si->getType(SymbolType)))
62       continue;
63     if (SymbolType != SymbolRef::ST_Function &&
64         SymbolType != SymbolRef::ST_Data)
65       continue;
66     uint64_t SymbolAddress;
67     if (error(si->getAddress(SymbolAddress)) ||
68         SymbolAddress == UnknownAddressOrSize)
69       continue;
70     uint64_t SymbolSize;
71     // Getting symbol size is linear for Mach-O files, so assume that symbol
72     // occupies the memory range up to the following symbol.
73     if (isa<MachOObjectFile>(Obj))
74       SymbolSize = 0;
75     else if (error(si->getSize(SymbolSize)) ||
76              SymbolSize == UnknownAddressOrSize)
77       continue;
78     StringRef SymbolName;
79     if (error(si->getName(SymbolName)))
80       continue;
81     // Mach-O symbol table names have leading underscore, skip it.
82     if (Module->isMachO() && SymbolName.size() > 0 && SymbolName[0] == '_')
83       SymbolName = SymbolName.drop_front();
84     // FIXME: If a function has alias, there are two entries in symbol table
85     // with same address size. Make sure we choose the correct one.
86     SymbolMapTy &M = SymbolType == SymbolRef::ST_Function ? Functions : Objects;
87     SymbolDesc SD = { SymbolAddress, SymbolSize };
88     M.insert(std::make_pair(SD, SymbolName));
89   }
90 }
91
92 bool ModuleInfo::getNameFromSymbolTable(SymbolRef::Type Type, uint64_t Address,
93                                         std::string &Name, uint64_t &Addr,
94                                         uint64_t &Size) const {
95   const SymbolMapTy &M = Type == SymbolRef::ST_Function ? Functions : Objects;
96   if (M.empty())
97     return false;
98   SymbolDesc SD = { Address, Address };
99   SymbolMapTy::const_iterator it = M.upper_bound(SD);
100   if (it == M.begin())
101     return false;
102   --it;
103   if (it->first.Size != 0 && it->first.Addr + it->first.Size <= Address)
104     return false;
105   Name = it->second.str();
106   Addr = it->first.Addr;
107   Size = it->first.Size;
108   return true;
109 }
110
111 DILineInfo ModuleInfo::symbolizeCode(
112     uint64_t ModuleOffset, const LLVMSymbolizer::Options &Opts) const {
113   DILineInfo LineInfo;
114   if (DebugInfoContext) {
115     LineInfo = DebugInfoContext->getLineInfoForAddress(
116         ModuleOffset, getDILineInfoSpecifierFlags(Opts));
117   }
118   // Override function name from symbol table if necessary.
119   if (Opts.PrintFunctions && Opts.UseSymbolTable) {
120     std::string FunctionName;
121     uint64_t Start, Size;
122     if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset,
123                                FunctionName, Start, Size)) {
124       patchFunctionNameInDILineInfo(FunctionName, LineInfo);
125     }
126   }
127   return LineInfo;
128 }
129
130 DIInliningInfo ModuleInfo::symbolizeInlinedCode(
131     uint64_t ModuleOffset, const LLVMSymbolizer::Options &Opts) const {
132   DIInliningInfo InlinedContext;
133   if (DebugInfoContext) {
134     InlinedContext = DebugInfoContext->getInliningInfoForAddress(
135         ModuleOffset, getDILineInfoSpecifierFlags(Opts));
136   }
137   // Make sure there is at least one frame in context.
138   if (InlinedContext.getNumberOfFrames() == 0) {
139     InlinedContext.addFrame(DILineInfo());
140   }
141   // Override the function name in lower frame with name from symbol table.
142   if (Opts.PrintFunctions && Opts.UseSymbolTable) {
143     DIInliningInfo PatchedInlinedContext;
144     for (uint32_t i = 0, n = InlinedContext.getNumberOfFrames(); i < n; i++) {
145       DILineInfo LineInfo = InlinedContext.getFrame(i);
146       if (i == n - 1) {
147         std::string FunctionName;
148         uint64_t Start, Size;
149         if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset,
150                                    FunctionName, Start, Size)) {
151           patchFunctionNameInDILineInfo(FunctionName, LineInfo);
152         }
153       }
154       PatchedInlinedContext.addFrame(LineInfo);
155     }
156     InlinedContext = PatchedInlinedContext;
157   }
158   return InlinedContext;
159 }
160
161 bool ModuleInfo::symbolizeData(uint64_t ModuleOffset, std::string &Name,
162                                uint64_t &Start, uint64_t &Size) const {
163   return getNameFromSymbolTable(SymbolRef::ST_Data, ModuleOffset, Name, Start,
164                                 Size);
165 }
166
167 const char LLVMSymbolizer::kBadString[] = "??";
168
169 std::string LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
170                                           uint64_t ModuleOffset) {
171   ModuleInfo *Info = getOrCreateModuleInfo(ModuleName);
172   if (Info == 0)
173     return printDILineInfo(DILineInfo());
174   if (Opts.PrintInlining) {
175     DIInliningInfo InlinedContext =
176         Info->symbolizeInlinedCode(ModuleOffset, Opts);
177     uint32_t FramesNum = InlinedContext.getNumberOfFrames();
178     assert(FramesNum > 0);
179     std::string Result;
180     for (uint32_t i = 0; i < FramesNum; i++) {
181       DILineInfo LineInfo = InlinedContext.getFrame(i);
182       Result += printDILineInfo(LineInfo);
183     }
184     return Result;
185   }
186   DILineInfo LineInfo = Info->symbolizeCode(ModuleOffset, Opts);
187   return printDILineInfo(LineInfo);
188 }
189
190 std::string LLVMSymbolizer::symbolizeData(const std::string &ModuleName,
191                                           uint64_t ModuleOffset) {
192   std::string Name = kBadString;
193   uint64_t Start = 0;
194   uint64_t Size = 0;
195   if (Opts.UseSymbolTable) {
196     if (ModuleInfo *Info = getOrCreateModuleInfo(ModuleName)) {
197       if (Info->symbolizeData(ModuleOffset, Name, Start, Size) && Opts.Demangle)
198         Name = DemangleGlobalName(Name);
199     }
200   }
201   std::stringstream ss;
202   ss << Name << "\n" << Start << " " << Size << "\n";
203   return ss.str();
204 }
205
206 void LLVMSymbolizer::flush() {
207   DeleteContainerSeconds(Modules);
208   DeleteContainerPointers(ParsedBinariesAndObjects);
209   BinaryForPath.clear();
210   ObjectFileForArch.clear();
211 }
212
213 static std::string getDarwinDWARFResourceForPath(const std::string &Path) {
214   StringRef Basename = sys::path::filename(Path);
215   const std::string &DSymDirectory = Path + ".dSYM";
216   SmallString<16> ResourceName = StringRef(DSymDirectory);
217   sys::path::append(ResourceName, "Contents", "Resources", "DWARF");
218   sys::path::append(ResourceName, Basename);
219   return ResourceName.str();
220 }
221
222 static bool checkFileCRC(StringRef Path, uint32_t CRCHash) {
223   OwningPtr<MemoryBuffer> MB;
224   if (MemoryBuffer::getFileOrSTDIN(Path, MB))
225     return false;
226   return !zlib::isAvailable() || CRCHash == zlib::crc32(MB->getBuffer());
227 }
228
229 static bool findDebugBinary(const std::string &OrigPath,
230                             const std::string &DebuglinkName, uint32_t CRCHash,
231                             std::string &Result) {
232   std::string OrigRealPath = OrigPath;
233 #if defined(HAVE_REALPATH)
234   if (char *RP = realpath(OrigPath.c_str(), NULL)) {
235     OrigRealPath = RP;
236     free(RP);
237   }
238 #endif
239   SmallString<16> OrigDir(OrigRealPath);
240   llvm::sys::path::remove_filename(OrigDir);
241   SmallString<16> DebugPath = OrigDir;
242   // Try /path/to/original_binary/debuglink_name
243   llvm::sys::path::append(DebugPath, DebuglinkName);
244   if (checkFileCRC(DebugPath, CRCHash)) {
245     Result = DebugPath.str();
246     return true;
247   }
248   // Try /path/to/original_binary/.debug/debuglink_name
249   DebugPath = OrigRealPath;
250   llvm::sys::path::append(DebugPath, ".debug", DebuglinkName);
251   if (checkFileCRC(DebugPath, CRCHash)) {
252     Result = DebugPath.str();
253     return true;
254   }
255   // Try /usr/lib/debug/path/to/original_binary/debuglink_name
256   DebugPath = "/usr/lib/debug";
257   llvm::sys::path::append(DebugPath, llvm::sys::path::relative_path(OrigDir),
258                           DebuglinkName);
259   if (checkFileCRC(DebugPath, CRCHash)) {
260     Result = DebugPath.str();
261     return true;
262   }
263   return false;
264 }
265
266 static bool getGNUDebuglinkContents(const Binary *Bin, std::string &DebugName,
267                                     uint32_t &CRCHash) {
268   const ObjectFile *Obj = dyn_cast<ObjectFile>(Bin);
269   if (!Obj)
270     return false;
271   error_code EC;
272   for (section_iterator I = Obj->begin_sections(), E = Obj->end_sections();
273        I != E; I.increment(EC)) {
274     StringRef Name;
275     I->getName(Name);
276     Name = Name.substr(Name.find_first_not_of("._"));
277     if (Name == "gnu_debuglink") {
278       StringRef Data;
279       I->getContents(Data);
280       DataExtractor DE(Data, Obj->isLittleEndian(), 0);
281       uint32_t Offset = 0;
282       if (const char *DebugNameStr = DE.getCStr(&Offset)) {
283         // 4-byte align the offset.
284         Offset = (Offset + 3) & ~0x3;
285         if (DE.isValidOffsetForDataOfSize(Offset, 4)) {
286           DebugName = DebugNameStr;
287           CRCHash = DE.getU32(&Offset);
288           return true;
289         }
290       }
291       break;
292     }
293   }
294   return false;
295 }
296
297 LLVMSymbolizer::BinaryPair
298 LLVMSymbolizer::getOrCreateBinary(const std::string &Path) {
299   BinaryMapTy::iterator I = BinaryForPath.find(Path);
300   if (I != BinaryForPath.end())
301     return I->second;
302   Binary *Bin = 0;
303   Binary *DbgBin = 0;
304   OwningPtr<Binary> ParsedBinary;
305   OwningPtr<Binary> ParsedDbgBinary;
306   if (!error(createBinary(Path, ParsedBinary))) {
307     // Check if it's a universal binary.
308     Bin = ParsedBinary.take();
309     ParsedBinariesAndObjects.push_back(Bin);
310     if (Bin->isMachO() || Bin->isMachOUniversalBinary()) {
311       // On Darwin we may find DWARF in separate object file in
312       // resource directory.
313       const std::string &ResourcePath =
314           getDarwinDWARFResourceForPath(Path);
315       bool ResourceFileExists = false;
316       if (!sys::fs::exists(ResourcePath, ResourceFileExists) &&
317           ResourceFileExists &&
318           !error(createBinary(ResourcePath, ParsedDbgBinary))) {
319         DbgBin = ParsedDbgBinary.take();
320         ParsedBinariesAndObjects.push_back(DbgBin);
321       }
322     }
323     // Try to locate the debug binary using .gnu_debuglink section.
324     if (DbgBin == 0) {
325       std::string DebuglinkName;
326       uint32_t CRCHash;
327       std::string DebugBinaryPath;
328       if (getGNUDebuglinkContents(Bin, DebuglinkName, CRCHash) &&
329           findDebugBinary(Path, DebuglinkName, CRCHash, DebugBinaryPath) &&
330           !error(createBinary(DebugBinaryPath, ParsedDbgBinary))) {
331         DbgBin = ParsedDbgBinary.take();
332         ParsedBinariesAndObjects.push_back(DbgBin);
333       }
334     }
335   }
336   if (DbgBin == 0)
337     DbgBin = Bin;
338   BinaryPair Res = std::make_pair(Bin, DbgBin);
339   BinaryForPath[Path] = Res;
340   return Res;
341 }
342
343 ObjectFile *
344 LLVMSymbolizer::getObjectFileFromBinary(Binary *Bin, const std::string &ArchName) {
345   if (Bin == 0)
346     return 0;
347   ObjectFile *Res = 0;
348   if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(Bin)) {
349     ObjectFileForArchMapTy::iterator I = ObjectFileForArch.find(
350         std::make_pair(UB, ArchName));
351     if (I != ObjectFileForArch.end())
352       return I->second;
353     OwningPtr<ObjectFile> ParsedObj;
354     if (!UB->getObjectForArch(Triple(ArchName).getArch(), ParsedObj)) {
355       Res = ParsedObj.take();
356       ParsedBinariesAndObjects.push_back(Res);
357     }
358     ObjectFileForArch[std::make_pair(UB, ArchName)] = Res;
359   } else if (Bin->isObject()) {
360     Res = cast<ObjectFile>(Bin);
361   }
362   return Res;
363 }
364
365 ModuleInfo *
366 LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) {
367   ModuleMapTy::iterator I = Modules.find(ModuleName);
368   if (I != Modules.end())
369     return I->second;
370   std::string BinaryName = ModuleName;
371   std::string ArchName = Opts.DefaultArch;
372   size_t ColonPos = ModuleName.find_last_of(':');
373   // Verify that substring after colon form a valid arch name.
374   if (ColonPos != std::string::npos) {
375     std::string ArchStr = ModuleName.substr(ColonPos + 1);
376     if (Triple(ArchStr).getArch() != Triple::UnknownArch) {
377       BinaryName = ModuleName.substr(0, ColonPos);
378       ArchName = ArchStr;
379     }
380   }
381   BinaryPair Binaries = getOrCreateBinary(BinaryName);
382   ObjectFile *Obj = getObjectFileFromBinary(Binaries.first, ArchName);
383   ObjectFile *DbgObj = getObjectFileFromBinary(Binaries.second, ArchName);
384
385   if (Obj == 0) {
386     // Failed to find valid object file.
387     Modules.insert(make_pair(ModuleName, (ModuleInfo *)0));
388     return 0;
389   }
390   DIContext *Context = DIContext::getDWARFContext(DbgObj);
391   assert(Context);
392   ModuleInfo *Info = new ModuleInfo(Obj, Context);
393   Modules.insert(make_pair(ModuleName, Info));
394   return Info;
395 }
396
397 std::string LLVMSymbolizer::printDILineInfo(DILineInfo LineInfo) const {
398   // By default, DILineInfo contains "<invalid>" for function/filename it
399   // cannot fetch. We replace it to "??" to make our output closer to addr2line.
400   static const std::string kDILineInfoBadString = "<invalid>";
401   std::stringstream Result;
402   if (Opts.PrintFunctions) {
403     std::string FunctionName = LineInfo.getFunctionName();
404     if (FunctionName == kDILineInfoBadString)
405       FunctionName = kBadString;
406     else if (Opts.Demangle)
407       FunctionName = DemangleName(FunctionName);
408     Result << FunctionName << "\n";
409   }
410   std::string Filename = LineInfo.getFileName();
411   if (Filename == kDILineInfoBadString)
412     Filename = kBadString;
413   Result << Filename << ":" << LineInfo.getLine() << ":" << LineInfo.getColumn()
414          << "\n";
415   return Result.str();
416 }
417
418 #if !defined(_MSC_VER)
419 // Assume that __cxa_demangle is provided by libcxxabi (except for Windows).
420 extern "C" char *__cxa_demangle(const char *mangled_name, char *output_buffer,
421                                 size_t *length, int *status);
422 #endif
423
424 std::string LLVMSymbolizer::DemangleName(const std::string &Name) {
425 #if !defined(_MSC_VER)
426   int status = 0;
427   char *DemangledName = __cxa_demangle(Name.c_str(), 0, 0, &status);
428   if (status != 0)
429     return Name;
430   std::string Result = DemangledName;
431   free(DemangledName);
432   return Result;
433 #else
434   return Name;
435 #endif
436 }
437
438 std::string LLVMSymbolizer::DemangleGlobalName(const std::string &Name) {
439   // We can spoil names of globals with C linkage, so use an heuristic
440   // approach to check if the name should be demangled.
441   return (Name.substr(0, 2) == "_Z") ? DemangleName(Name) : Name;
442 }
443
444 } // namespace symbolize
445 } // namespace llvm