labath created this revision.
labath added reviewers: zturner, lemo, clayborg, markmentovai.
Herald added a subscriber: aprantl.

This patch extends SymbolFileBreakpad::AddSymbols to include the symbols
from the FUNC records too. These symbols come from the debug info and
have a size associated with them, so they are given preference in case
there is a PUBLIC record for the same address.

To achieve this, I first pre-process the symbols into a temporary
DenseMap, and then insert the uniqued symbols into the module's symtab.


https://reviews.llvm.org/D56590

Files:
  lit/SymbolFile/Breakpad/Inputs/symtab.syms
  lit/SymbolFile/Breakpad/symtab.test
  source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
  source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
  source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp

Index: source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
===================================================================
--- source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
+++ source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
@@ -26,8 +26,9 @@
 class LineIterator {
 public:
   // begin iterator for sections of given type
-  LineIterator(ObjectFile &obj, ConstString section_type)
-      : m_obj(&obj), m_section_type(section_type), m_next_section_idx(0) {
+  LineIterator(ObjectFile &obj, Token section_type)
+      : m_obj(&obj), m_section_type(toString(section_type)),
+        m_next_section_idx(0) {
     ++*this;
   }
 
@@ -77,7 +78,7 @@
 }
 
 static llvm::iterator_range<LineIterator> lines(ObjectFile &obj,
-                                                ConstString section_type) {
+                                                Token section_type) {
   return llvm::make_range(LineIterator(obj, section_type), LineIterator(obj));
 }
 
@@ -181,10 +182,11 @@
   }
 
   const SectionList &list = *module.GetSectionList();
-  for (llvm::StringRef line : lines(*m_obj_file, ConstString("PUBLIC"))) {
-    // PUBLIC [m] address param_size name
-    // skip PUBLIC keyword
-    line = getToken(line).second;
+  llvm::DenseMap<addr_t, Symbol> symbols;
+
+  auto parse = [&](llvm::StringRef line, bool is_func) {
+    // [m] address {size} param_size name
+    // {size} is present in FUNC records.
     llvm::StringRef token;
     std::tie(token, line) = getToken(line);
     if (token == "m")
@@ -192,9 +194,18 @@
 
     addr_t address;
     if (!to_integer(token, address, 16))
-      continue;
+      return;
     address += base;
 
+    addr_t size = 0;
+    bool size_is_valid = false;
+    if (is_func) {
+      std::tie(token, line) = getToken(line);
+      if (!to_integer(token, size, 16))
+        return;
+      size_is_valid = true;
+    }
+
     // skip param_size
     line = getToken(line).second;
 
@@ -206,19 +217,36 @@
                "Ignoring symbol {0}, whose address ({1}) is outside of the "
                "object file. Mismatched symbol file?",
                name, address);
-      continue;
+      return;
     }
 
-    symtab.AddSymbol(Symbol(
-        /*symID*/ 0, Mangled(name, /*is_mangled*/ false), eSymbolTypeCode,
+    symbols.try_emplace(
+        address, /*symID*/ 0, Mangled(name, /*is_mangled*/ false),
+        eSymbolTypeCode,
         /*is_global*/ true, /*is_debug*/ false, /*is_trampoline*/ false,
         /*is_artificial*/ false,
-        AddressRange(section_sp, address - section_sp->GetFileAddress(), 0),
-        /*size_is_valid*/ 0, /*contains_linker_annotations*/ false,
-        /*flags*/ 0));
+        AddressRange(section_sp, address - section_sp->GetFileAddress(), size),
+        size_is_valid, /*contains_linker_annotations*/ false,
+        /*flags*/ 0);
+  };
+  for (llvm::StringRef line: lines(*m_obj_file, Token::Func)) {
+    // Here we can get either FUNC records (starting with FUNC), or line records
+    // (starting with a hex number).
+    llvm::StringRef token_str;
+    std::tie(token_str, line) = getToken(line);
+    if (toToken(token_str) != Token::Func)
+      continue; // Skip line records.
+
+    parse(line, true);
   }
 
-  // TODO: Process FUNC records as well.
+  for (llvm::StringRef line : lines(*m_obj_file, Token::Public)) {
+    // PUBLIC [m] address param_size name
+    // skip PUBLIC keyword
+    parse(getToken(line).second, false);
+  }
 
+  for (auto &KV : symbols)
+    symtab.AddSymbol(std::move(KV.second));
   symtab.CalculateSymbolSizes();
 }
Index: source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
===================================================================
--- source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
+++ source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
@@ -17,6 +17,11 @@
 namespace lldb_private {
 namespace breakpad {
 
+enum class Token { Unknown, Module, Info, File, Func, Public, Stack };
+
+Token toToken(llvm::StringRef str);
+llvm::StringRef toString(Token t);
+
 class ObjectFileBreakpad : public ObjectFile {
 public:
   //------------------------------------------------------------------
Index: source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
===================================================================
--- source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
+++ source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
@@ -24,11 +24,9 @@
   UUID uuid;
   static llvm::Optional<Header> parse(llvm::StringRef text);
 };
-
-enum class Token { Unknown, Module, Info, File, Func, Public, Stack };
 } // namespace
 
-static Token toToken(llvm::StringRef str) {
+Token breakpad::toToken(llvm::StringRef str) {
   return llvm::StringSwitch<Token>(str)
       .Case("MODULE", Token::Module)
       .Case("INFO", Token::Info)
@@ -39,7 +37,7 @@
       .Default(Token::Unknown);
 }
 
-static llvm::StringRef toString(Token t) {
+llvm::StringRef breakpad::toString(Token t) {
   switch (t) {
   case Token::Unknown:
     return "";
Index: lit/SymbolFile/Breakpad/symtab.test
===================================================================
--- lit/SymbolFile/Breakpad/symtab.test
+++ lit/SymbolFile/Breakpad/symtab.test
@@ -3,15 +3,16 @@
 # RUN:   -s %s | FileCheck %s
 
 # CHECK-LABEL: (lldb) image dump symtab symtab.out
-# CHECK: Symtab, file = {{.*}}symtab.out, num_symbols = 3:
+# CHECK: Symtab, file = {{.*}}symtab.out, num_symbols = 4:
 # CHECK: Index   UserID DSX Type            File Address/Value Load Address       Size               Flags      Name
-# CHECK: [    0]      0   X Code            0x00000000004000b0                    0x0000000000000010 0x00000000 f1
-# CHECK: [    1]      0   X Code            0x00000000004000c0                    0x0000000000000010 0x00000000 f2
-# CHECK: [    2]      0   X Code            0x00000000004000d0                    0x0000000000000022 0x00000000 _start
+# CHECK: [    0]      0   X Code            0x00000000004000c0                    0x0000000000000010 0x00000000 f2
+# CHECK: [    1]      0   X Code            0x00000000004000d0                    0x0000000000000022 0x00000000 _start
+# CHECK: [    2]      0   X Code            0x00000000004000a0                    0x000000000000000d 0x00000000 func_only
+# CHECK: [    3]      0   X Code            0x00000000004000b0                    0x000000000000000c 0x00000000 f1_func
 
 # CHECK-LABEL: (lldb) image lookup -a 0x4000b0 -v
 # CHECK: Address: symtab.out[0x00000000004000b0] (symtab.out.PT_LOAD[0]..text2 + 0)
-# CHECK: Symbol: id = {0x00000000}, range = [0x00000000004000b0-0x00000000004000c0), name="f1"
+# CHECK: Symbol: id = {0x00000000}, range = [0x00000000004000b0-0x00000000004000bc), name="f1_func"
 
 # CHECK-LABEL: (lldb) image lookup -n f2 -v
 # CHECK: Address: symtab.out[0x00000000004000c0] (symtab.out.PT_LOAD[0]..text2 + 16)
Index: lit/SymbolFile/Breakpad/Inputs/symtab.syms
===================================================================
--- lit/SymbolFile/Breakpad/Inputs/symtab.syms
+++ lit/SymbolFile/Breakpad/Inputs/symtab.syms
@@ -5,3 +5,5 @@
 PUBLIC m c0 0 f2
 PUBLIC d0 0 _start
 PUBLIC ff 0 _out_of_range_ignored
+FUNC b0 c 0 f1_func
+FUNC m a0 d 0 func_only
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to