labath updated this revision to Diff 179819.
labath added a comment.
Add some "image lookup" commands to the test. The test now goes through lldb
instead of lldb-test, but I've kept the lldb-test changes, as I think they make
sense regardless. The tricky part about the new test is the need to specify the
"target symbols add" command via '-o', because I need lit to substitute the full
path to the symbol file.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D56173/new/
https://reviews.llvm.org/D56173
Files:
lit/SymbolFile/Breakpad/Inputs/symtab.lldbinit
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 ®ex, 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 § = *list.GetSectionAtIndex(m_next_section_idx++);
+ if (sect.GetName() != m_section_type)
+ continue;
+ DataExtractor data;
+ m_obj->ReadSectionData(§, 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 ®ex,
+ 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,51 @@
+# RUN: yaml2obj %s > %T/symtab.out
+# RUN: %lldb %T/symtab.out -o "target symbols add -s symtab.out %S/Inputs/symtab.syms" \
+# RUN: -s %S/Inputs/symtab.lldbinit | FileCheck %s
+
+# CHECK-LABEL: (lldb) image dump symtab symtab.out
+# CHECK: Symtab, file = {{.*}}symtab.out, 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
+
+# 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-LABEL: (lldb) image lookup -n f2 -v
+# CHECK: Address: symtab.out[0x00000000004000c0] (symtab.out.PT_LOAD[0]..text2 + 16)
+# CHECK: Symbol: id = {0x00000000}, range = [0x00000000004000c0-0x00000000004000d0), name="f2"
+
+
+--- !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
Index: lit/SymbolFile/Breakpad/Inputs/symtab.lldbinit
===================================================================
--- /dev/null
+++ lit/SymbolFile/Breakpad/Inputs/symtab.lldbinit
@@ -0,0 +1,4 @@
+image dump symtab symtab.out
+image lookup -a 0x4000b0 -v
+image lookup -n f2 -v
+exit
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits