2016-11-26 13:23:44 +08:00
|
|
|
//===-- SymbolVendor.cpp ----------------------------------------*- C++ -*-===//
|
2010-06-09 00:52:24 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2010-06-09 00:52:24 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "lldb/Symbol/SymbolVendor.h"
|
|
|
|
|
|
|
|
#include "lldb/Core/Module.h"
|
|
|
|
#include "lldb/Core/PluginManager.h"
|
<rdar://problem/11757916>
Make breakpoint setting by file and line much more efficient by only looking for inlined breakpoint locations if we are setting a breakpoint in anything but a source implementation file. Implementing this complex for a many reasons. Turns out that parsing compile units lazily had some issues with respect to how we need to do things with DWARF in .o files. So the fixes in the checkin for this makes these changes:
- Add a new setting called "target.inline-breakpoint-strategy" which can be set to "never", "always", or "headers". "never" will never try and set any inlined breakpoints (fastest). "always" always looks for inlined breakpoint locations (slowest, but most accurate). "headers", which is the default setting, will only look for inlined breakpoint locations if the breakpoint is set in what are consudered to be header files, which is realy defined as "not in an implementation source file".
- modify the breakpoint setting by file and line to check the current "target.inline-breakpoint-strategy" setting and act accordingly
- Modify compile units to be able to get their language and other info lazily. This allows us to create compile units from the debug map and not have to fill all of the details in, and then lazily discover this information as we go on debuggging. This is needed to avoid parsing all .o files when setting breakpoints in implementation only files (no inlines). Otherwise we would need to parse the .o file, the object file (mach-o in our case) and the symbol file (DWARF in the object file) just to see what the compile unit was.
- modify the "SymbolFileDWARFDebugMap" to subclass lldb_private::Module so that the virtual "GetObjectFile()" and "GetSymbolVendor()" functions can be intercepted when the .o file contenst are later lazilly needed. Prior to this fix, when we first instantiated the "SymbolFileDWARFDebugMap" class, we would also make modules, object files and symbol files for every .o file in the debug map because we needed to fix up the sections in the .o files with information that is in the executable debug map. Now we lazily do this in the DebugMapModule::GetObjectFile()
Cleaned up header includes a bit as well.
llvm-svn: 162860
2012-08-30 05:13:06 +08:00
|
|
|
#include "lldb/Symbol/CompileUnit.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
#include "lldb/Symbol/ObjectFile.h"
|
|
|
|
#include "lldb/Symbol/SymbolFile.h"
|
2017-02-03 05:39:50 +08:00
|
|
|
#include "lldb/Utility/Stream.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
using namespace lldb;
|
|
|
|
using namespace lldb_private;
|
|
|
|
|
|
|
|
// FindPlugin
|
|
|
|
//
|
2018-05-01 00:49:04 +08:00
|
|
|
// Platforms can register a callback to use when creating symbol vendors to
|
|
|
|
// allow for complex debug information file setups, and to also allow for
|
|
|
|
// finding separate debug information files.
|
2016-09-07 04:57:50 +08:00
|
|
|
SymbolVendor *SymbolVendor::FindPlugin(const lldb::ModuleSP &module_sp,
|
|
|
|
lldb_private::Stream *feedback_strm) {
|
2019-02-13 14:25:41 +08:00
|
|
|
std::unique_ptr<SymbolVendor> instance_up;
|
2016-09-07 04:57:50 +08:00
|
|
|
SymbolVendorCreateInstance create_callback;
|
|
|
|
|
|
|
|
for (size_t idx = 0;
|
|
|
|
(create_callback = PluginManager::GetSymbolVendorCreateCallbackAtIndex(
|
|
|
|
idx)) != nullptr;
|
|
|
|
++idx) {
|
2019-02-13 14:25:41 +08:00
|
|
|
instance_up.reset(create_callback(module_sp, feedback_strm));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2019-02-13 14:25:41 +08:00
|
|
|
if (instance_up) {
|
|
|
|
return instance_up.release();
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
}
|
2018-05-01 00:49:04 +08:00
|
|
|
// The default implementation just tries to create debug information using
|
|
|
|
// the file representation for the module.
|
2019-01-17 23:07:35 +08:00
|
|
|
ObjectFileSP sym_objfile_sp;
|
|
|
|
FileSpec sym_spec = module_sp->GetSymbolFileFileSpec();
|
|
|
|
if (sym_spec && sym_spec != module_sp->GetObjectFile()->GetFileSpec()) {
|
|
|
|
DataBufferSP data_sp;
|
|
|
|
offset_t data_offset = 0;
|
|
|
|
sym_objfile_sp = ObjectFile::FindPlugin(
|
|
|
|
module_sp, &sym_spec, 0, FileSystem::Instance().GetByteSize(sym_spec),
|
|
|
|
data_sp, data_offset);
|
2019-01-17 00:09:13 +08:00
|
|
|
}
|
2019-01-17 23:07:35 +08:00
|
|
|
if (!sym_objfile_sp)
|
|
|
|
sym_objfile_sp = module_sp->GetObjectFile()->shared_from_this();
|
2019-02-13 14:25:41 +08:00
|
|
|
instance_up.reset(new SymbolVendor(module_sp));
|
|
|
|
instance_up->AddSymbolFileRepresentation(sym_objfile_sp);
|
|
|
|
return instance_up.release();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// SymbolVendor constructor
|
2016-09-07 04:57:50 +08:00
|
|
|
SymbolVendor::SymbolVendor(const lldb::ModuleSP &module_sp)
|
2019-02-13 14:25:41 +08:00
|
|
|
: ModuleChild(module_sp), m_type_list(), m_compile_units(), m_sym_file_up(),
|
|
|
|
m_symtab() {}
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
// Destructor
|
2016-09-07 04:57:50 +08:00
|
|
|
SymbolVendor::~SymbolVendor() {}
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2015-07-22 08:16:02 +08:00
|
|
|
// Add a representation given an object file.
|
2016-09-07 04:57:50 +08:00
|
|
|
void SymbolVendor::AddSymbolFileRepresentation(const ObjectFileSP &objfile_sp) {
|
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
|
|
|
if (objfile_sp) {
|
|
|
|
m_objfile_sp = objfile_sp;
|
2019-02-13 14:25:41 +08:00
|
|
|
m_sym_file_up.reset(SymbolFile::FindPlugin(objfile_sp.get()));
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SymbolVendor::SetCompileUnitAtIndex(size_t idx, const CompUnitSP &cu_sp) {
|
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
|
|
|
const size_t num_compile_units = GetNumCompileUnits();
|
|
|
|
if (idx < num_compile_units) {
|
2018-05-01 00:49:04 +08:00
|
|
|
// Fire off an assertion if this compile unit already exists for now. The
|
|
|
|
// partial parsing should take care of only setting the compile unit
|
|
|
|
// once, so if this assertion fails, we need to make sure that we don't
|
|
|
|
// have a race condition, or have a second parse of the same compile
|
|
|
|
// unit.
|
2016-09-07 04:57:50 +08:00
|
|
|
assert(m_compile_units[idx].get() == nullptr);
|
|
|
|
m_compile_units[idx] = cu_sp;
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
// This should NOT happen, and if it does, we want to crash and know
|
|
|
|
// about it
|
|
|
|
assert(idx < num_compile_units);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t SymbolVendor::GetNumCompileUnits() {
|
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
|
|
|
if (m_compile_units.empty()) {
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up) {
|
2018-05-01 00:49:04 +08:00
|
|
|
// Resize our array of compile unit shared pointers -- which will each
|
|
|
|
// remain NULL until someone asks for the actual compile unit
|
|
|
|
// information. When this happens, the symbol file will be asked to
|
|
|
|
// parse this compile unit information.
|
2019-02-13 14:25:41 +08:00
|
|
|
m_compile_units.resize(m_sym_file_up->GetNumCompileUnits());
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return m_compile_units.size();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2019-01-12 02:03:20 +08:00
|
|
|
lldb::LanguageType SymbolVendor::ParseLanguage(CompileUnit &comp_unit) {
|
2016-09-07 04:57:50 +08:00
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
return m_sym_file_up->ParseLanguage(comp_unit);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
return eLanguageTypeUnknown;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2019-01-12 02:03:20 +08:00
|
|
|
size_t SymbolVendor::ParseFunctions(CompileUnit &comp_unit) {
|
2016-09-07 04:57:50 +08:00
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
return m_sym_file_up->ParseFunctions(comp_unit);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
return 0;
|
<rdar://problem/11757916>
Make breakpoint setting by file and line much more efficient by only looking for inlined breakpoint locations if we are setting a breakpoint in anything but a source implementation file. Implementing this complex for a many reasons. Turns out that parsing compile units lazily had some issues with respect to how we need to do things with DWARF in .o files. So the fixes in the checkin for this makes these changes:
- Add a new setting called "target.inline-breakpoint-strategy" which can be set to "never", "always", or "headers". "never" will never try and set any inlined breakpoints (fastest). "always" always looks for inlined breakpoint locations (slowest, but most accurate). "headers", which is the default setting, will only look for inlined breakpoint locations if the breakpoint is set in what are consudered to be header files, which is realy defined as "not in an implementation source file".
- modify the breakpoint setting by file and line to check the current "target.inline-breakpoint-strategy" setting and act accordingly
- Modify compile units to be able to get their language and other info lazily. This allows us to create compile units from the debug map and not have to fill all of the details in, and then lazily discover this information as we go on debuggging. This is needed to avoid parsing all .o files when setting breakpoints in implementation only files (no inlines). Otherwise we would need to parse the .o file, the object file (mach-o in our case) and the symbol file (DWARF in the object file) just to see what the compile unit was.
- modify the "SymbolFileDWARFDebugMap" to subclass lldb_private::Module so that the virtual "GetObjectFile()" and "GetSymbolVendor()" functions can be intercepted when the .o file contenst are later lazilly needed. Prior to this fix, when we first instantiated the "SymbolFileDWARFDebugMap" class, we would also make modules, object files and symbol files for every .o file in the debug map because we needed to fix up the sections in the .o files with information that is in the executable debug map. Now we lazily do this in the DebugMapModule::GetObjectFile()
Cleaned up header includes a bit as well.
llvm-svn: 162860
2012-08-30 05:13:06 +08:00
|
|
|
}
|
|
|
|
|
2019-01-12 02:03:20 +08:00
|
|
|
bool SymbolVendor::ParseLineTable(CompileUnit &comp_unit) {
|
2016-09-07 04:57:50 +08:00
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
return m_sym_file_up->ParseLineTable(comp_unit);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
<rdar://problem/11757916>
Make breakpoint setting by file and line much more efficient by only looking for inlined breakpoint locations if we are setting a breakpoint in anything but a source implementation file. Implementing this complex for a many reasons. Turns out that parsing compile units lazily had some issues with respect to how we need to do things with DWARF in .o files. So the fixes in the checkin for this makes these changes:
- Add a new setting called "target.inline-breakpoint-strategy" which can be set to "never", "always", or "headers". "never" will never try and set any inlined breakpoints (fastest). "always" always looks for inlined breakpoint locations (slowest, but most accurate). "headers", which is the default setting, will only look for inlined breakpoint locations if the breakpoint is set in what are consudered to be header files, which is realy defined as "not in an implementation source file".
- modify the breakpoint setting by file and line to check the current "target.inline-breakpoint-strategy" setting and act accordingly
- Modify compile units to be able to get their language and other info lazily. This allows us to create compile units from the debug map and not have to fill all of the details in, and then lazily discover this information as we go on debuggging. This is needed to avoid parsing all .o files when setting breakpoints in implementation only files (no inlines). Otherwise we would need to parse the .o file, the object file (mach-o in our case) and the symbol file (DWARF in the object file) just to see what the compile unit was.
- modify the "SymbolFileDWARFDebugMap" to subclass lldb_private::Module so that the virtual "GetObjectFile()" and "GetSymbolVendor()" functions can be intercepted when the .o file contenst are later lazilly needed. Prior to this fix, when we first instantiated the "SymbolFileDWARFDebugMap" class, we would also make modules, object files and symbol files for every .o file in the debug map because we needed to fix up the sections in the .o files with information that is in the executable debug map. Now we lazily do this in the DebugMapModule::GetObjectFile()
Cleaned up header includes a bit as well.
llvm-svn: 162860
2012-08-30 05:13:06 +08:00
|
|
|
|
2019-01-12 02:03:20 +08:00
|
|
|
bool SymbolVendor::ParseDebugMacros(CompileUnit &comp_unit) {
|
2016-09-07 04:57:50 +08:00
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
return m_sym_file_up->ParseDebugMacros(comp_unit);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2019-01-12 02:03:20 +08:00
|
|
|
bool SymbolVendor::ParseSupportFiles(CompileUnit &comp_unit,
|
|
|
|
FileSpecList &support_files) {
|
2016-09-07 04:57:50 +08:00
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
return m_sym_file_up->ParseSupportFiles(comp_unit, support_files);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
return false;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2019-01-12 02:03:20 +08:00
|
|
|
bool SymbolVendor::ParseIsOptimized(CompileUnit &comp_unit) {
|
2016-09-07 04:57:50 +08:00
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
return m_sym_file_up->ParseIsOptimized(comp_unit);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
bool SymbolVendor::ParseImportedModules(
|
2019-02-14 02:10:41 +08:00
|
|
|
const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
|
2016-09-07 04:57:50 +08:00
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
return m_sym_file_up->ParseImportedModules(sc, imported_modules);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
return false;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2019-01-15 06:40:41 +08:00
|
|
|
size_t SymbolVendor::ParseBlocksRecursive(Function &func) {
|
2016-09-07 04:57:50 +08:00
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
return m_sym_file_up->ParseBlocksRecursive(func);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2019-01-12 02:03:20 +08:00
|
|
|
size_t SymbolVendor::ParseTypes(CompileUnit &comp_unit) {
|
2016-09-07 04:57:50 +08:00
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
return m_sym_file_up->ParseTypes(comp_unit);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t SymbolVendor::ParseVariablesForContext(const SymbolContext &sc) {
|
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
return m_sym_file_up->ParseVariablesForContext(sc);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Type *SymbolVendor::ResolveTypeUID(lldb::user_id_t type_uid) {
|
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
return m_sym_file_up->ResolveTypeUID(type_uid);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t SymbolVendor::ResolveSymbolContext(const Address &so_addr,
|
2018-10-26 04:45:19 +08:00
|
|
|
SymbolContextItem resolve_scope,
|
2016-09-07 04:57:50 +08:00
|
|
|
SymbolContext &sc) {
|
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
return m_sym_file_up->ResolveSymbolContext(so_addr, resolve_scope, sc);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t SymbolVendor::ResolveSymbolContext(const FileSpec &file_spec,
|
|
|
|
uint32_t line, bool check_inlines,
|
2018-10-26 04:45:19 +08:00
|
|
|
SymbolContextItem resolve_scope,
|
2016-09-07 04:57:50 +08:00
|
|
|
SymbolContextList &sc_list) {
|
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
return m_sym_file_up->ResolveSymbolContext(file_spec, line, check_inlines,
|
2016-09-07 04:57:50 +08:00
|
|
|
resolve_scope, sc_list);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-05-31 17:46:26 +08:00
|
|
|
size_t
|
2019-03-07 05:22:25 +08:00
|
|
|
SymbolVendor::FindGlobalVariables(ConstString name,
|
2018-05-31 17:46:26 +08:00
|
|
|
const CompilerDeclContext *parent_decl_ctx,
|
|
|
|
size_t max_matches, VariableList &variables) {
|
2016-09-07 04:57:50 +08:00
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
return m_sym_file_up->FindGlobalVariables(name, parent_decl_ctx,
|
2016-09-07 04:57:50 +08:00
|
|
|
max_matches, variables);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t SymbolVendor::FindGlobalVariables(const RegularExpression ®ex,
|
2018-05-31 17:46:26 +08:00
|
|
|
size_t max_matches,
|
2016-09-07 04:57:50 +08:00
|
|
|
VariableList &variables) {
|
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
return m_sym_file_up->FindGlobalVariables(regex, max_matches, variables);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-03-07 05:22:25 +08:00
|
|
|
size_t SymbolVendor::FindFunctions(ConstString name,
|
2016-09-07 04:57:50 +08:00
|
|
|
const CompilerDeclContext *parent_decl_ctx,
|
2018-10-26 04:45:40 +08:00
|
|
|
FunctionNameType name_type_mask,
|
2016-09-07 04:57:50 +08:00
|
|
|
bool include_inlines, bool append,
|
|
|
|
SymbolContextList &sc_list) {
|
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
return m_sym_file_up->FindFunctions(name, parent_decl_ctx, name_type_mask,
|
2016-09-07 04:57:50 +08:00
|
|
|
include_inlines, append, sc_list);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t SymbolVendor::FindFunctions(const RegularExpression ®ex,
|
|
|
|
bool include_inlines, bool append,
|
|
|
|
SymbolContextList &sc_list) {
|
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
return m_sym_file_up->FindFunctions(regex, include_inlines, append,
|
2016-09-07 04:57:50 +08:00
|
|
|
sc_list);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t SymbolVendor::FindTypes(
|
2019-03-07 05:22:25 +08:00
|
|
|
ConstString name, const CompilerDeclContext *parent_decl_ctx,
|
2019-01-15 06:41:21 +08:00
|
|
|
bool append, size_t max_matches,
|
2016-09-07 04:57:50 +08:00
|
|
|
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
|
|
|
|
TypeMap &types) {
|
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
return m_sym_file_up->FindTypes(name, parent_decl_ctx, append,
|
2016-09-07 04:57:50 +08:00
|
|
|
max_matches, searched_symbol_files,
|
|
|
|
types);
|
|
|
|
}
|
|
|
|
if (!append)
|
|
|
|
types.Clear();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t SymbolVendor::FindTypes(const std::vector<CompilerContext> &context,
|
|
|
|
bool append, TypeMap &types) {
|
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
return m_sym_file_up->FindTypes(context, append, types);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
if (!append)
|
|
|
|
types.Clear();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-26 04:45:40 +08:00
|
|
|
size_t SymbolVendor::GetTypes(SymbolContextScope *sc_scope, TypeClass type_mask,
|
2016-09-07 04:57:50 +08:00
|
|
|
lldb_private::TypeList &type_list) {
|
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
return m_sym_file_up->GetTypes(sc_scope, type_mask, type_list);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
return 0;
|
2013-06-19 06:51:05 +08:00
|
|
|
}
|
|
|
|
|
2015-08-25 07:46:31 +08:00
|
|
|
CompilerDeclContext
|
2019-03-07 05:22:25 +08:00
|
|
|
SymbolVendor::FindNamespace(ConstString name,
|
2016-09-07 04:57:50 +08:00
|
|
|
const CompilerDeclContext *parent_decl_ctx) {
|
|
|
|
CompilerDeclContext namespace_decl_ctx;
|
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
namespace_decl_ctx = m_sym_file_up->FindNamespace(name, parent_decl_ctx);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
return namespace_decl_ctx;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SymbolVendor::Dump(Stream *s) {
|
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
|
|
|
|
|
|
|
bool show_context = false;
|
|
|
|
|
|
|
|
s->Printf("%p: ", static_cast<void *>(this));
|
|
|
|
s->Indent();
|
|
|
|
s->PutCString("SymbolVendor");
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up) {
|
|
|
|
*s << " " << m_sym_file_up->GetPluginName();
|
|
|
|
ObjectFile *objfile = m_sym_file_up->GetObjectFile();
|
2016-09-07 04:57:50 +08:00
|
|
|
if (objfile) {
|
|
|
|
const FileSpec &objfile_file_spec = objfile->GetFileSpec();
|
|
|
|
if (objfile_file_spec) {
|
|
|
|
s->PutCString(" (");
|
|
|
|
objfile_file_spec.Dump(s);
|
|
|
|
s->PutChar(')');
|
2012-03-14 07:14:29 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
s->EOL();
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up)
|
|
|
|
m_sym_file_up->Dump(*s);
|
2016-09-07 04:57:50 +08:00
|
|
|
s->IndentMore();
|
|
|
|
m_type_list.Dump(s, show_context);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
CompileUnitConstIter cu_pos, cu_end;
|
|
|
|
cu_end = m_compile_units.end();
|
|
|
|
for (cu_pos = m_compile_units.begin(); cu_pos != cu_end; ++cu_pos) {
|
|
|
|
// We currently only dump the compile units that have been parsed
|
2019-02-12 11:47:39 +08:00
|
|
|
if (*cu_pos)
|
2016-09-07 04:57:50 +08:00
|
|
|
(*cu_pos)->Dump(s, show_context);
|
2012-03-14 07:14:29 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
Introduce SymbolFileBreakpad and use it to fill symtab
Summary:
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.
Reviewers: clayborg, zturner, lemo, markmentovai, amccarth
Subscribers: mgorny, lldb-commits
Differential Revision: https://reviews.llvm.org/D56173
llvm-svn: 350924
2019-01-11 19:17:51 +08:00
|
|
|
if (Symtab *symtab = GetSymtab())
|
|
|
|
symtab->Dump(s, nullptr, eSortOrderNone);
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
s->IndentLess();
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
CompUnitSP SymbolVendor::GetCompileUnitAtIndex(size_t idx) {
|
|
|
|
CompUnitSP cu_sp;
|
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
|
|
|
const size_t num_compile_units = GetNumCompileUnits();
|
|
|
|
if (idx < num_compile_units) {
|
|
|
|
cu_sp = m_compile_units[idx];
|
|
|
|
if (cu_sp.get() == nullptr) {
|
2019-02-13 14:25:41 +08:00
|
|
|
m_compile_units[idx] = m_sym_file_up->ParseCompileUnitAtIndex(idx);
|
2016-09-07 04:57:50 +08:00
|
|
|
cu_sp = m_compile_units[idx];
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
return cu_sp;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
FileSpec SymbolVendor::GetMainFileSpec() const {
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up) {
|
|
|
|
const ObjectFile *symfile_objfile = m_sym_file_up->GetObjectFile();
|
2016-09-07 04:57:50 +08:00
|
|
|
if (symfile_objfile)
|
|
|
|
return symfile_objfile->GetFileSpec();
|
|
|
|
}
|
2015-03-11 05:18:59 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
return FileSpec();
|
2015-03-11 05:18:59 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
Symtab *SymbolVendor::GetSymtab() {
|
|
|
|
ModuleSP module_sp(GetModule());
|
[Symbol] Search symbols with name and type in a symbol file
Summary:
This patch adds possibility of searching a public symbol with name and type in
a symbol file, not only in a symtab. It is helpful when working with PE, because
PE's symtabs contain only imported / exported symbols only. Such a search is
required for e.g. evaluation of an expression that calls some function of
the debuggee.
Reviewers: zturner, asmith, labath, clayborg, espindola
Reviewed By: clayborg
Subscribers: davide, emaste, arichardson, aleksandr.urakov, jingham,
lldb-commits, stella.stamenova
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D53368
llvm-svn: 347960
2018-11-30 14:56:37 +08:00
|
|
|
if (!module_sp)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
|
|
|
|
|
|
|
if (m_symtab)
|
|
|
|
return m_symtab;
|
|
|
|
|
|
|
|
ObjectFile *objfile = module_sp->GetObjectFile();
|
|
|
|
if (!objfile)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
m_symtab = objfile->GetSymtab();
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_symtab && m_sym_file_up)
|
|
|
|
m_sym_file_up->AddSymbols(*m_symtab);
|
[Symbol] Search symbols with name and type in a symbol file
Summary:
This patch adds possibility of searching a public symbol with name and type in
a symbol file, not only in a symtab. It is helpful when working with PE, because
PE's symtabs contain only imported / exported symbols only. Such a search is
required for e.g. evaluation of an expression that calls some function of
the debuggee.
Reviewers: zturner, asmith, labath, clayborg, espindola
Reviewed By: clayborg
Subscribers: davide, emaste, arichardson, aleksandr.urakov, jingham,
lldb-commits, stella.stamenova
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D53368
llvm-svn: 347960
2018-11-30 14:56:37 +08:00
|
|
|
|
|
|
|
return m_symtab;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void SymbolVendor::ClearSymtab() {
|
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
ObjectFile *objfile = module_sp->GetObjectFile();
|
|
|
|
if (objfile) {
|
|
|
|
// Clear symbol table from unified section list.
|
|
|
|
objfile->ClearSymtab();
|
2013-07-02 03:45:50 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2013-07-02 03:45:50 +08:00
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
void SymbolVendor::SectionFileAddressesChanged() {
|
|
|
|
ModuleSP module_sp(GetModule());
|
|
|
|
if (module_sp) {
|
|
|
|
ObjectFile *module_objfile = module_sp->GetObjectFile();
|
2019-02-13 14:25:41 +08:00
|
|
|
if (m_sym_file_up) {
|
|
|
|
ObjectFile *symfile_objfile = m_sym_file_up->GetObjectFile();
|
2016-09-07 04:57:50 +08:00
|
|
|
if (symfile_objfile != module_objfile)
|
|
|
|
symfile_objfile->SectionFileAddressesChanged();
|
|
|
|
}
|
|
|
|
Symtab *symtab = GetSymtab();
|
|
|
|
if (symtab) {
|
|
|
|
symtab->SectionFileAddressesChanged();
|
2014-08-22 10:46:46 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2014-08-22 10:46:46 +08:00
|
|
|
}
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
// PluginInterface protocol
|
2016-09-07 04:57:50 +08:00
|
|
|
lldb_private::ConstString SymbolVendor::GetPluginName() {
|
|
|
|
static ConstString g_name("vendor-default");
|
|
|
|
return g_name;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
uint32_t SymbolVendor::GetPluginVersion() { return 1; }
|