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

This commit adds the glue code necessary to integrate the
SymbolFileBreakpad into the plugin system. Most of the methods are
stubbed out. The only method implemented method is AddSymbols, which
parses the PUBLIC "section" of the breakpad "object file", and fills out
the Module's symtab.

To enable testing this, I've made two additional changes:

- dump Symtab from the SymbolVendor class. The symtab was already being dumped 
as a part of the object file dump, but that happened before symbol vendor 
kicked in, so it did not reflect any symbols added there.
- add ability to explicitly specify the external symbol file in lldb-test (so 
that the object file could be linked with the breakpad symbol file). To make 
things simpler, I've changed lldb-test from consuming multiple inputs (and 
dumping their symbols) to having it just process a single file per invocation. 
This was not a problem since everyone was using it that way already.


https://reviews.llvm.org/D56173

Files:
  lit/SymbolFile/Breakpad/Inputs/symtab.syms
  lit/SymbolFile/Breakpad/lit.local.cfg
  lit/SymbolFile/Breakpad/symtab.yaml
  source/API/SystemInitializerFull.cpp
  source/Plugins/SymbolFile/Breakpad/CMakeLists.txt
  source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
  source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
  source/Plugins/SymbolFile/CMakeLists.txt
  source/Symbol/SymbolVendor.cpp
  tools/lldb-test/SystemInitializerTest.cpp
  tools/lldb-test/lldb-test.cpp

Index: tools/lldb-test/lldb-test.cpp
===================================================================
--- tools/lldb-test/lldb-test.cpp
+++ tools/lldb-test/lldb-test.cpp
@@ -100,10 +100,14 @@
 } // namespace object
 
 namespace symbols {
-static cl::list<std::string> InputFilenames(cl::Positional,
-                                            cl::desc("<input files>"),
-                                            cl::OneOrMore,
-                                            cl::sub(SymbolsSubcommand));
+static cl::opt<std::string> InputFile(cl::Positional, cl::desc("<input file>"),
+                                      cl::Required, cl::sub(SymbolsSubcommand));
+
+static cl::opt<std::string>
+    SymbolPath("symbol-file",
+               cl::desc("The file from which to fetch symbol information."),
+               cl::value_desc("file"), cl::sub(SymbolsSubcommand));
+
 enum class FindType {
   None,
   Function,
@@ -694,28 +698,24 @@
   }
   auto Action = *ActionOr;
 
-  int HadErrors = 0;
-  for (const auto &File : InputFilenames) {
-    outs() << "Module: " << File << "\n";
-    ModuleSpec Spec{FileSpec(File)};
-    Spec.GetSymbolFileSpec().SetFile(File, FileSpec::Style::native);
-
-    auto ModulePtr = std::make_shared<lldb_private::Module>(Spec);
-    SymbolVendor *Vendor = ModulePtr->GetSymbolVendor();
-    if (!Vendor) {
-      WithColor::error() << "Module has no symbol vendor.\n";
-      HadErrors = 1;
-      continue;
-    }
+  outs() << "Module: " << InputFile << "\n";
+  ModuleSpec Spec{FileSpec(InputFile)};
+  StringRef Symbols = SymbolPath.empty() ? InputFile : SymbolPath;
+  Spec.GetSymbolFileSpec().SetFile(Symbols, FileSpec::Style::native);
 
-    if (Error E = Action(*ModulePtr)) {
-      WithColor::error() << toString(std::move(E)) << "\n";
-      HadErrors = 1;
-    }
+  auto ModulePtr = std::make_shared<lldb_private::Module>(Spec);
+  SymbolVendor *Vendor = ModulePtr->GetSymbolVendor();
+  if (!Vendor) {
+    WithColor::error() << "Module has no symbol vendor.\n";
+    return 1;
+  }
 
-    outs().flush();
+  if (Error E = Action(*ModulePtr)) {
+    WithColor::error() << toString(std::move(E)) << "\n";
+    return 1;
   }
-  return HadErrors;
+
+  return 0;
 }
 
 static void dumpSectionList(LinePrinter &Printer, const SectionList &List, bool is_subsection) {
Index: tools/lldb-test/SystemInitializerTest.cpp
===================================================================
--- tools/lldb-test/SystemInitializerTest.cpp
+++ tools/lldb-test/SystemInitializerTest.cpp
@@ -70,6 +70,7 @@
 #include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
 #include "Plugins/Process/minidump/ProcessMinidump.h"
 #include "Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h"
+#include "Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h"
 #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
 #include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h"
 #include "Plugins/SymbolFile/PDB/SymbolFilePDB.h"
@@ -176,6 +177,7 @@
   MainThreadCheckerRuntime::Initialize();
 
   SymbolVendorELF::Initialize();
+  breakpad::SymbolFileBreakpad::Initialize();
   SymbolFileDWARF::Initialize();
   SymbolFilePDB::Initialize();
   SymbolFileSymtab::Initialize();
@@ -274,6 +276,7 @@
   UndefinedBehaviorSanitizerRuntime::Terminate();
   MainThreadCheckerRuntime::Terminate();
   SymbolVendorELF::Terminate();
+  breakpad::SymbolFileBreakpad::Terminate();
   SymbolFileDWARF::Terminate();
   SymbolFilePDB::Terminate();
   SymbolFileSymtab::Terminate();
Index: source/Symbol/SymbolVendor.cpp
===================================================================
--- source/Symbol/SymbolVendor.cpp
+++ source/Symbol/SymbolVendor.cpp
@@ -384,6 +384,7 @@
     s->Indent();
     s->PutCString("SymbolVendor");
     if (m_sym_file_ap.get()) {
+      *s << " " << m_sym_file_ap->GetPluginName();
       ObjectFile *objfile = m_sym_file_ap->GetObjectFile();
       if (objfile) {
         const FileSpec &objfile_file_spec = objfile->GetFileSpec();
@@ -408,6 +409,9 @@
         (*cu_pos)->Dump(s, show_context);
     }
 
+    if (Symtab *symtab = GetSymtab())
+      symtab->Dump(s, nullptr, eSortOrderNone);
+
     s->IndentLess();
   }
 }
Index: source/Plugins/SymbolFile/CMakeLists.txt
===================================================================
--- source/Plugins/SymbolFile/CMakeLists.txt
+++ source/Plugins/SymbolFile/CMakeLists.txt
@@ -1,3 +1,4 @@
+add_subdirectory(Breakpad)
 add_subdirectory(DWARF)
 add_subdirectory(Symtab)
 add_subdirectory(NativePDB)
Index: source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
===================================================================
--- /dev/null
+++ source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
@@ -0,0 +1,149 @@
+//===-- SymbolFileBreakpad.h ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H
+#define LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H
+
+#include "lldb/Symbol/SymbolFile.h"
+
+namespace lldb_private {
+
+namespace breakpad {
+
+class SymbolFileBreakpad : public SymbolFile {
+public:
+  //------------------------------------------------------------------
+  // Static Functions
+  //------------------------------------------------------------------
+  static void Initialize();
+  static void Terminate();
+  static void DebuggerInitialize(Debugger &debugger) {}
+  static ConstString GetPluginNameStatic();
+
+  static const char *GetPluginDescriptionStatic() {
+    return "Breakpad debug symbol file reader.";
+  }
+
+  static SymbolFile *CreateInstance(ObjectFile *obj_file) {
+    return new SymbolFileBreakpad(obj_file);
+  }
+
+  //------------------------------------------------------------------
+  // Constructors and Destructors
+  //------------------------------------------------------------------
+  SymbolFileBreakpad(ObjectFile *object_file) : SymbolFile(object_file) {}
+
+  ~SymbolFileBreakpad() override {}
+
+  uint32_t CalculateAbilities() override;
+
+  void InitializeObject() override {}
+
+  //------------------------------------------------------------------
+  // Compile Unit function calls
+  //------------------------------------------------------------------
+
+  uint32_t GetNumCompileUnits() override;
+
+  lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
+
+  lldb::LanguageType
+  ParseCompileUnitLanguage(const SymbolContext &sc) override {
+    return lldb::eLanguageTypeUnknown;
+  }
+
+  size_t ParseCompileUnitFunctions(const SymbolContext &sc) override;
+
+  bool ParseCompileUnitLineTable(const SymbolContext &sc) override;
+
+  bool ParseCompileUnitDebugMacros(const SymbolContext &sc) override {
+    return false;
+  }
+
+  bool ParseCompileUnitSupportFiles(const SymbolContext &sc,
+                                    FileSpecList &support_files) override {
+    return false;
+  }
+
+  bool
+  ParseImportedModules(const SymbolContext &sc,
+                       std::vector<ConstString> &imported_modules) override {
+    return false;
+  }
+
+  size_t ParseFunctionBlocks(const SymbolContext &sc) override { return 0; }
+
+  uint32_t FindGlobalVariables(const ConstString &name,
+                               const CompilerDeclContext *parent_decl_ctx,
+                               uint32_t max_matches,
+                               VariableList &variables) override {
+    return 0;
+  }
+
+  size_t ParseTypes(const SymbolContext &sc) override { return 0; }
+  size_t ParseVariablesForContext(const SymbolContext &sc) override {
+    return 0;
+  }
+  Type *ResolveTypeUID(lldb::user_id_t type_uid) override { return nullptr; }
+  llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID(
+      lldb::user_id_t type_uid,
+      const lldb_private::ExecutionContext *exe_ctx) override {
+    return llvm::None;
+  }
+
+  bool CompleteType(CompilerType &compiler_type) override { return false; }
+  uint32_t ResolveSymbolContext(const Address &so_addr,
+                                lldb::SymbolContextItem resolve_scope,
+                                SymbolContext &sc) override;
+
+  size_t GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
+                  TypeList &type_list) override {
+    return 0;
+  }
+
+  uint32_t FindFunctions(const ConstString &name,
+                         const CompilerDeclContext *parent_decl_ctx,
+                         lldb::FunctionNameType name_type_mask,
+                         bool include_inlines, bool append,
+                         SymbolContextList &sc_list) override;
+
+  uint32_t FindFunctions(const RegularExpression &regex, bool include_inlines,
+                         bool append, SymbolContextList &sc_list) override;
+
+  uint32_t FindTypes(const SymbolContext &sc, const ConstString &name,
+                     const CompilerDeclContext *parent_decl_ctx, bool append,
+                     uint32_t max_matches,
+                     llvm::DenseSet<SymbolFile *> &searched_symbol_files,
+                     TypeMap &types) override;
+
+  size_t FindTypes(const std::vector<CompilerContext> &context, bool append,
+                   TypeMap &types) override;
+
+  TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language) override {
+    return nullptr;
+  }
+
+  CompilerDeclContext
+  FindNamespace(const SymbolContext &sc, const ConstString &name,
+                const CompilerDeclContext *parent_decl_ctx) override {
+    return CompilerDeclContext();
+  }
+
+  void AddSymbols(Symtab &symtab) override;
+
+  ConstString GetPluginName() override { return GetPluginNameStatic(); }
+  uint32_t GetPluginVersion() override { return 1; }
+
+private:
+};
+
+} // namespace breakpad
+} // namespace lldb_private
+
+#endif
Index: source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
===================================================================
--- /dev/null
+++ source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
@@ -0,0 +1,221 @@
+//===-- SymbolFileBreakpad.cpp ----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h"
+#include "Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/TypeMap.h"
+#include "lldb/Utility/Log.h"
+#include "llvm/ADT/StringExtras.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::breakpad;
+
+namespace {
+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) {
+    ++*this;
+  }
+
+  // end iterator
+  explicit LineIterator(ObjectFile &obj)
+      : m_obj(&obj),
+        m_next_section_idx(m_obj->GetSectionList()->GetNumSections(0)) {}
+
+  friend bool operator!=(const LineIterator &lhs, const LineIterator &rhs) {
+    assert(lhs.m_obj == rhs.m_obj);
+    if (lhs.m_next_section_idx != rhs.m_next_section_idx)
+      return true;
+    if (lhs.m_next_text.data() != rhs.m_next_text.data())
+      return true;
+    assert(lhs.m_current_text == rhs.m_current_text);
+    assert(rhs.m_next_text == rhs.m_next_text);
+    return false;
+  }
+
+  const LineIterator &operator++();
+  llvm::StringRef operator*() const { return m_current_text; }
+
+private:
+  ObjectFile *m_obj;
+  ConstString m_section_type;
+  uint32_t m_next_section_idx;
+  llvm::StringRef m_current_text;
+  llvm::StringRef m_next_text;
+};
+} // namespace
+
+const LineIterator &LineIterator::operator++() {
+  const SectionList &list = *m_obj->GetSectionList();
+  size_t num_sections = list.GetNumSections(0);
+  while (m_next_text.empty() && m_next_section_idx < num_sections) {
+    Section &sect = *list.GetSectionAtIndex(m_next_section_idx++);
+    if (sect.GetName() != m_section_type)
+      continue;
+    DataExtractor data;
+    m_obj->ReadSectionData(&sect, data);
+    m_next_text =
+        llvm::StringRef(reinterpret_cast<const char *>(data.GetDataStart()),
+                        data.GetByteSize());
+  }
+  std::tie(m_current_text, m_next_text) = m_next_text.split('\n');
+  return *this;
+}
+
+static llvm::iterator_range<LineIterator> lines(ObjectFile &obj,
+                                                ConstString section_type) {
+  return llvm::make_range(LineIterator(obj, section_type), LineIterator(obj));
+}
+
+void SymbolFileBreakpad::Initialize() {
+  PluginManager::RegisterPlugin(GetPluginNameStatic(),
+                                GetPluginDescriptionStatic(), CreateInstance,
+                                DebuggerInitialize);
+}
+
+void SymbolFileBreakpad::Terminate() {
+  PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+ConstString SymbolFileBreakpad::GetPluginNameStatic() {
+  static ConstString g_name("breakpad");
+  return g_name;
+}
+
+uint32_t SymbolFileBreakpad::CalculateAbilities() {
+  if (!m_obj_file)
+    return 0;
+  if (m_obj_file->GetPluginName() != ObjectFileBreakpad::GetPluginNameStatic())
+    return 0;
+
+  return CompileUnits | Functions;
+}
+
+uint32_t SymbolFileBreakpad::GetNumCompileUnits() {
+  // TODO
+  return 0;
+}
+
+CompUnitSP SymbolFileBreakpad::ParseCompileUnitAtIndex(uint32_t index) {
+  // TODO
+  return nullptr;
+}
+
+size_t SymbolFileBreakpad::ParseCompileUnitFunctions(const SymbolContext &sc) {
+  // TODO
+  return 0;
+}
+
+bool SymbolFileBreakpad::ParseCompileUnitLineTable(const SymbolContext &sc) {
+  // TODO
+  return 0;
+}
+
+uint32_t
+SymbolFileBreakpad::ResolveSymbolContext(const Address &so_addr,
+                                         SymbolContextItem resolve_scope,
+                                         SymbolContext &sc) {
+  // TODO
+  return 0;
+}
+
+uint32_t SymbolFileBreakpad::FindFunctions(
+    const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+    FunctionNameType name_type_mask, bool include_inlines, bool append,
+    SymbolContextList &sc_list) {
+  // TODO
+  if (!append)
+    sc_list.Clear();
+  return sc_list.GetSize();
+}
+
+uint32_t SymbolFileBreakpad::FindFunctions(const RegularExpression &regex,
+                                           bool include_inlines, bool append,
+                                           SymbolContextList &sc_list) {
+  // TODO
+  if (!append)
+    sc_list.Clear();
+  return sc_list.GetSize();
+}
+
+uint32_t SymbolFileBreakpad::FindTypes(
+    const SymbolContext &sc, const ConstString &name,
+    const CompilerDeclContext *parent_decl_ctx, bool append,
+    uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files,
+    TypeMap &types) {
+  if (!append)
+    types.Clear();
+  return types.GetSize();
+}
+
+size_t
+SymbolFileBreakpad::FindTypes(const std::vector<CompilerContext> &context,
+                              bool append, TypeMap &types) {
+  if (!append)
+    types.Clear();
+  return types.GetSize();
+}
+
+void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
+  Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
+  Module &module = *m_obj_file->GetModule();
+  addr_t base = module.GetObjectFile()->GetBaseAddress().GetFileAddress();
+  if (base == LLDB_INVALID_ADDRESS)
+    return;
+
+  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::StringRef token;
+    std::tie(token, line) = getToken(line);
+    if (token == "m")
+      std::tie(token, line) = getToken(line);
+
+    addr_t address;
+    if (!to_integer(token, address, 16))
+      continue;
+    address += base;
+
+    // skip param_size
+    line = getToken(line).second;
+
+    llvm::StringRef name = line.trim();
+
+    SectionSP section_sp = list.FindSectionContainingFileAddress(address);
+    if (!section_sp) {
+      LLDB_LOG(log,
+               "Ignoring symbol {0}, whose address ({1}) is outside of the "
+               "object file. Mismatched symbol file?",
+               name, address);
+      continue;
+    }
+
+    symtab.AddSymbol(Symbol(
+        /*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));
+  }
+
+  // TODO: Process FUNC records as well.
+
+  symtab.CalculateSymbolSizes();
+}
Index: source/Plugins/SymbolFile/Breakpad/CMakeLists.txt
===================================================================
--- /dev/null
+++ source/Plugins/SymbolFile/Breakpad/CMakeLists.txt
@@ -0,0 +1,12 @@
+add_lldb_library(lldbPluginSymbolFileBreakpad PLUGIN
+  SymbolFileBreakpad.cpp
+
+  LINK_LIBS
+    lldbCore
+    lldbHost
+    lldbSymbol
+    lldbUtility
+    lldbPluginObjectFileBreakpad
+  LINK_COMPONENTS
+    Support
+  )
Index: source/API/SystemInitializerFull.cpp
===================================================================
--- source/API/SystemInitializerFull.cpp
+++ source/API/SystemInitializerFull.cpp
@@ -83,6 +83,7 @@
 #include "Plugins/Process/mach-core/ProcessMachCore.h"
 #include "Plugins/Process/minidump/ProcessMinidump.h"
 #include "Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h"
+#include "Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h"
 #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
 #include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h"
 #include "Plugins/SymbolFile/PDB/SymbolFilePDB.h"
@@ -343,6 +344,7 @@
   MainThreadCheckerRuntime::Initialize();
 
   SymbolVendorELF::Initialize();
+  breakpad::SymbolFileBreakpad::Initialize();
   SymbolFileDWARF::Initialize();
   SymbolFilePDB::Initialize();
   SymbolFileSymtab::Initialize();
@@ -471,6 +473,7 @@
   UndefinedBehaviorSanitizerRuntime::Terminate();
   MainThreadCheckerRuntime::Terminate();
   SymbolVendorELF::Terminate();
+  breakpad::SymbolFileBreakpad::Terminate();
   SymbolFileDWARF::Terminate();
   SymbolFilePDB::Terminate();
   SymbolFileSymtab::Terminate();
Index: lit/SymbolFile/Breakpad/symtab.yaml
===================================================================
--- /dev/null
+++ lit/SymbolFile/Breakpad/symtab.yaml
@@ -0,0 +1,42 @@
+# RUN: yaml2obj %s > %t
+# RUN: lldb-test symbols %t -symbol-file %S/Inputs/symtab.syms | FileCheck %s
+
+# CHECK: SymbolVendor breakpad ({{.*}}symtab.syms)
+# CHECK: num_symbols = 3:
+# 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
+
+
+--- !ELF
+FileHeader:      
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+  Entry:           0x00000000004000D0
+Sections:        
+  - Name:            .text1
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    Address:         0x0000000000400000
+    AddressAlign:    0x0000000000001000
+    Size:            0xb0
+  - Name:            .text2
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    Address:         0x00000000004000B0
+    AddressAlign:    0x0000000000000010
+    Size:            0x42
+Symbols:         
+DynamicSymbols:  
+ProgramHeaders:
+  - Type: PT_LOAD
+    Flags: [ PF_X, PF_R ]
+    VAddr: 0x400000
+    Align: 0x1000
+    Sections:
+      - Section: .text1
+      - Section: .text2
+...
Index: lit/SymbolFile/Breakpad/lit.local.cfg
===================================================================
--- /dev/null
+++ lit/SymbolFile/Breakpad/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes.add('.yaml')
Index: lit/SymbolFile/Breakpad/Inputs/symtab.syms
===================================================================
--- /dev/null
+++ lit/SymbolFile/Breakpad/Inputs/symtab.syms
@@ -0,0 +1,7 @@
+MODULE Linux x86_64 761550E08086333960A9074A9CE2895C0 a.out
+INFO CODE_ID E05015768680393360A9074A9CE2895C
+FILE 0 /tmp/a.c
+PUBLIC b0 0 f1
+PUBLIC c0 0 f2
+PUBLIC d0 0 _start
+PUBLIC ff 0 _out_of_range_ignored
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to