[llvm-commits] [PATCH] llvm-symbolizer: symbolize global variables

Dmitry Vyukov dvyukov at google.com
Thu Jan 10 01:12:11 PST 2013


Hi kcc, samsonov, eugenis,

Add DATA command that allows to symbolize global variables.
Example:
>DATA bin/clang 0x26e8e40
<llvm::SparcSubTypeKV 40799808 416


http://llvm-reviews.chandlerc.com/D277

Files:
  tools/llvm-symbolizer/llvm-symbolizer.cpp

Index: tools/llvm-symbolizer/llvm-symbolizer.cpp
===================================================================
--- tools/llvm-symbolizer/llvm-symbolizer.cpp
+++ tools/llvm-symbolizer/llvm-symbolizer.cpp
@@ -96,7 +96,9 @@
     // Override function name from symbol table if necessary.
     if (PrintFunctions && UseSymbolTable) {
       std::string Function;
-      if (getFunctionNameFromSymbolTable(ModuleOffset, Function)) {
+      uint64_t Start, Size;
+      if (getNameFromSymbolTable(SymbolRef::ST_Function,
+                                 ModuleOffset, Function, Start, Size)) {
         patchFunctionNameInDILineInfo(Function, LineInfo);
       }
     }
@@ -121,7 +123,9 @@
         DILineInfo LineInfo = InlinedContext.getFrame(i);
         if (i == n - 1) {
           std::string Function;
-          if (getFunctionNameFromSymbolTable(ModuleOffset, Function)) {
+          uint64_t Start, Size;
+          if (getNameFromSymbolTable(SymbolRef::ST_Function,
+                                     ModuleOffset, Function, Start, Size)) {
             patchFunctionNameInDILineInfo(Function, LineInfo);
           }
         }
@@ -132,9 +136,18 @@
     return InlinedContext;
   }
 
+  bool symbolizeData(uint64_t ModuleOffset, std::string &Name,
+                     uint64_t &Start, uint64_t &Size) const {
+    return getNameFromSymbolTable(SymbolRef::ST_Data,
+                                  ModuleOffset, Name, Start, Size);
+  }
+
  private:
-  bool getFunctionNameFromSymbolTable(uint64_t Address,
-                                      std::string &FunctionName) const {
+  bool getNameFromSymbolTable(SymbolRef::Type Type,
+                              uint64_t Address,
+                              std::string &Name,
+                              uint64_t &Addr,
+                              uint64_t &Size) const {
     assert(Module);
     error_code ec;
     for (symbol_iterator si = Module->begin_symbols(),
@@ -152,10 +165,12 @@
       // 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 &&
-          SymbolType == SymbolRef::ST_Function) {
-        StringRef Name;
-        if (error(si->getName(Name))) continue;
-        FunctionName = Name.str();
+          SymbolType == Type) {
+        StringRef SymbolName;
+        if (error(si->getName(SymbolName))) continue;
+        Name = SymbolName.str();
+        Addr = SymbolAddress;
+        Size = SymbolSize;
         return true;
       }
     }
@@ -263,7 +278,7 @@
          "\n";
 }
 
-static void symbolize(std::string ModuleName, std::string ModuleOffsetStr) {
+static void symbolizeCode(std::string ModuleName, std::string ModuleOffsetStr) {
   ModuleInfo *Info = getOrCreateModuleInfo(ModuleName);
   uint64_t Offset = 0;
   if (Info == 0 ||
@@ -286,17 +301,54 @@
   outs().flush();
 }
 
-static bool parseModuleNameAndOffset(std::string &ModuleName,
-                                     std::string &ModuleOffsetStr) {
-  static const int kMaxInputStringLength = 1024;
-  static const char kDelimiters[] = " \n";
+static void symbolizeData(std::string ModuleName, std::string ModuleOffsetStr) {
+  std::string Name = "??";
+  uint64_t Start = 0;
+  uint64_t Size = 0;
+  uint64_t Offset = 0;
+  ModuleInfo *Info = getOrCreateModuleInfo(ModuleName);
+  if (Info && !StringRef(ModuleOffsetStr).getAsInteger(0, Offset)) {
+    if (Info->symbolizeData(Offset, Name, Start, Size)) {
+      if (Demangle) {
+        int status = 0;
+        char *DemangledName = __cxa_demangle(Name.c_str(), 0, 0, &status);
+        if (status == 0) {
+          Name = DemangledName;
+          free(DemangledName);
+        }
+      }
+    }
+  }
+  outs() << Name << " " << Start << " " << Size << "\n\n";
+  outs().flush();
+}
+
+static bool parseCommand(bool &IsData,
+                         std::string &ModuleName,
+                         std::string &ModuleOffsetStr) {
+  const char *kDataCmd = "DATA ";
+  const char *kCodeCmd = "CODE ";
+  const int kMaxInputStringLength = 1024;
+  const char kDelimiters[] = " \n";
   char InputString[kMaxInputStringLength];
   if (!fgets(InputString, sizeof(InputString), stdin))
     return false;
+  IsData = false;
   ModuleName = "";
   ModuleOffsetStr = "";
+  char *pos = InputString;
+  if (strncmp(pos, kDataCmd, strlen(kDataCmd)) == 0) {
+    IsData = true;
+    pos += strlen(kDataCmd);
+  } else if (strncmp(pos, kCodeCmd, strlen(kCodeCmd)) == 0) {
+    IsData = false;
+    pos += strlen(kCodeCmd);
+  } else {
+    // If no cmd, assume it's CODE.
+    IsData = false;
+  }
   // FIXME: Handle case when filename is given in quotes.
-  if (char *FilePath = strtok(InputString, kDelimiters)) {
+  if (char *FilePath = strtok(pos, kDelimiters)) {
     ModuleName = FilePath;
     if (char *OffsetStr = strtok((char*)0, kDelimiters))
       ModuleOffsetStr = OffsetStr;
@@ -313,10 +365,14 @@
   cl::ParseCommandLineOptions(argc, argv, "llvm symbolizer for compiler-rt\n");
   ToolInvocationPath = argv[0];
 
+  bool IsData = false;
   std::string ModuleName;
   std::string ModuleOffsetStr;
-  while (parseModuleNameAndOffset(ModuleName, ModuleOffsetStr)) {
-    symbolize(ModuleName, ModuleOffsetStr);
+  while (parseCommand(IsData, ModuleName, ModuleOffsetStr)) {
+    if (IsData)
+      symbolizeData(ModuleName, ModuleOffsetStr);
+    else
+      symbolizeCode(ModuleName, ModuleOffsetStr);
   }
   return 0;
 }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D277.1.patch
Type: text/x-patch
Size: 5530 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130110/f2df8c09/attachment.bin>


More information about the llvm-commits mailing list