[llvm-commits] [compiler-rt] r165389 - /compiler-rt/trunk/utils/llvm-symbolizer/llvm-symbolizer.cpp

Alexey Samsonov samsonov at google.com
Mon Oct 8 03:17:44 PDT 2012


Author: samsonov
Date: Mon Oct  8 05:17:44 2012
New Revision: 165389

URL: http://llvm.org/viewvc/llvm-project?rev=165389&view=rev
Log:
llvm-symbolizer for Mac: add support for reading DWARF from separate object file in resource directory generated by dsymutil. Fix minor symbol table lookup issues.

Modified:
    compiler-rt/trunk/utils/llvm-symbolizer/llvm-symbolizer.cpp

Modified: compiler-rt/trunk/utils/llvm-symbolizer/llvm-symbolizer.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/utils/llvm-symbolizer/llvm-symbolizer.cpp?rev=165389&r1=165388&r2=165389&view=diff
==============================================================================
--- compiler-rt/trunk/utils/llvm-symbolizer/llvm-symbolizer.cpp (original)
+++ compiler-rt/trunk/utils/llvm-symbolizer/llvm-symbolizer.cpp Mon Oct  8 05:17:44 2012
@@ -18,11 +18,14 @@
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/DebugInfo/DIContext.h"
+#include "llvm/Object/MachO.h"
 #include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Casting.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/PrettyStackTrace.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/raw_ostream.h"
@@ -84,6 +87,7 @@
  public:
   ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
       : Module(Obj), DebugInfoContext(DICtx) {}
+
   DILineInfo symbolizeCode(uint64_t ModuleOffset) const {
     DILineInfo LineInfo;
     if (DebugInfoContext) {
@@ -99,6 +103,7 @@
     }
     return LineInfo;
   }
+
   DIInliningInfo symbolizeInlinedCode(uint64_t ModuleOffset) const {
     DIInliningInfo InlinedContext;
     if (DebugInfoContext) {
@@ -127,8 +132,9 @@
     }
     return InlinedContext;
   }
+
  private:
-  bool getFunctionNameFromSymbolTable(size_t Address,
+  bool getFunctionNameFromSymbolTable(uint64_t Address,
                                       std::string &FunctionName) const {
     assert(Module);
     error_code ec;
@@ -138,11 +144,16 @@
       if (error(ec)) return false;
       uint64_t SymbolAddress;
       uint64_t SymbolSize;
-      if (error(si->getAddress(SymbolAddress))) continue;
-      if (error(si->getSize(SymbolSize))) continue;
+      SymbolRef::Type SymbolType;
+      if (error(si->getAddress(SymbolAddress)) ||
+          SymbolAddress == UnknownAddressOrSize) continue;
+      if (error(si->getSize(SymbolSize)) ||
+          SymbolSize == UnknownAddressOrSize) continue;
+      if (error(si->getType(SymbolType))) continue;
       // FIXME: If a function has alias, there are two entries in symbol table
       // with same address size. Make sure we choose the correct one.
-      if (SymbolAddress <= Address && Address < SymbolAddress + SymbolSize) {
+      if (SymbolAddress <= Address && Address < SymbolAddress + SymbolSize &&
+          SymbolType == SymbolRef::ST_Function) {
         StringRef Name;
         if (error(si->getName(Name))) continue;
         FunctionName = Name.str();
@@ -155,7 +166,6 @@
 
 typedef std::map<std::string, ModuleInfo*> ModuleMapTy;
 typedef ModuleMapTy::iterator ModuleMapIter;
-typedef ModuleMapTy::const_iterator ModuleMapConstIter;
 }  // namespace
 
 static ModuleMapTy Modules;
@@ -180,14 +190,62 @@
   return true;
 }
 
+static void getDebugInfoSections(const ObjectFile *Obj,
+                                 StringRef &DebugInfoSection,
+                                 StringRef &DebugAbbrevSection,
+                                 StringRef &DebugLineSection,
+                                 StringRef &DebugArangesSection, 
+                                 StringRef &DebugStringSection, 
+                                 StringRef &DebugRangesSection) {
+  if (Obj == 0)
+    return;
+  error_code ec;
+  for (section_iterator i = Obj->begin_sections(),
+                        e = Obj->end_sections();
+                        i != e; i.increment(ec)) {
+    if (error(ec)) break;
+    StringRef Name;
+    if (error(i->getName(Name))) continue;
+    StringRef Data;
+    if (error(i->getContents(Data))) continue;
+    if (isFullNameOfDwarfSection(Name, "debug_info"))
+      DebugInfoSection = Data;
+    else if (isFullNameOfDwarfSection(Name, "debug_abbrev"))
+      DebugAbbrevSection = Data;
+    else if (isFullNameOfDwarfSection(Name, "debug_line"))
+      DebugLineSection = Data;
+    // Don't use debug_aranges for now, as address ranges contained
+    // there may not cover all instructions in the module
+    // else if (isFullNameOfDwarfSection(Name, "debug_aranges"))
+    //   DebugArangesSection = Data;
+    else if (isFullNameOfDwarfSection(Name, "debug_str"))
+      DebugStringSection = Data;
+    else if (isFullNameOfDwarfSection(Name, "debug_ranges"))
+      DebugRangesSection = Data;
+  }
+}
+
+static ObjectFile *getObjectFile(const std::string &Path) {
+  OwningPtr<MemoryBuffer> Buff;
+  MemoryBuffer::getFile(Path, Buff);
+  return ObjectFile::createObjectFile(Buff.take());
+}
+
+static std::string getDarwinDWARFResourceForModule(const std::string &Path) {
+  StringRef Basename = sys::path::filename(Path);
+  const std::string &DSymDirectory = Path + ".dSYM";
+  SmallString<16> ResourceName = StringRef(DSymDirectory);
+  sys::path::append(ResourceName, "Contents", "Resources", "DWARF");
+  sys::path::append(ResourceName, Basename);
+  return ResourceName.str();
+}
+
 static ModuleInfo *getOrCreateModuleInfo(const std::string &ModuleName) {
   ModuleMapIter I = Modules.find(ModuleName);
   if (I != Modules.end())
     return I->second;
 
-  OwningPtr<MemoryBuffer> Buff;
-  MemoryBuffer::getFile(ModuleName, Buff);
-  ObjectFile *Obj = ObjectFile::createObjectFile(Buff.take());
+  ObjectFile *Obj = getObjectFile(ModuleName);
   if (Obj == 0) {
     // Module name doesn't point to a valid object file.
     Modules.insert(make_pair(ModuleName, (ModuleInfo*)0));
@@ -197,41 +255,30 @@
   DIContext *Context = 0;
   bool IsLittleEndian;
   if (getObjectEndianness(Obj, IsLittleEndian)) {
-    StringRef DebugInfoSection;
-    StringRef DebugAbbrevSection;
-    StringRef DebugLineSection;
-    StringRef DebugArangesSection;
-    StringRef DebugStringSection;
-    StringRef DebugRangesSection;
-    error_code ec;
-    for (section_iterator i = Obj->begin_sections(),
-                          e = Obj->end_sections();
-                          i != e; i.increment(ec)) {
-      if (error(ec)) break;
-      StringRef Name;
-      if (error(i->getName(Name))) continue;
-      StringRef Data;
-      if (error(i->getContents(Data))) continue;
-      if (isFullNameOfDwarfSection(Name, "debug_info"))
-        DebugInfoSection = Data;
-      else if (isFullNameOfDwarfSection(Name, "debug_abbrev"))
-        DebugAbbrevSection = Data;
-      else if (isFullNameOfDwarfSection(Name, "debug_line"))
-        DebugLineSection = Data;
-      // Don't use debug_aranges for now, as address ranges contained
-      // there may not cover all instructions in the module
-      // else if (isFullNameOfDwarfSection(Name, "debug_aranges"))
-      //   DebugArangesSection = Data;
-      else if (isFullNameOfDwarfSection(Name, "debug_str"))
-        DebugStringSection = Data;
-      else if (isFullNameOfDwarfSection(Name, "debug_ranges"))
-        DebugRangesSection = Data;
+    StringRef DebugInfo;
+    StringRef DebugAbbrev;
+    StringRef DebugLine;
+    StringRef DebugAranges;
+    StringRef DebugString;
+    StringRef DebugRanges;
+    getDebugInfoSections(Obj, DebugInfo, DebugAbbrev, DebugLine,
+                         DebugAranges, DebugString, DebugRanges);
+    
+    // On Darwin we may find DWARF in separate object file in
+    // resource directory.
+    if (isa<MachOObjectFile>(Obj)) {
+      const std::string &ResourceName = getDarwinDWARFResourceForModule(
+          ModuleName);
+      ObjectFile *ResourceObj = getObjectFile(ResourceName);
+      if (ResourceObj != 0)
+        getDebugInfoSections(ResourceObj, DebugInfo, DebugAbbrev, DebugLine,
+                             DebugAranges, DebugString, DebugRanges);
     }
 
     Context = DIContext::getDWARFContext(
-        IsLittleEndian, DebugInfoSection, DebugAbbrevSection,
-        DebugArangesSection, DebugLineSection, DebugStringSection,
-        DebugRangesSection);
+        IsLittleEndian, DebugInfo, DebugAbbrev,
+        DebugAranges, DebugLine, DebugString,
+        DebugRanges);
     assert(Context);
   }
 





More information about the llvm-commits mailing list