aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins')
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp2
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp63
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h13
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp22
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp3
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp2
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp13
-rw-r--r--lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp7
-rw-r--r--lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h2
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp244
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h11
-rw-r--r--lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp21
-rw-r--r--lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h2
-rw-r--r--lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h2
-rw-r--r--lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp2
-rw-r--r--lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h2
-rw-r--r--lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp148
-rw-r--r--lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h57
-rw-r--r--lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td12
-rw-r--r--lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp4
-rw-r--r--lldb/source/Plugins/Process/elf-core/ProcessElfCore.h8
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp96
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h23
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp13
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp6
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h4
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp12
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h1
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp62
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h10
-rw-r--r--lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp6
-rw-r--r--lldb/source/Plugins/Process/minidump/ProcessMinidump.h6
-rw-r--r--lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp4
-rw-r--r--lldb/source/Plugins/Process/scripted/ScriptedProcess.h6
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h152
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp183
-rw-r--r--lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp3
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp12
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp5
-rw-r--r--lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp1
-rw-r--r--lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp2
41 files changed, 653 insertions, 594 deletions
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index 50e9f7827838..1437d7b58293 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -516,7 +516,7 @@ CppModuleConfiguration GetModuleConfig(lldb::LanguageType language,
// Try to create a configuration from the files. If there is no valid
// configuration possible with the files, this just returns an invalid
// configuration.
- return CppModuleConfiguration(files);
+ return CppModuleConfiguration(files, target->GetArchitecture().GetTriple());
}
bool ClangUserExpression::PrepareForParsing(
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
index ffab16b1682b..befb1f125406 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
@@ -10,6 +10,7 @@
#include "ClangHost.h"
#include "lldb/Host/FileSystem.h"
+#include "llvm/ADT/Triple.h"
using namespace lldb_private;
@@ -30,7 +31,35 @@ bool CppModuleConfiguration::SetOncePath::TrySet(llvm::StringRef path) {
return false;
}
-bool CppModuleConfiguration::analyzeFile(const FileSpec &f) {
+static llvm::SmallVector<std::string, 2>
+getTargetIncludePaths(const llvm::Triple &triple) {
+ llvm::SmallVector<std::string, 2> paths;
+ if (!triple.str().empty()) {
+ paths.push_back("/usr/include/" + triple.str());
+ if (!triple.getArchName().empty() ||
+ triple.getOSAndEnvironmentName().empty())
+ paths.push_back(("/usr/include/" + triple.getArchName() + "-" +
+ triple.getOSAndEnvironmentName())
+ .str());
+ }
+ return paths;
+}
+
+/// Returns the include path matching the given pattern for the given file
+/// path (or None if the path doesn't match the pattern).
+static llvm::Optional<llvm::StringRef>
+guessIncludePath(llvm::StringRef path_to_file, llvm::StringRef pattern) {
+ if (pattern.empty())
+ return llvm::NoneType();
+ size_t pos = path_to_file.find(pattern);
+ if (pos == llvm::StringRef::npos)
+ return llvm::NoneType();
+
+ return path_to_file.substr(0, pos + pattern.size());
+}
+
+bool CppModuleConfiguration::analyzeFile(const FileSpec &f,
+ const llvm::Triple &triple) {
using namespace llvm::sys::path;
// Convert to slashes to make following operations simpler.
std::string dir_buffer = convert_to_slash(f.GetDirectory().GetStringRef());
@@ -43,15 +72,25 @@ bool CppModuleConfiguration::analyzeFile(const FileSpec &f) {
// need to be specified in the header search.
if (libcpp_regex.match(f.GetPath()) &&
parent_path(posix_dir, Style::posix).endswith("c++")) {
- return m_std_inc.TrySet(posix_dir);
+ if (!m_std_inc.TrySet(posix_dir))
+ return false;
+ if (triple.str().empty())
+ return true;
+
+ posix_dir.consume_back("c++/v1");
+ // Check if this is a target-specific libc++ include directory.
+ return m_std_target_inc.TrySet(
+ (posix_dir + triple.str() + "/c++/v1").str());
}
- // Check for /usr/include. On Linux this might be /usr/include/bits, so
- // we should remove that '/bits' suffix to get the actual include directory.
- if (posix_dir.endswith("/usr/include/bits"))
- posix_dir.consume_back("/bits");
- if (posix_dir.endswith("/usr/include"))
- return m_c_inc.TrySet(posix_dir);
+ llvm::Optional<llvm::StringRef> inc_path;
+ // Target specific paths contains /usr/include, so we check them first
+ for (auto &path : getTargetIncludePaths(triple)) {
+ if ((inc_path = guessIncludePath(posix_dir, path)))
+ return m_c_target_inc.TrySet(*inc_path);
+ }
+ if ((inc_path = guessIncludePath(posix_dir, "/usr/include")))
+ return m_c_inc.TrySet(*inc_path);
// File wasn't interesting, continue analyzing.
return true;
@@ -92,11 +131,11 @@ bool CppModuleConfiguration::hasValidConfig() {
}
CppModuleConfiguration::CppModuleConfiguration(
- const FileSpecList &support_files) {
+ const FileSpecList &support_files, const llvm::Triple &triple) {
// Analyze all files we were given to build the configuration.
bool error = !llvm::all_of(support_files,
std::bind(&CppModuleConfiguration::analyzeFile,
- this, std::placeholders::_1));
+ this, std::placeholders::_1, triple));
// If we have a valid configuration at this point, set the
// include directories and module list that should be used.
if (!error && hasValidConfig()) {
@@ -109,6 +148,10 @@ CppModuleConfiguration::CppModuleConfiguration(
// This order matches the way Clang orders these directories.
m_include_dirs = {m_std_inc.Get().str(), m_resource_inc,
m_c_inc.Get().str()};
+ if (m_c_target_inc.Valid())
+ m_include_dirs.push_back(m_c_target_inc.Get().str());
+ if (m_std_target_inc.Valid())
+ m_include_dirs.push_back(m_std_target_inc.Get().str());
m_imported_modules = {"std"};
}
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
index 907db5d625dc..5db8abbdbdf3 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
@@ -42,8 +42,15 @@ class CppModuleConfiguration {
/// If valid, the include path used for the std module.
SetOncePath m_std_inc;
+ /// If valid, the per-target include path used for the std module.
+ /// This is an optional path only required on some systems.
+ SetOncePath m_std_target_inc;
/// If valid, the include path to the C library (e.g. /usr/include).
SetOncePath m_c_inc;
+ /// If valid, the include path to target-specific C library files
+ /// (e.g. /usr/include/x86_64-linux-gnu).
+ /// This is an optional path only required on some systems.
+ SetOncePath m_c_target_inc;
/// The Clang resource include path for this configuration.
std::string m_resource_inc;
@@ -53,11 +60,13 @@ class CppModuleConfiguration {
/// Analyze a given source file to build the current configuration.
/// Returns false iff there was a fatal error that makes analyzing any
/// further files pointless as the configuration is now invalid.
- bool analyzeFile(const FileSpec &f);
+ bool analyzeFile(const FileSpec &f, const llvm::Triple &triple);
public:
/// Creates a configuration by analyzing the given list of used source files.
- explicit CppModuleConfiguration(const FileSpecList &support_files);
+ /// The triple (if valid) is used to search for target-specific include paths.
+ explicit CppModuleConfiguration(const FileSpecList &support_files,
+ const llvm::Triple &triple);
/// Creates an empty and invalid configuration.
CppModuleConfiguration() = default;
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 83e8e52b86f2..f1925990e94a 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -914,11 +914,21 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
stl_deref_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
+ RegularExpression("^std::optional<.+>(( )?&)?$"),
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ stl_synth_flags,
+ "lldb.formatters.cpp.gnu_libstdcpp.StdOptionalSynthProvider")));
+ cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
RegularExpression("^std::multiset<.+> >(( )?&)?$"),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_deref_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider")));
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
+ RegularExpression("^std::unordered_(multi)?(map|set)<.+> >$"),
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(
+ stl_deref_flags,
+ "lldb.formatters.cpp.gnu_libstdcpp.StdUnorderedMapSynthProvider")));
+ cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$"),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
@@ -928,9 +938,15 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdForwardListSynthProvider")));
+
stl_summary_flags.SetDontShowChildren(false);
stl_summary_flags.SetSkipPointers(false);
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
+ RegularExpression("^std::optional<.+>(( )?&)?$"),
+ TypeSummaryImplSP(new ScriptSummaryFormat(
+ stl_summary_flags,
+ "lldb.formatters.cpp.gnu_libstdcpp.StdOptionalSummaryProvider")));
+ cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
RegularExpression("^std::bitset<.+>(( )?&)?$"),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
@@ -955,13 +971,17 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
+ RegularExpression("^std::unordered_(multi)?(map|set)<.+> >$"),
+ TypeSummaryImplSP(
+ new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
+ cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$"),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
RegularExpression("^std::(__cxx11::)?forward_list<.+>(( )?&)?$"),
TypeSummaryImplSP(
- new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
+ new ScriptSummaryFormat(stl_summary_flags, "lldb.formatters.cpp.gnu_libstdcpp.ForwardListSummaryProvider")));
AddCXXSynthetic(
cpp_category_sp,
diff --git a/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp b/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
index fc8255983436..c8063915b178 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
@@ -81,12 +81,11 @@ bool GenericBitsetFrontEnd::Update() {
TargetSP target_sp = m_backend.GetTargetSP();
if (!target_sp)
return false;
- size_t capping_size = target_sp->GetMaximumNumberOfChildrenToDisplay();
size_t size = 0;
if (auto arg = m_backend.GetCompilerType().GetIntegralTemplateArgument(0))
- size = arg->value.getLimitedValue(capping_size);
+ size = arg->value.getLimitedValue();
m_elements.assign(size, ValueObjectSP());
m_first = m_backend.GetChildMemberWithName(GetDataContainerMemberName(), true)
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
index c0c819632851..c1b40ba65e7d 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
@@ -45,7 +45,7 @@ bool OptionalFrontEnd::Update() {
// __engaged_ is a bool flag and is true if the optional contains a value.
// Converting it to unsigned gives us a size of 1 if it contains a value
// and 0 if not.
- m_has_value = engaged_sp->GetValueAsUnsigned(0) == 1;
+ m_has_value = engaged_sp->GetValueAsUnsigned(0) != 0;
return false;
}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
index 3a441973fc73..57c5ba87c397 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
@@ -62,9 +62,7 @@ lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
size_t lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
CalculateNumChildren() {
- if (m_num_elements != UINT32_MAX)
- return m_num_elements;
- return 0;
+ return m_num_elements;
}
lldb::ValueObjectSP lldb_private::formatters::
@@ -160,7 +158,7 @@ lldb::ValueObjectSP lldb_private::formatters::
bool lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
Update() {
- m_num_elements = UINT32_MAX;
+ m_num_elements = 0;
m_next_element = nullptr;
m_elements_cache.clear();
ValueObjectSP table_sp =
@@ -195,8 +193,13 @@ bool lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
if (!num_elements_sp)
return false;
- m_num_elements = num_elements_sp->GetValueAsUnsigned(0);
+
m_tree = table_sp->GetChildAtNamePath(next_path).get();
+ if (m_tree == nullptr)
+ return false;
+
+ m_num_elements = num_elements_sp->GetValueAsUnsigned(0);
+
if (m_num_elements > 0)
m_next_element =
table_sp->GetChildAtNamePath(next_path).get();
diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
index bad730512ff4..ce701fd823fd 100644
--- a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
+++ b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
@@ -116,9 +116,10 @@ bool ObjectFileBreakpad::ParseHeader() {
return true;
}
-Symtab *ObjectFileBreakpad::GetSymtab() {
- // TODO
- return nullptr;
+void ObjectFileBreakpad::ParseSymtab(Symtab &symtab) {
+ // Nothing to do for breakpad files, all information is parsed as debug info
+ // which means "lldb_private::Function" objects are used, or symbols are added
+ // by the SymbolFileBreakpad::AddSymbols(...) function in the symbol file.
}
void ObjectFileBreakpad::CreateSections(SectionList &unified_section_list) {
diff --git a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
index c320c7ad3e2e..f04e0b4dd7a7 100644
--- a/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
+++ b/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
@@ -71,7 +71,7 @@ public:
return AddressClass::eInvalid;
}
- Symtab *GetSymtab() override;
+ void ParseSymtab(lldb_private::Symtab &symtab) override;
bool IsStripped() override { return false; }
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 8e0f228a988f..96e94ef08a45 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -2687,155 +2687,131 @@ unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr,
return 0;
}
-Symtab *ObjectFileELF::GetSymtab() {
+void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) {
ModuleSP module_sp(GetModule());
if (!module_sp)
- return nullptr;
+ return;
+
+ Progress progress(
+ llvm::formatv("Parsing symbol table for {0}",
+ m_file.GetFilename().AsCString("<Unknown>")));
+ ElapsedTime elapsed(module_sp->GetSymtabParseTime());
// We always want to use the main object file so we (hopefully) only have one
// cached copy of our symtab, dynamic sections, etc.
ObjectFile *module_obj_file = module_sp->GetObjectFile();
if (module_obj_file && module_obj_file != this)
- return module_obj_file->GetSymtab();
-
- if (m_symtab_up == nullptr) {
- Progress progress(
- llvm::formatv("Parsing symbol table for {0}",
- m_file.GetFilename().AsCString("<Unknown>")));
- ElapsedTime elapsed(module_sp->GetSymtabParseTime());
- SectionList *section_list = module_sp->GetSectionList();
- if (!section_list)
- return nullptr;
+ return module_obj_file->ParseSymtab(lldb_symtab);
- uint64_t symbol_id = 0;
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
-
- // Sharable objects and dynamic executables usually have 2 distinct symbol
- // tables, one named ".symtab", and the other ".dynsym". The dynsym is a
- // smaller version of the symtab that only contains global symbols. The
- // information found in the dynsym is therefore also found in the symtab,
- // while the reverse is not necessarily true.
- Section *symtab =
- section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
- if (symtab) {
- m_symtab_up = std::make_unique<Symtab>(symtab->GetObjectFile());
- symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, symtab);
- }
-
- // The symtab section is non-allocable and can be stripped, while the
- // .dynsym section which should always be always be there. To support the
- // minidebuginfo case we parse .dynsym when there's a .gnu_debuginfo
- // section, nomatter if .symtab was already parsed or not. This is because
- // minidebuginfo normally removes the .symtab symbols which have their
- // matching .dynsym counterparts.
- if (!symtab ||
- GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"))) {
- Section *dynsym =
- section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
- .get();
- if (dynsym) {
- if (!m_symtab_up)
- m_symtab_up = std::make_unique<Symtab>(dynsym->GetObjectFile());
- symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, dynsym);
- }
- }
+ SectionList *section_list = module_sp->GetSectionList();
+ if (!section_list)
+ return;
- // DT_JMPREL
- // If present, this entry's d_ptr member holds the address of
- // relocation
- // entries associated solely with the procedure linkage table.
- // Separating
- // these relocation entries lets the dynamic linker ignore them during
- // process initialization, if lazy binding is enabled. If this entry is
- // present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
- // also be present.
- const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
- if (symbol) {
- // Synthesize trampoline symbols to help navigate the PLT.
- addr_t addr = symbol->d_ptr;
- Section *reloc_section =
- section_list->FindSectionContainingFileAddress(addr).get();
- if (reloc_section) {
- user_id_t reloc_id = reloc_section->GetID();
- const ELFSectionHeaderInfo *reloc_header =
- GetSectionHeaderByIndex(reloc_id);
- if (reloc_header) {
- if (m_symtab_up == nullptr)
- m_symtab_up =
- std::make_unique<Symtab>(reloc_section->GetObjectFile());
-
- ParseTrampolineSymbols(m_symtab_up.get(), symbol_id, reloc_header,
- reloc_id);
- }
- }
- }
+ uint64_t symbol_id = 0;
- if (DWARFCallFrameInfo *eh_frame =
- GetModule()->GetUnwindTable().GetEHFrameInfo()) {
- if (m_symtab_up == nullptr)
- m_symtab_up = std::make_unique<Symtab>(this);
- ParseUnwindSymbols(m_symtab_up.get(), eh_frame);
+ // Sharable objects and dynamic executables usually have 2 distinct symbol
+ // tables, one named ".symtab", and the other ".dynsym". The dynsym is a
+ // smaller version of the symtab that only contains global symbols. The
+ // information found in the dynsym is therefore also found in the symtab,
+ // while the reverse is not necessarily true.
+ Section *symtab =
+ section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
+ if (symtab)
+ symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, symtab);
+
+ // The symtab section is non-allocable and can be stripped, while the
+ // .dynsym section which should always be always be there. To support the
+ // minidebuginfo case we parse .dynsym when there's a .gnu_debuginfo
+ // section, nomatter if .symtab was already parsed or not. This is because
+ // minidebuginfo normally removes the .symtab symbols which have their
+ // matching .dynsym counterparts.
+ if (!symtab ||
+ GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"))) {
+ Section *dynsym =
+ section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
+ .get();
+ if (dynsym)
+ symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, dynsym);
+ }
+
+ // DT_JMPREL
+ // If present, this entry's d_ptr member holds the address of
+ // relocation
+ // entries associated solely with the procedure linkage table.
+ // Separating
+ // these relocation entries lets the dynamic linker ignore them during
+ // process initialization, if lazy binding is enabled. If this entry is
+ // present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
+ // also be present.
+ const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
+ if (symbol) {
+ // Synthesize trampoline symbols to help navigate the PLT.
+ addr_t addr = symbol->d_ptr;
+ Section *reloc_section =
+ section_list->FindSectionContainingFileAddress(addr).get();
+ if (reloc_section) {
+ user_id_t reloc_id = reloc_section->GetID();
+ const ELFSectionHeaderInfo *reloc_header =
+ GetSectionHeaderByIndex(reloc_id);
+ if (reloc_header)
+ ParseTrampolineSymbols(&lldb_symtab, symbol_id, reloc_header, reloc_id);
}
+ }
- // If we still don't have any symtab then create an empty instance to avoid
- // do the section lookup next time.
- if (m_symtab_up == nullptr)
- m_symtab_up = std::make_unique<Symtab>(this);
-
- // In the event that there's no symbol entry for the entry point we'll
- // artificially create one. We delegate to the symtab object the figuring
- // out of the proper size, this will usually make it span til the next
- // symbol it finds in the section. This means that if there are missing
- // symbols the entry point might span beyond its function definition.
- // We're fine with this as it doesn't make it worse than not having a
- // symbol entry at all.
- if (CalculateType() == eTypeExecutable) {
- ArchSpec arch = GetArchitecture();
- auto entry_point_addr = GetEntryPointAddress();
- bool is_valid_entry_point =
- entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset();
- addr_t entry_point_file_addr = entry_point_addr.GetFileAddress();
- if (is_valid_entry_point && !m_symtab_up->FindSymbolContainingFileAddress(
- entry_point_file_addr)) {
- uint64_t symbol_id = m_symtab_up->GetNumSymbols();
- // Don't set the name for any synthetic symbols, the Symbol
- // object will generate one if needed when the name is accessed
- // via accessors.
- SectionSP section_sp = entry_point_addr.GetSection();
- Symbol symbol(
- /*symID=*/symbol_id,
- /*name=*/llvm::StringRef(), // Name will be auto generated.
- /*type=*/eSymbolTypeCode,
- /*external=*/true,
- /*is_debug=*/false,
- /*is_trampoline=*/false,
- /*is_artificial=*/true,
- /*section_sp=*/section_sp,
- /*offset=*/0,
- /*size=*/0, // FDE can span multiple symbols so don't use its size.
- /*size_is_valid=*/false,
- /*contains_linker_annotations=*/false,
- /*flags=*/0);
- // When the entry point is arm thumb we need to explicitly set its
- // class address to reflect that. This is important because expression
- // evaluation relies on correctly setting a breakpoint at this
- // address.
- if (arch.GetMachine() == llvm::Triple::arm &&
- (entry_point_file_addr & 1)) {
- symbol.GetAddressRef().SetOffset(entry_point_addr.GetOffset() ^ 1);
- m_address_class_map[entry_point_file_addr ^ 1] =
- AddressClass::eCodeAlternateISA;
- } else {
- m_address_class_map[entry_point_file_addr] = AddressClass::eCode;
- }
- m_symtab_up->AddSymbol(symbol);
+ if (DWARFCallFrameInfo *eh_frame =
+ GetModule()->GetUnwindTable().GetEHFrameInfo()) {
+ ParseUnwindSymbols(&lldb_symtab, eh_frame);
+ }
+
+ // In the event that there's no symbol entry for the entry point we'll
+ // artificially create one. We delegate to the symtab object the figuring
+ // out of the proper size, this will usually make it span til the next
+ // symbol it finds in the section. This means that if there are missing
+ // symbols the entry point might span beyond its function definition.
+ // We're fine with this as it doesn't make it worse than not having a
+ // symbol entry at all.
+ if (CalculateType() == eTypeExecutable) {
+ ArchSpec arch = GetArchitecture();
+ auto entry_point_addr = GetEntryPointAddress();
+ bool is_valid_entry_point =
+ entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset();
+ addr_t entry_point_file_addr = entry_point_addr.GetFileAddress();
+ if (is_valid_entry_point && !lldb_symtab.FindSymbolContainingFileAddress(
+ entry_point_file_addr)) {
+ uint64_t symbol_id = lldb_symtab.GetNumSymbols();
+ // Don't set the name for any synthetic symbols, the Symbol
+ // object will generate one if needed when the name is accessed
+ // via accessors.
+ SectionSP section_sp = entry_point_addr.GetSection();
+ Symbol symbol(
+ /*symID=*/symbol_id,
+ /*name=*/llvm::StringRef(), // Name will be auto generated.
+ /*type=*/eSymbolTypeCode,
+ /*external=*/true,
+ /*is_debug=*/false,
+ /*is_trampoline=*/false,
+ /*is_artificial=*/true,
+ /*section_sp=*/section_sp,
+ /*offset=*/0,
+ /*size=*/0, // FDE can span multiple symbols so don't use its size.
+ /*size_is_valid=*/false,
+ /*contains_linker_annotations=*/false,
+ /*flags=*/0);
+ // When the entry point is arm thumb we need to explicitly set its
+ // class address to reflect that. This is important because expression
+ // evaluation relies on correctly setting a breakpoint at this
+ // address.
+ if (arch.GetMachine() == llvm::Triple::arm &&
+ (entry_point_file_addr & 1)) {
+ symbol.GetAddressRef().SetOffset(entry_point_addr.GetOffset() ^ 1);
+ m_address_class_map[entry_point_file_addr ^ 1] =
+ AddressClass::eCodeAlternateISA;
+ } else {
+ m_address_class_map[entry_point_file_addr] = AddressClass::eCode;
}
+ lldb_symtab.AddSymbol(symbol);
}
-
- m_symtab_up->CalculateSymbolSizes();
}
-
- return m_symtab_up.get();
}
void ObjectFileELF::RelocateSection(lldb_private::Section *section)
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index 5738e5cf60d5..554f623ec8af 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -110,7 +110,7 @@ public:
lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override;
- lldb_private::Symtab *GetSymtab() override;
+ void ParseSymtab(lldb_private::Symtab &symtab) override;
bool IsStripped() override;
@@ -123,7 +123,7 @@ public:
lldb_private::UUID GetUUID() override;
/// Return the contents of the .gnu_debuglink section, if the object file
- /// contains it.
+ /// contains it.
llvm::Optional<lldb_private::FileSpec> GetDebugLink();
uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
@@ -278,8 +278,9 @@ private:
/// number of dynamic symbols parsed.
size_t ParseDynamicSymbols();
- /// Populates m_symtab_up will all non-dynamic linker symbols. This method
- /// will parse the symbols only once. Returns the number of symbols parsed.
+ /// Populates the symbol table with all non-dynamic linker symbols. This
+ /// method will parse the symbols only once. Returns the number of symbols
+ /// parsed.
unsigned ParseSymbolTable(lldb_private::Symtab *symbol_table,
lldb::user_id_t start_id,
lldb_private::Section *symtab);
@@ -384,7 +385,7 @@ private:
lldb_private::UUID &uuid);
bool AnySegmentHasPhysicalAddress();
-
+
/// Takes the .gnu_debugdata and returns the decompressed object file that is
/// stored within that section.
///
diff --git a/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
index bec0099517c8..ca9337454889 100644
--- a/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
+++ b/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
@@ -106,23 +106,10 @@ uint32_t ObjectFileJIT::GetAddressByteSize() const {
return m_data.GetAddressByteSize();
}
-Symtab *ObjectFileJIT::GetSymtab() {
- ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- if (m_symtab_up == nullptr) {
- ElapsedTime elapsed(module_sp->GetSymtabParseTime());
- m_symtab_up = std::make_unique<Symtab>(this);
- std::lock_guard<std::recursive_mutex> symtab_guard(
- m_symtab_up->GetMutex());
- ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());
- if (delegate_sp)
- delegate_sp->PopulateSymtab(this, *m_symtab_up);
- // TODO: get symbols from delegate
- m_symtab_up->Finalize();
- }
- }
- return m_symtab_up.get();
+void ObjectFileJIT::ParseSymtab(Symtab &symtab) {
+ ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());
+ if (delegate_sp)
+ delegate_sp->PopulateSymtab(this, symtab);
}
bool ObjectFileJIT::IsStripped() {
diff --git a/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h b/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
index 03ac001988a0..be31139df549 100644
--- a/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
+++ b/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
@@ -67,7 +67,7 @@ public:
uint32_t GetAddressByteSize() const override;
- lldb_private::Symtab *GetSymtab() override;
+ void ParseSymtab(lldb_private::Symtab &symtab) override;
bool IsStripped() override;
diff --git a/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h b/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h
index 36e71e21332f..da999d2b55a7 100644
--- a/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h
+++ b/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h
@@ -68,7 +68,7 @@ public:
bool IsExecutable() const override { return false; }
- Symtab *GetSymtab() override { return nullptr; }
+ void ParseSymtab(lldb_private::Symtab &symtab) override {}
bool IsStripped() override { return false; }
diff --git a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
index 0e6329885528..7445f8311c50 100644
--- a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
+++ b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
@@ -246,7 +246,7 @@ bool ObjectFileWasm::ParseHeader() {
return true;
}
-Symtab *ObjectFileWasm::GetSymtab() { return nullptr; }
+void ObjectFileWasm::ParseSymtab(Symtab &symtab) {}
static SectionType GetSectionTypeFromName(llvm::StringRef Name) {
if (Name.consume_front(".debug_") || Name.consume_front(".zdebug_")) {
diff --git a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
index 44939b6d4ea0..d7b5bc22caad 100644
--- a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
+++ b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
@@ -78,7 +78,7 @@ public:
return AddressClass::eInvalid;
}
- Symtab *GetSymtab() override;
+ void ParseSymtab(lldb_private::Symtab &symtab) override;
bool IsStripped() override { return !!GetExternalDebugInfoFileSpec(); }
diff --git a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp
new file mode 100644
index 000000000000..90c290b6fbc7
--- /dev/null
+++ b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp
@@ -0,0 +1,148 @@
+//===-- PlatformQemuUser.cpp ----------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/Platform/QemuUser/PlatformQemuUser.h"
+#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/ProcessLaunchInfo.h"
+#include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/Listener.h"
+#include "lldb/Utility/Log.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE(PlatformQemuUser)
+
+#define LLDB_PROPERTIES_platformqemuuser
+#include "PlatformQemuUserProperties.inc"
+
+enum {
+#define LLDB_PROPERTIES_platformqemuuser
+#include "PlatformQemuUserPropertiesEnum.inc"
+};
+
+class PluginProperties : public Properties {
+public:
+ PluginProperties() {
+ m_collection_sp = std::make_shared<OptionValueProperties>(
+ ConstString(PlatformQemuUser::GetPluginNameStatic()));
+ m_collection_sp->Initialize(g_platformqemuuser_properties);
+ }
+
+ llvm::StringRef GetArchitecture() {
+ return m_collection_sp->GetPropertyAtIndexAsString(
+ nullptr, ePropertyArchitecture, "");
+ }
+
+ FileSpec GetEmulatorPath() {
+ return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr,
+ ePropertyEmulatorPath);
+ }
+};
+
+static PluginProperties &GetGlobalProperties() {
+ static PluginProperties g_settings;
+ return g_settings;
+}
+
+llvm::StringRef PlatformQemuUser::GetPluginDescriptionStatic() {
+ return "Platform for debugging binaries under user mode qemu";
+}
+
+void PlatformQemuUser::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), GetPluginDescriptionStatic(),
+ PlatformQemuUser::CreateInstance, PlatformQemuUser::DebuggerInitialize);
+}
+
+void PlatformQemuUser::Terminate() {
+ PluginManager::UnregisterPlugin(PlatformQemuUser::CreateInstance);
+}
+
+void PlatformQemuUser::DebuggerInitialize(Debugger &debugger) {
+ if (!PluginManager::GetSettingForPlatformPlugin(
+ debugger, ConstString(GetPluginNameStatic()))) {
+ PluginManager::CreateSettingForPlatformPlugin(
+ debugger, GetGlobalProperties().GetValueProperties(),
+ ConstString("Properties for the qemu-user platform plugin."),
+ /*is_global_property=*/true);
+ }
+}
+
+PlatformSP PlatformQemuUser::CreateInstance(bool force, const ArchSpec *arch) {
+ if (force)
+ return PlatformSP(new PlatformQemuUser());
+ return nullptr;
+}
+
+std::vector<ArchSpec> PlatformQemuUser::GetSupportedArchitectures() {
+ llvm::Triple triple = HostInfo::GetArchitecture().GetTriple();
+ triple.setEnvironment(llvm::Triple::UnknownEnvironment);
+ triple.setArchName(GetGlobalProperties().GetArchitecture());
+ if (triple.getArch() != llvm::Triple::UnknownArch)
+ return {ArchSpec(triple)};
+ return {};
+}
+
+static auto get_arg_range(const Args &args) {
+ return llvm::make_range(args.GetArgumentArrayRef().begin(),
+ args.GetArgumentArrayRef().end());
+}
+
+lldb::ProcessSP PlatformQemuUser::DebugProcess(ProcessLaunchInfo &launch_info,
+ Debugger &debugger,
+ Target &target, Status &error) {
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+
+ std::string qemu = GetGlobalProperties().GetEmulatorPath().GetPath();
+
+ llvm::SmallString<0> socket_model, socket_path;
+ HostInfo::GetProcessTempDir().GetPath(socket_model);
+ llvm::sys::path::append(socket_model, "qemu-%%%%%%%%.socket");
+ do {
+ llvm::sys::fs::createUniquePath(socket_model, socket_path, false);
+ } while (FileSystem::Instance().Exists(socket_path));
+
+ Args args(
+ {qemu, "-g", socket_path, launch_info.GetExecutableFile().GetPath()});
+ for (size_t i = 1; i < launch_info.GetArguments().size(); ++i)
+ args.AppendArgument(launch_info.GetArguments()[i].ref());
+
+ LLDB_LOG(log, "{0} -> {1}", get_arg_range(launch_info.GetArguments()),
+ get_arg_range(args));
+
+ launch_info.SetArguments(args, true);
+ launch_info.SetLaunchInSeparateProcessGroup(true);
+ launch_info.GetFlags().Clear(eLaunchFlagDebug);
+ launch_info.SetMonitorProcessCallback(ProcessLaunchInfo::NoOpMonitorCallback,
+ false);
+
+ error = Host::LaunchProcess(launch_info);
+ if (error.Fail())
+ return nullptr;
+
+ ProcessSP process_sp = target.CreateProcess(
+ launch_info.GetListener(),
+ process_gdb_remote::ProcessGDBRemote::GetPluginNameStatic(), nullptr,
+ true);
+ ListenerSP listener_sp =
+ Listener::MakeListener("lldb.platform_qemu_user.debugprocess");
+ launch_info.SetHijackListener(listener_sp);
+ Process::ProcessEventHijacker hijacker(*process_sp, listener_sp);
+
+ error = process_sp->ConnectRemote(("unix-connect://" + socket_path).str());
+ if (error.Fail())
+ return nullptr;
+
+ process_sp->WaitForProcessToStop(llvm::None, nullptr, false, listener_sp);
+ return process_sp;
+}
diff --git a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h
new file mode 100644
index 000000000000..f4f5d224a8cd
--- /dev/null
+++ b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.h
@@ -0,0 +1,57 @@
+//===-- PlatformQemuUser.h ------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/Host.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Target/Platform.h"
+
+namespace lldb_private {
+
+class PlatformQemuUser : public Platform {
+public:
+ static void Initialize();
+ static void Terminate();
+
+ static llvm::StringRef GetPluginNameStatic() { return "qemu-user"; }
+ static llvm::StringRef GetPluginDescriptionStatic();
+
+ llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+ llvm::StringRef GetDescription() override {
+ return GetPluginDescriptionStatic();
+ }
+
+ UserIDResolver &GetUserIDResolver() override {
+ return HostInfo::GetUserIDResolver();
+ }
+
+ std::vector<ArchSpec> GetSupportedArchitectures() override;
+
+ lldb::ProcessSP DebugProcess(ProcessLaunchInfo &launch_info,
+ Debugger &debugger, Target &target,
+ Status &error) override;
+
+ lldb::ProcessSP Attach(ProcessAttachInfo &attach_info, Debugger &debugger,
+ Target *target, Status &status) override {
+ status.SetErrorString("Not supported");
+ return nullptr;
+ }
+
+ bool IsConnected() const override { return true; }
+
+ void CalculateTrapHandlerSymbolNames() override {}
+
+ Environment GetEnvironment() override { return Host::GetEnvironment(); }
+
+private:
+ static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+ static void DebuggerInitialize(Debugger &debugger);
+
+ PlatformQemuUser() : Platform(/*is_host=*/false) {}
+};
+
+} // namespace lldb_private
diff --git a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td
new file mode 100644
index 000000000000..abfab7f59de4
--- /dev/null
+++ b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td
@@ -0,0 +1,12 @@
+include "../../../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "platformqemuuser" in {
+ def Architecture: Property<"architecture", "String">,
+ Global,
+ DefaultStringValue<"">,
+ Desc<"Architecture to emulate.">;
+ def EmulatorPath: Property<"emulator-path", "FileSpec">,
+ Global,
+ DefaultStringValue<"">,
+ Desc<"Path to the emulator binary.">;
+}
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index 23b346d5c17f..b852a0164375 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -281,8 +281,8 @@ size_t ProcessElfCore::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
return DoReadMemory(addr, buf, size, error);
}
-Status ProcessElfCore::DoGetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &region_info) {
+Status ProcessElfCore::GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &region_info) {
region_info.Clear();
const VMRangeToPermissions::Entry *permission_entry =
m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
index fd36e5027816..67df3c5fac76 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -86,6 +86,10 @@ public:
size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
lldb_private::Status &error) override;
+ lldb_private::Status
+ GetMemoryRegionInfo(lldb::addr_t load_addr,
+ lldb_private::MemoryRegionInfo &region_info) override;
+
lldb::addr_t GetImageInfoAddress() override;
lldb_private::ArchSpec GetArchitecture();
@@ -101,10 +105,6 @@ protected:
bool DoUpdateThreadList(lldb_private::ThreadList &old_thread_list,
lldb_private::ThreadList &new_thread_list) override;
- lldb_private::Status
- DoGetMemoryRegionInfo(lldb::addr_t load_addr,
- lldb_private::MemoryRegionInfo &region_info) override;
-
private:
struct NT_FILE_Entry {
lldb::addr_t start;
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 4ce79da48f07..25ae08838bf8 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -81,11 +81,6 @@ GDBRemoteCommunication::~GDBRemoteCommunication() {
if (m_decompression_scratch)
free (m_decompression_scratch);
#endif
-
- // Stop the communications read thread which is used to parse all incoming
- // packets. This function will block until the read thread returns.
- if (m_read_thread_enabled)
- StopReadThread();
}
char GDBRemoteCommunication::CalculcateChecksum(llvm::StringRef payload) {
@@ -193,7 +188,7 @@ GDBRemoteCommunication::SendRawPacketNoLock(llvm::StringRef packet,
GDBRemoteCommunication::PacketResult GDBRemoteCommunication::GetAck() {
StringExtractorGDBRemote packet;
- PacketResult result = ReadPacket(packet, GetPacketTimeout(), false);
+ PacketResult result = WaitForPacketNoLock(packet, GetPacketTimeout(), false);
if (result == PacketResult::Success) {
if (packet.GetResponseType() ==
StringExtractorGDBRemote::ResponseType::eAck)
@@ -225,40 +220,18 @@ GDBRemoteCommunication::PacketResult
GDBRemoteCommunication::ReadPacket(StringExtractorGDBRemote &response,
Timeout<std::micro> timeout,
bool sync_on_timeout) {
- if (m_read_thread_enabled)
- return PopPacketFromQueue(response, timeout);
- else
- return WaitForPacketNoLock(response, timeout, sync_on_timeout);
-}
+ using ResponseType = StringExtractorGDBRemote::ResponseType;
-// This function is called when a packet is requested.
-// A whole packet is popped from the packet queue and returned to the caller.
-// Packets are placed into this queue from the communication read thread. See
-// GDBRemoteCommunication::AppendBytesToCache.
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunication::PopPacketFromQueue(StringExtractorGDBRemote &response,
- Timeout<std::micro> timeout) {
- auto pred = [&] { return !m_packet_queue.empty() && IsConnected(); };
- // lock down the packet queue
- std::unique_lock<std::mutex> lock(m_packet_queue_mutex);
-
- if (!timeout)
- m_condition_queue_not_empty.wait(lock, pred);
- else {
- if (!m_condition_queue_not_empty.wait_for(lock, *timeout, pred))
- return PacketResult::ErrorReplyTimeout;
- if (!IsConnected())
- return PacketResult::ErrorDisconnected;
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
+ for (;;) {
+ PacketResult result =
+ WaitForPacketNoLock(response, timeout, sync_on_timeout);
+ if (result != PacketResult::Success ||
+ (response.GetResponseType() != ResponseType::eAck &&
+ response.GetResponseType() != ResponseType::eNack))
+ return result;
+ LLDB_LOG(log, "discarding spurious `{0}` packet", response.GetStringRef());
}
-
- // get the front element of the queue
- response = m_packet_queue.front();
-
- // remove the front element
- m_packet_queue.pop();
-
- // we got a packet
- return PacketResult::Success;
}
GDBRemoteCommunication::PacketResult
@@ -1287,53 +1260,6 @@ GDBRemoteCommunication::ScopedTimeout::~ScopedTimeout() {
m_gdb_comm.SetPacketTimeout(m_saved_timeout);
}
-// This function is called via the Communications class read thread when bytes
-// become available for this connection. This function will consume all
-// incoming bytes and try to parse whole packets as they become available. Full
-// packets are placed in a queue, so that all packet requests can simply pop
-// from this queue. Async notification packets will be dispatched immediately
-// to the ProcessGDBRemote Async thread via an event.
-void GDBRemoteCommunication::AppendBytesToCache(const uint8_t *bytes,
- size_t len, bool broadcast,
- lldb::ConnectionStatus status) {
- StringExtractorGDBRemote packet;
-
- while (true) {
- PacketType type = CheckForPacket(bytes, len, packet);
-
- // scrub the data so we do not pass it back to CheckForPacket on future
- // passes of the loop
- bytes = nullptr;
- len = 0;
-
- // we may have received no packet so lets bail out
- if (type == PacketType::Invalid)
- break;
-
- if (type == PacketType::Standard) {
- // scope for the mutex
- {
- // lock down the packet queue
- std::lock_guard<std::mutex> guard(m_packet_queue_mutex);
- // push a new packet into the queue
- m_packet_queue.push(packet);
- // Signal condition variable that we have a packet
- m_condition_queue_not_empty.notify_one();
- }
- }
-
- if (type == PacketType::Notify) {
- // put this packet into an event
- const char *pdata = packet.GetStringRef().data();
-
- // as the communication class, we are a broadcaster and the async thread
- // is tuned to listen to us
- BroadcastEvent(eBroadcastBitGdbReadThreadGotNotify,
- new EventDataBytes(pdata));
- }
- }
-}
-
void llvm::format_provider<GDBRemoteCommunication::PacketResult>::format(
const GDBRemoteCommunication::PacketResult &result, raw_ostream &Stream,
StringRef Style) {
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index 5da568e9b4d4..afc7e740d4c9 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -84,8 +84,6 @@ class GDBRemoteCommunication : public Communication {
public:
enum {
eBroadcastBitRunPacketSent = kLoUserBroadcastBit,
- eBroadcastBitGdbReadThreadGotNotify =
- kLoUserBroadcastBit << 1 // Sent when we received a notify packet.
};
enum class PacketType { Invalid = 0, Standard, Notify };
@@ -196,10 +194,6 @@ protected:
bool sync_on_timeout,
llvm::function_ref<void(llvm::StringRef)> output_callback);
- // Pop a packet from the queue in a thread safe manner
- PacketResult PopPacketFromQueue(StringExtractorGDBRemote &response,
- Timeout<std::micro> timeout);
-
PacketResult WaitForPacketNoLock(StringExtractorGDBRemote &response,
Timeout<std::micro> timeout,
bool sync_on_timeout);
@@ -226,24 +220,7 @@ protected:
static lldb::thread_result_t ListenThread(lldb::thread_arg_t arg);
- // GDB-Remote read thread
- // . this thread constantly tries to read from the communication
- // class and stores all packets received in a queue. The usual
- // threads read requests simply pop packets off the queue in the
- // usual order.
- // This setup allows us to intercept and handle async packets, such
- // as the notify packet.
-
- // This method is defined as part of communication.h
- // when the read thread gets any bytes it will pass them on to this function
- void AppendBytesToCache(const uint8_t *bytes, size_t len, bool broadcast,
- lldb::ConnectionStatus status) override;
-
private:
- std::queue<StringExtractorGDBRemote> m_packet_queue; // The packet queue
- std::mutex m_packet_queue_mutex; // Mutex for accessing queue
- std::condition_variable
- m_condition_queue_not_empty; // Condition variable to wait for packets
// Promise used to grab the port number from listening thread
std::promise<uint16_t> m_port_promise;
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 78e722eee080..07dfa5e04ee5 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -86,13 +86,6 @@ bool GDBRemoteCommunicationClient::HandshakeWithServer(Status *error_ptr) {
std::chrono::steady_clock::time_point start_of_handshake =
std::chrono::steady_clock::now();
if (SendAck()) {
- // Wait for any responses that might have been queued up in the remote
- // GDB server and flush them all
- StringExtractorGDBRemote response;
- PacketResult packet_result = PacketResult::Success;
- while (packet_result == PacketResult::Success)
- packet_result = ReadPacket(response, milliseconds(10), false);
-
// The return value from QueryNoAckModeSupported() is true if the packet
// was sent and _any_ response (including UNIMPLEMENTED) was received), or
// false if no response was received. This quickly tells us if we have a
@@ -106,17 +99,15 @@ bool GDBRemoteCommunicationClient::HandshakeWithServer(Status *error_ptr) {
std::chrono::duration<double>(end_of_handshake - start_of_handshake)
.count();
if (error_ptr) {
- if (packet_result == PacketResult::ErrorDisconnected)
+ if (!IsConnected())
error_ptr->SetErrorString("Connection shut down by remote side "
"while waiting for reply to initial "
"handshake packet");
- else if (packet_result == PacketResult::ErrorReplyTimeout)
+ else
error_ptr->SetErrorStringWithFormat(
"failed to get reply to handshake packet within timeout of "
"%.1f seconds",
handshake_timeout);
- else
- error_ptr->SetErrorString("failed to get reply to handshake packet");
}
}
} else {
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index 11cac9fa3a4d..49d88b72b01b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -46,7 +46,7 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse(
Timeout<std::micro> timeout, Status &error, bool &interrupt, bool &quit) {
StringExtractorGDBRemote packet;
- PacketResult packet_result = WaitForPacketNoLock(packet, timeout, false);
+ PacketResult packet_result = ReadPacket(packet, timeout, false);
if (packet_result == PacketResult::Success) {
const StringExtractorGDBRemote::ServerPacketType packet_type =
packet.GetServerPacketType();
@@ -150,10 +150,6 @@ GDBRemoteCommunicationServer::SendOKResponse() {
return SendPacketNoLock("OK");
}
-bool GDBRemoteCommunicationServer::HandshakeWithClient() {
- return GetAck() == PacketResult::Success;
-}
-
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::SendJSONResponse(const json::Value &value) {
std::string json_string;
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index 68448eae2b9f..5de344061ec9 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -44,10 +44,6 @@ public:
Status &error, bool &interrupt,
bool &quit);
- // After connecting, do a little handshake with the client to make sure
- // we are at least communicating
- bool HandshakeWithClient();
-
protected:
std::map<StringExtractorGDBRemote::ServerPacketType, PacketHandler>
m_packet_handlers;
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 5360db3d8462..30f14a52dfb5 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -1088,18 +1088,6 @@ void GDBRemoteCommunicationServerLLGS::NewSubprocess(
void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() {
Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_COMM));
- if (!m_handshake_completed) {
- if (!HandshakeWithClient()) {
- LLDB_LOGF(log,
- "GDBRemoteCommunicationServerLLGS::%s handshake with "
- "client failed, exiting",
- __FUNCTION__);
- m_mainloop.RequestTermination();
- return;
- }
- m_handshake_completed = true;
- }
-
bool interrupt = false;
bool done = false;
Status error;
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index 6c75771f6427..17ee4130dc34 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -104,7 +104,6 @@ protected:
std::mutex m_saved_registers_mutex;
std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map;
uint32_t m_next_saved_registers_id = 1;
- bool m_handshake_completed = false;
bool m_thread_suffix_supported = false;
bool m_list_threads_in_stop_reply = false;
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 2233bf675819..3ade8c815feb 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -282,9 +282,7 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
__FUNCTION__);
}
- const uint32_t gdb_event_mask =
- Communication::eBroadcastBitReadThreadDidExit |
- GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify;
+ const uint32_t gdb_event_mask = Communication::eBroadcastBitReadThreadDidExit;
if (m_async_listener_sp->StartListeningForEvents(
&m_gdb_comm, gdb_event_mask) != gdb_event_mask) {
LLDB_LOGF(log,
@@ -1324,24 +1322,6 @@ Status ProcessGDBRemote::DoResume() {
return error;
}
-void ProcessGDBRemote::HandleStopReplySequence() {
- while (true) {
- // Send vStopped
- StringExtractorGDBRemote response;
- m_gdb_comm.SendPacketAndWaitForResponse("vStopped", response);
-
- // OK represents end of signal list
- if (response.IsOKResponse())
- break;
-
- // If not OK or a normal packet we have a problem
- if (!response.IsNormalResponse())
- break;
-
- SetLastStopPacket(response);
- }
-}
-
void ProcessGDBRemote::ClearThreadIDList() {
std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
m_thread_ids.clear();
@@ -2897,8 +2877,8 @@ lldb::addr_t ProcessGDBRemote::DoAllocateMemory(size_t size,
return allocated_addr;
}
-Status ProcessGDBRemote::DoGetMemoryRegionInfo(addr_t load_addr,
- MemoryRegionInfo &region_info) {
+Status ProcessGDBRemote::GetMemoryRegionInfo(addr_t load_addr,
+ MemoryRegionInfo &region_info) {
Status error(m_gdb_comm.GetMemoryRegionInfo(load_addr, region_info));
return error;
@@ -3539,31 +3519,6 @@ void ProcessGDBRemote::StopAsyncThread() {
__FUNCTION__);
}
-bool ProcessGDBRemote::HandleNotifyPacket(StringExtractorGDBRemote &packet) {
- // get the packet at a string
- const std::string &pkt = std::string(packet.GetStringRef());
- // skip %stop:
- StringExtractorGDBRemote stop_info(pkt.c_str() + 5);
-
- // pass as a thread stop info packet
- SetLastStopPacket(stop_info);
-
- // check for more stop reasons
- HandleStopReplySequence();
-
- // if the process is stopped then we need to fake a resume so that we can
- // stop properly with the new break. This is possible due to
- // SetPrivateState() broadcasting the state change as a side effect.
- if (GetPrivateState() == lldb::StateType::eStateStopped) {
- SetPrivateState(lldb::StateType::eStateRunning);
- }
-
- // since we have some stopped packets we can halt the process
- SetPrivateState(lldb::StateType::eStateStopped);
-
- return true;
-}
-
thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
ProcessGDBRemote *process = (ProcessGDBRemote *)arg;
@@ -3712,17 +3667,6 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
done = true;
break;
- case GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify: {
- lldb_private::Event *event = event_sp.get();
- const EventDataBytes *continue_packet =
- EventDataBytes::GetEventDataFromEvent(event);
- StringExtractorGDBRemote notify(
- (const char *)continue_packet->GetBytes());
- // Hand this over to the process to handle
- process->HandleNotifyPacket(notify);
- break;
- }
-
default:
LLDB_LOGF(log,
"ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 8134bc6b530d..488336b8c1b8 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -144,6 +144,9 @@ public:
lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
Status &error) override;
+ Status GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &region_info) override;
+
Status DoDeallocateMemory(lldb::addr_t ptr) override;
// Process STDIO
@@ -343,8 +346,6 @@ protected:
size_t UpdateThreadIDsFromStopReplyThreadsValue(llvm::StringRef value);
- bool HandleNotifyPacket(StringExtractorGDBRemote &packet);
-
bool StartAsyncThread();
void StopAsyncThread();
@@ -375,8 +376,6 @@ protected:
lldb::addr_t dispatch_queue_t, std::string &queue_name,
lldb::QueueKind queue_kind, uint64_t queue_serial);
- void HandleStopReplySequence();
-
void ClearThreadIDList();
bool UpdateThreadIDList();
@@ -421,9 +420,6 @@ protected:
Status DoWriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type,
const std::vector<uint8_t> &tags) override;
- Status DoGetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &region_info) override;
-
private:
// For ProcessGDBRemote only
std::string m_partial_profile_data;
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
index 736cfa070088..37ee5466c5b9 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -73,7 +73,7 @@ public:
bool IsExecutable() const override { return false; }
ArchSpec GetArchitecture() override { return m_arch; }
UUID GetUUID() override { return m_uuid; }
- Symtab *GetSymtab() override { return m_symtab_up.get(); }
+ void ParseSymtab(lldb_private::Symtab &symtab) override {}
bool IsStripped() override { return true; }
ByteOrder GetByteOrder() const override { return m_arch.GetByteOrder(); }
@@ -439,8 +439,8 @@ void ProcessMinidump::BuildMemoryRegions() {
llvm::sort(*m_memory_regions);
}
-Status ProcessMinidump::DoGetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &region) {
+Status ProcessMinidump::GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &region) {
BuildMemoryRegions();
region = MinidumpParser::GetMemoryRegionInfo(*m_memory_regions, load_addr);
return Status();
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
index 5360269199cd..3501d38a0f27 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -75,6 +75,9 @@ public:
ArchSpec GetArchitecture();
+ Status GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) override;
+
Status GetMemoryRegions(
lldb_private::MemoryRegionInfos &region_list) override;
@@ -95,9 +98,6 @@ protected:
bool DoUpdateThreadList(ThreadList &old_thread_list,
ThreadList &new_thread_list) override;
- Status DoGetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &range_info) override;
-
void ReadModuleList();
lldb::ModuleSP GetOrCreateModule(lldb_private::UUID minidump_uuid,
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
index 15d3d43d9993..c1b7294a7f58 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
+++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
@@ -248,8 +248,8 @@ ArchSpec ScriptedProcess::GetArchitecture() {
return GetTarget().GetArchitecture();
}
-Status ScriptedProcess::DoGetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &region) {
+Status ScriptedProcess::GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &region) {
CheckInterpreterAndScriptObject();
Status error;
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
index c8355f35548a..d56658a2e48a 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
+++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
@@ -84,6 +84,9 @@ public:
ArchSpec GetArchitecture();
+ Status GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) override;
+
Status
GetMemoryRegions(lldb_private::MemoryRegionInfos &region_list) override;
@@ -97,9 +100,6 @@ protected:
bool DoUpdateThreadList(ThreadList &old_thread_list,
ThreadList &new_thread_list) override;
- Status DoGetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &range_info) override;
-
private:
friend class ScriptedThread;
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
index 798d947a0a7d..c7af13598843 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
@@ -15,8 +15,12 @@
#if LLDB_ENABLE_PYTHON
+// LLDB Python header must be included first
+#include "lldb-python.h"
+
#include "lldb/lldb-forward.h"
#include "lldb/lldb-types.h"
+#include "llvm/Support/Error.h"
namespace lldb_private {
@@ -41,20 +45,148 @@ template <> const char *GetPythonValueFormatString(unsigned long long);
template <> const char *GetPythonValueFormatString(float t);
template <> const char *GetPythonValueFormatString(double t);
-extern "C" void *LLDBSwigPythonCreateScriptedProcess(
+void *LLDBSWIGPython_CastPyObjectToSBData(PyObject *data);
+void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data);
+void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data);
+void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data);
+
+// These prototypes are the Pythonic implementations of the required callbacks.
+// Although these are scripting-language specific, their definition depends on
+// the public API.
+
+void *LLDBSwigPythonCreateScriptedProcess(const char *python_class_name,
+ const char *session_dictionary_name,
+ const lldb::TargetSP &target_sp,
+ StructuredDataImpl *args_impl,
+ std::string &error_string);
+
+void *LLDBSwigPythonCreateScriptedThread(const char *python_class_name,
+ const char *session_dictionary_name,
+ const lldb::ProcessSP &process_sp,
+ StructuredDataImpl *args_impl,
+ std::string &error_string);
+
+llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction(
+ const char *python_function_name, const char *session_dictionary_name,
+ const lldb::StackFrameSP &sb_frame,
+ const lldb::BreakpointLocationSP &sb_bp_loc,
+ lldb_private::StructuredDataImpl *args_impl);
+
+bool LLDBSwigPythonWatchpointCallbackFunction(
+ const char *python_function_name, const char *session_dictionary_name,
+ const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp);
+
+bool LLDBSwigPythonCallTypeScript(const char *python_function_name,
+ const void *session_dictionary,
+ const lldb::ValueObjectSP &valobj_sp,
+ void **pyfunct_wrapper,
+ const lldb::TypeSummaryOptionsSP &options_sp,
+ std::string &retval);
+
+void *
+LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name,
+ const char *session_dictionary_name,
+ const lldb::ValueObjectSP &valobj_sp);
+
+void *LLDBSwigPythonCreateCommandObject(const char *python_class_name,
+ const char *session_dictionary_name,
+ const lldb::DebuggerSP debugger_sp);
+
+void *LLDBSwigPythonCreateScriptedThreadPlan(
const char *python_class_name, const char *session_dictionary_name,
- const lldb::TargetSP &target_sp, StructuredDataImpl *args_impl,
- std::string &error_string);
+ lldb_private::StructuredDataImpl *args_data, std::string &error_string,
+ const lldb::ThreadPlanSP &thread_plan_sp);
-extern "C" void *LLDBSwigPythonCreateScriptedThread(
+bool LLDBSWIGPythonCallThreadPlan(void *implementor, const char *method_name,
+ lldb_private::Event *event_sp,
+ bool &got_error);
+
+void *LLDBSwigPythonCreateScriptedBreakpointResolver(
const char *python_class_name, const char *session_dictionary_name,
- const lldb::ProcessSP &process_sp, StructuredDataImpl *args_impl,
- std::string &error_string);
+ lldb_private::StructuredDataImpl *args, const lldb::BreakpointSP &bkpt_sp);
+
+unsigned int
+LLDBSwigPythonCallBreakpointResolver(void *implementor, const char *method_name,
+ lldb_private::SymbolContext *sym_ctx);
+
+void *LLDBSwigPythonCreateScriptedStopHook(
+ lldb::TargetSP target_sp, const char *python_class_name,
+ const char *session_dictionary_name, lldb_private::StructuredDataImpl *args,
+ lldb_private::Status &error);
+
+bool LLDBSwigPythonStopHookCallHandleStop(void *implementor,
+ lldb::ExecutionContextRefSP exc_ctx,
+ lldb::StreamSP stream);
+
+size_t LLDBSwigPython_CalculateNumChildren(PyObject *implementor, uint32_t max);
+
+PyObject *LLDBSwigPython_GetChildAtIndex(PyObject *implementor, uint32_t idx);
+
+int LLDBSwigPython_GetIndexOfChildWithName(PyObject *implementor,
+ const char *child_name);
+
+lldb::ValueObjectSP LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data);
+
+bool LLDBSwigPython_UpdateSynthProviderInstance(PyObject *implementor);
+
+bool LLDBSwigPython_MightHaveChildrenSynthProviderInstance(
+ PyObject *implementor);
+
+PyObject *LLDBSwigPython_GetValueSynthProviderInstance(PyObject *implementor);
+
+bool LLDBSwigPythonCallCommand(const char *python_function_name,
+ const char *session_dictionary_name,
+ lldb::DebuggerSP &debugger, const char *args,
+ lldb_private::CommandReturnObject &cmd_retobj,
+ lldb::ExecutionContextRefSP exe_ctx_ref_sp);
+
+bool LLDBSwigPythonCallCommandObject(
+ PyObject *implementor, lldb::DebuggerSP &debugger, const char *args,
+ lldb_private::CommandReturnObject &cmd_retobj,
+ lldb::ExecutionContextRefSP exe_ctx_ref_sp);
+
+bool LLDBSwigPythonCallModuleInit(const char *python_module_name,
+ const char *session_dictionary_name,
+ lldb::DebuggerSP &debugger);
+
+void *LLDBSWIGPythonCreateOSPlugin(const char *python_class_name,
+ const char *session_dictionary_name,
+ const lldb::ProcessSP &process_sp);
+
+void *LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name,
+ const char *session_dictionary_name);
+
+PyObject *
+LLDBSwigPython_GetRecognizedArguments(PyObject *implementor,
+ const lldb::StackFrameSP &frame_sp);
+
+bool LLDBSWIGPythonRunScriptKeywordProcess(const char *python_function_name,
+ const char *session_dictionary_name,
+ const lldb::ProcessSP &process,
+ std::string &output);
+
+bool LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name,
+ const char *session_dictionary_name,
+ lldb::ThreadSP &thread,
+ std::string &output);
+
+bool LLDBSWIGPythonRunScriptKeywordTarget(const char *python_function_name,
+ const char *session_dictionary_name,
+ const lldb::TargetSP &target,
+ std::string &output);
+
+bool LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name,
+ const char *session_dictionary_name,
+ lldb::StackFrameSP &frame,
+ std::string &output);
+
+bool LLDBSWIGPythonRunScriptKeywordValue(const char *python_function_name,
+ const char *session_dictionary_name,
+ const lldb::ValueObjectSP &value,
+ std::string &output);
-extern "C" void *LLDBSWIGPython_CastPyObjectToSBData(void *data);
-extern "C" void *LLDBSWIGPython_CastPyObjectToSBError(void *data);
-extern "C" void *LLDBSWIGPython_CastPyObjectToSBValue(void *data);
-extern "C" void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(void *data);
+void *LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting,
+ const lldb::TargetSP &target_sp);
} // namespace lldb_private
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index c1f4c2d3b4d3..5f282d74e364 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -70,153 +70,6 @@ extern "C" void init_lldb(void);
#define LLDBSwigPyInit init_lldb
#endif
-// These prototypes are the Pythonic implementations of the required callbacks.
-// Although these are scripting-language specific, their definition depends on
-// the public API.
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
-
-// Disable warning C4190: 'LLDBSwigPythonBreakpointCallbackFunction' has
-// C-linkage specified, but returns UDT 'llvm::Expected<bool>' which is
-// incompatible with C
-#if _MSC_VER
-#pragma warning (push)
-#pragma warning (disable : 4190)
-#endif
-
-extern "C" llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction(
- const char *python_function_name, const char *session_dictionary_name,
- const lldb::StackFrameSP &sb_frame,
- const lldb::BreakpointLocationSP &sb_bp_loc, StructuredDataImpl *args_impl);
-
-#if _MSC_VER
-#pragma warning (pop)
-#endif
-
-#pragma clang diagnostic pop
-
-extern "C" bool LLDBSwigPythonWatchpointCallbackFunction(
- const char *python_function_name, const char *session_dictionary_name,
- const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp);
-
-extern "C" bool LLDBSwigPythonCallTypeScript(
- const char *python_function_name, void *session_dictionary,
- const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper,
- const lldb::TypeSummaryOptionsSP &options_sp, std::string &retval);
-
-extern "C" void *
-LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name,
- const char *session_dictionary_name,
- const lldb::ValueObjectSP &valobj_sp);
-
-extern "C" void *
-LLDBSwigPythonCreateCommandObject(const char *python_class_name,
- const char *session_dictionary_name,
- const lldb::DebuggerSP debugger_sp);
-
-extern "C" void *LLDBSwigPythonCreateScriptedThreadPlan(
- const char *python_class_name, const char *session_dictionary_name,
- StructuredDataImpl *args_data,
- std::string &error_string,
- const lldb::ThreadPlanSP &thread_plan_sp);
-
-extern "C" bool LLDBSWIGPythonCallThreadPlan(void *implementor,
- const char *method_name,
- Event *event_sp, bool &got_error);
-
-extern "C" void *LLDBSwigPythonCreateScriptedBreakpointResolver(
- const char *python_class_name, const char *session_dictionary_name,
- lldb_private::StructuredDataImpl *args, lldb::BreakpointSP &bkpt_sp);
-
-extern "C" unsigned int
-LLDBSwigPythonCallBreakpointResolver(void *implementor, const char *method_name,
- lldb_private::SymbolContext *sym_ctx);
-
-extern "C" void *LLDBSwigPythonCreateScriptedStopHook(
- TargetSP target_sp, const char *python_class_name,
- const char *session_dictionary_name, lldb_private::StructuredDataImpl *args,
- lldb_private::Status &error);
-
-extern "C" bool
-LLDBSwigPythonStopHookCallHandleStop(void *implementor,
- lldb::ExecutionContextRefSP exc_ctx,
- lldb::StreamSP stream);
-
-extern "C" size_t LLDBSwigPython_CalculateNumChildren(void *implementor,
- uint32_t max);
-
-extern "C" void *LLDBSwigPython_GetChildAtIndex(void *implementor,
- uint32_t idx);
-
-extern "C" int LLDBSwigPython_GetIndexOfChildWithName(void *implementor,
- const char *child_name);
-
-extern lldb::ValueObjectSP
-LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data);
-
-extern "C" bool LLDBSwigPython_UpdateSynthProviderInstance(void *implementor);
-
-extern "C" bool
-LLDBSwigPython_MightHaveChildrenSynthProviderInstance(void *implementor);
-
-extern "C" void *
-LLDBSwigPython_GetValueSynthProviderInstance(void *implementor);
-
-extern "C" bool
-LLDBSwigPythonCallCommand(const char *python_function_name,
- const char *session_dictionary_name,
- lldb::DebuggerSP &debugger, const char *args,
- lldb_private::CommandReturnObject &cmd_retobj,
- lldb::ExecutionContextRefSP exe_ctx_ref_sp);
-
-extern "C" bool
-LLDBSwigPythonCallCommandObject(void *implementor, lldb::DebuggerSP &debugger,
- const char *args,
- lldb_private::CommandReturnObject &cmd_retobj,
- lldb::ExecutionContextRefSP exe_ctx_ref_sp);
-
-extern "C" bool
-LLDBSwigPythonCallModuleInit(const char *python_module_name,
- const char *session_dictionary_name,
- lldb::DebuggerSP &debugger);
-
-extern "C" void *
-LLDBSWIGPythonCreateOSPlugin(const char *python_class_name,
- const char *session_dictionary_name,
- const lldb::ProcessSP &process_sp);
-
-extern "C" void *
-LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name,
- const char *session_dictionary_name);
-
-extern "C" void *
-LLDBSwigPython_GetRecognizedArguments(void *implementor,
- const lldb::StackFrameSP &frame_sp);
-
-extern "C" bool LLDBSWIGPythonRunScriptKeywordProcess(
- const char *python_function_name, const char *session_dictionary_name,
- lldb::ProcessSP &process, std::string &output);
-
-extern "C" bool LLDBSWIGPythonRunScriptKeywordThread(
- const char *python_function_name, const char *session_dictionary_name,
- lldb::ThreadSP &thread, std::string &output);
-
-extern "C" bool LLDBSWIGPythonRunScriptKeywordTarget(
- const char *python_function_name, const char *session_dictionary_name,
- lldb::TargetSP &target, std::string &output);
-
-extern "C" bool LLDBSWIGPythonRunScriptKeywordFrame(
- const char *python_function_name, const char *session_dictionary_name,
- lldb::StackFrameSP &frame, std::string &output);
-
-extern "C" bool LLDBSWIGPythonRunScriptKeywordValue(
- const char *python_function_name, const char *session_dictionary_name,
- lldb::ValueObjectSP &value, std::string &output);
-
-extern "C" void *
-LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting,
- const lldb::TargetSP &target_sp);
static ScriptInterpreterPythonImpl *GetPythonInterpreter(Debugger &debugger) {
ScriptInterpreter *script_interpreter =
@@ -1591,9 +1444,9 @@ lldb::ValueObjectListSP ScriptInterpreterPythonImpl::GetRecognizedArguments(
if (!implementor.IsAllocated())
return ValueObjectListSP();
- PythonObject py_return(PyRefType::Owned,
- (PyObject *)LLDBSwigPython_GetRecognizedArguments(
- implementor.get(), frame_sp));
+ PythonObject py_return(
+ PyRefType::Owned,
+ LLDBSwigPython_GetRecognizedArguments(implementor.get(), frame_sp));
// if it fails, print the error but otherwise go on
if (PyErr_Occurred()) {
@@ -2423,7 +2276,7 @@ size_t ScriptInterpreterPythonImpl::CalculateNumChildren(
StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
if (!generic)
return 0;
- void *implementor = generic->GetValue();
+ auto *implementor = static_cast<PyObject *>(generic->GetValue());
if (!implementor)
return 0;
@@ -2446,7 +2299,7 @@ lldb::ValueObjectSP ScriptInterpreterPythonImpl::GetChildAtIndex(
StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
if (!generic)
return lldb::ValueObjectSP();
- void *implementor = generic->GetValue();
+ auto *implementor = static_cast<PyObject *>(generic->GetValue());
if (!implementor)
return lldb::ValueObjectSP();
@@ -2454,7 +2307,7 @@ lldb::ValueObjectSP ScriptInterpreterPythonImpl::GetChildAtIndex(
{
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- void *child_ptr = LLDBSwigPython_GetChildAtIndex(implementor, idx);
+ PyObject *child_ptr = LLDBSwigPython_GetChildAtIndex(implementor, idx);
if (child_ptr != nullptr && child_ptr != Py_None) {
lldb::SBValue *sb_value_ptr =
(lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(child_ptr);
@@ -2478,7 +2331,7 @@ int ScriptInterpreterPythonImpl::GetIndexOfChildWithName(
StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
if (!generic)
return UINT32_MAX;
- void *implementor = generic->GetValue();
+ auto *implementor = static_cast<PyObject *>(generic->GetValue());
if (!implementor)
return UINT32_MAX;
@@ -2503,7 +2356,7 @@ bool ScriptInterpreterPythonImpl::UpdateSynthProviderInstance(
StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
if (!generic)
return ret_val;
- void *implementor = generic->GetValue();
+ auto *implementor = static_cast<PyObject *>(generic->GetValue());
if (!implementor)
return ret_val;
@@ -2526,7 +2379,7 @@ bool ScriptInterpreterPythonImpl::MightHaveChildrenSynthProviderInstance(
StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
if (!generic)
return ret_val;
- void *implementor = generic->GetValue();
+ auto *implementor = static_cast<PyObject *>(generic->GetValue());
if (!implementor)
return ret_val;
@@ -2550,14 +2403,15 @@ lldb::ValueObjectSP ScriptInterpreterPythonImpl::GetSyntheticValue(
StructuredData::Generic *generic = implementor_sp->GetAsGeneric();
if (!generic)
return ret_val;
- void *implementor = generic->GetValue();
+ auto *implementor = static_cast<PyObject *>(generic->GetValue());
if (!implementor)
return ret_val;
{
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- void *child_ptr = LLDBSwigPython_GetValueSynthProviderInstance(implementor);
+ PyObject *child_ptr =
+ LLDBSwigPython_GetValueSynthProviderInstance(implementor);
if (child_ptr != nullptr && child_ptr != Py_None) {
lldb::SBValue *sb_value_ptr =
(lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(child_ptr);
@@ -2653,11 +2507,11 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
}
{
- ProcessSP process_sp(process->shared_from_this());
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
ret_val = LLDBSWIGPythonRunScriptKeywordProcess(
- impl_function, m_dictionary_name.c_str(), process_sp, output);
+ impl_function, m_dictionary_name.c_str(), process->shared_from_this(),
+ output);
if (!ret_val)
error.SetErrorString("python script evaluation failed");
}
@@ -2753,11 +2607,10 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword(
}
{
- ValueObjectSP value_sp(value->GetSP());
Locker py_lock(this,
Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
ret_val = LLDBSWIGPythonRunScriptKeywordValue(
- impl_function, m_dictionary_name.c_str(), value_sp, output);
+ impl_function, m_dictionary_name.c_str(), value->GetSP(), output);
if (!ret_val)
error.SetErrorString("python script evaluation failed");
}
@@ -3076,9 +2929,9 @@ bool ScriptInterpreterPythonImpl::RunScriptBasedCommand(
SynchronicityHandler synch_handler(debugger_sp, synchronicity);
std::string args_str = args.str();
- ret_val = LLDBSwigPythonCallCommandObject(impl_obj_sp->GetValue(),
- debugger_sp, args_str.c_str(),
- cmd_retobj, exe_ctx_ref_sp);
+ ret_val = LLDBSwigPythonCallCommandObject(
+ static_cast<PyObject *>(impl_obj_sp->GetValue()), debugger_sp,
+ args_str.c_str(), cmd_retobj, exe_ctx_ref_sp);
}
if (!ret_val)
diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
index b07674af3bd9..9d23f1baf931 100644
--- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
+++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
@@ -500,7 +500,7 @@ void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
for (Symbol &symbol : symbols)
symtab.AddSymbol(std::move(symbol));
- symtab.CalculateSymbolSizes();
+ symtab.Finalize();
}
llvm::Expected<lldb::addr_t>
@@ -927,4 +927,3 @@ uint64_t SymbolFileBreakpad::GetDebugInfoSize() {
// Breakpad files are all debug info.
return m_objfile_sp->GetByteSize();
}
-
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 2dd7ae60b231..8c20244a6c44 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2067,6 +2067,13 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(
}
void SymbolFileDWARF::PreloadSymbols() {
+ // Get the symbol table for the symbol file prior to taking the module lock
+ // so that it is available without needing to take the module lock. The DWARF
+ // indexing might end up needing to relocate items when DWARF sections are
+ // loaded as they might end up getting the section contents which can call
+ // ObjectFileELF::RelocateSection() which in turn will ask for the symbol
+ // table and can cause deadlocks.
+ GetSymtab();
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
m_index->Preload();
}
@@ -3271,15 +3278,14 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
}
const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die);
- const dw_tag_t parent_tag = die.GetParent().Tag();
+ const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
+ const dw_tag_t parent_tag = sc_parent_die.Tag();
bool is_static_member = (parent_tag == DW_TAG_compile_unit ||
parent_tag == DW_TAG_partial_unit) &&
(parent_context_die.Tag() == DW_TAG_class_type ||
parent_context_die.Tag() == DW_TAG_structure_type);
ValueType scope = eValueTypeInvalid;
-
- const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die);
SymbolContextScope *symbol_context_scope = nullptr;
bool has_explicit_mangled = mangled != nullptr;
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 8af90cb66e87..bf101ac1acf1 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -1182,8 +1182,9 @@ void SymbolFileNativePDB::FindFunctions(
FunctionNameType name_type_mask, bool include_inlines,
SymbolContextList &sc_list) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- // For now we only support lookup by method name.
- if (!(name_type_mask & eFunctionNameTypeMethod))
+ // For now we only support lookup by method name or full name.
+ if (!(name_type_mask & eFunctionNameTypeFull ||
+ name_type_mask & eFunctionNameTypeMethod))
return;
using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index 45dfc4b9a152..db0ae241be7e 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -1421,7 +1421,6 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
));
}
- symtab.CalculateSymbolSizes();
symtab.Finalize();
}
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index b20ae32a08ac..b1dbc382ff04 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -91,7 +91,7 @@ static void VerifyDecl(clang::Decl *decl) {
assert(decl && "VerifyDecl called with nullptr?");
#ifndef NDEBUG
// We don't care about the actual access value here but only want to trigger
- // that Clang calls its internal Decl::AccessDeclContextSanity check.
+ // that Clang calls its internal Decl::AccessDeclContextCheck validation.
decl->getAccess();
#endif
}