[Lldb-commits] [lldb] [lldb][progress] Add discrete boolean flag to progress reports (PR #69516)
Chelsea Cassanova via lldb-commits
lldb-commits at lists.llvm.org
Thu Nov 30 11:31:25 PST 2023
https://github.com/chelcassanova updated https://github.com/llvm/llvm-project/pull/69516
>From 83ca6c8e94ded4378b4c0cd067aaeca1d92719d0 Mon Sep 17 00:00:00 2001
From: Chelsea Cassanova <chelsea_cassanova at apple.com>
Date: Wed, 18 Oct 2023 13:07:51 -0700
Subject: [PATCH] [lldb][progress] Add discrete boolean flag to progress
reports
This commit adds a boolean flag `is_discrete` is to progress reports in
LLDB. The flag is set to false by default and indicates if a progress event is discrete, i.e. an
operation that has no clear start and end and can happen multiple times
during the course of a debug session. Operations that happen
in this manner will report multiple individual progress events as they
happen, so this flag gives the functionality to group multiple progress
events so they can be reported in a less haphazard manner.
---
lldb/include/lldb/Core/Debugger.h | 8 +-
lldb/include/lldb/Core/DebuggerEvents.h | 11 +-
lldb/include/lldb/Core/Progress.h | 28 +-
lldb/source/Core/Debugger.cpp | 17 +-
lldb/source/Core/DebuggerEvents.cpp | 1 +
lldb/source/Core/Progress.cpp | 9 +-
.../ObjectFile/Mach-O/ObjectFileMachO.cpp | 835 +++++++++---------
.../SymbolFile/DWARF/ManualDWARFIndex.cpp | 2 +-
.../SymbolFile/DWARF/SymbolFileDWARF.cpp | 6 +-
.../TestProgressReporting.py | 13 +-
10 files changed, 503 insertions(+), 427 deletions(-)
diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h
index e4ee94809cf1a09..395ac09a965e05b 100644
--- a/lldb/include/lldb/Core/Debugger.h
+++ b/lldb/include/lldb/Core/Debugger.h
@@ -618,10 +618,16 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
/// debugger identifier that this progress should be delivered to. If this
/// optional parameter does not have a value, the progress will be
/// delivered to all debuggers.
+ ///
+ /// \param [in] report_type
+ /// Indicates whether the operation for which this progress reporting is
+ /// reporting on will happen as an aggregate of multiple individual
+ /// progress reports or not.
static void ReportProgress(uint64_t progress_id, std::string title,
std::string details, uint64_t completed,
uint64_t total,
- std::optional<lldb::user_id_t> debugger_id);
+ std::optional<lldb::user_id_t> debugger_id,
+ Progress::ProgressReportType report_type);
static void ReportDiagnosticImpl(DiagnosticEventData::Type type,
std::string message,
diff --git a/lldb/include/lldb/Core/DebuggerEvents.h b/lldb/include/lldb/Core/DebuggerEvents.h
index 982b22229701f89..dc933c47dcf53f0 100644
--- a/lldb/include/lldb/Core/DebuggerEvents.h
+++ b/lldb/include/lldb/Core/DebuggerEvents.h
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/Progress.h"
#include "lldb/Utility/Event.h"
#include "lldb/Utility/StructuredData.h"
@@ -21,10 +22,11 @@ class Stream;
class ProgressEventData : public EventData {
public:
ProgressEventData(uint64_t progress_id, std::string title, std::string update,
- uint64_t completed, uint64_t total, bool debugger_specific)
+ uint64_t completed, uint64_t total, bool debugger_specific,
+ Progress::ProgressReportType report_type)
: m_title(std::move(title)), m_details(std::move(update)),
m_id(progress_id), m_completed(completed), m_total(total),
- m_debugger_specific(debugger_specific) {}
+ m_debugger_specific(debugger_specific), m_report_type(report_type) {}
static llvm::StringRef GetFlavorString();
@@ -52,6 +54,10 @@ class ProgressEventData : public EventData {
const std::string &GetTitle() const { return m_title; }
const std::string &GetDetails() const { return m_details; }
bool IsDebuggerSpecific() const { return m_debugger_specific; }
+ bool IsAggregate() const {
+ return m_report_type ==
+ Progress::ProgressReportType::eAggregateProgressReport;
+ }
private:
/// The title of this progress event. The value is expected to remain stable
@@ -68,6 +74,7 @@ class ProgressEventData : public EventData {
uint64_t m_completed;
const uint64_t m_total;
const bool m_debugger_specific;
+ const Progress::ProgressReportType m_report_type;
ProgressEventData(const ProgressEventData &) = delete;
const ProgressEventData &operator=(const ProgressEventData &) = delete;
};
diff --git a/lldb/include/lldb/Core/Progress.h b/lldb/include/lldb/Core/Progress.h
index b2b8781a43b0591..41343ce890ed887 100644
--- a/lldb/include/lldb/Core/Progress.h
+++ b/lldb/include/lldb/Core/Progress.h
@@ -55,6 +55,11 @@ namespace lldb_private {
class Progress {
public:
+ /// Enum that indicates the type of progress report
+ enum class ProgressReportType {
+ eAggregateProgressReport,
+ eNonAggregateProgressReport
+ };
/// Construct a progress object that will report information.
///
/// The constructor will create a unique progress reporting object and
@@ -63,13 +68,30 @@ class Progress {
///
/// @param [in] title The title of this progress activity.
///
+ /// @param [in] report_type Enum value indicating how the progress is being
+ /// reported. Progress reports considered "aggregate" are reports done for
+ /// operations that may happen multiple times during a debug session.
+ ///
+ /// For example, when a debug session is first started it needs to parse the
+ /// symbol tables for all files that were initially included and this
+ /// operation will deliver progress reports. If new dSYMs are added later
+ /// during the session then these will also be parsed and deliver more
+ /// progress reports. This type of operation would use the
+ /// eAggregateProgressReport enum. Using this enum would allow these progress
+ /// reports to be grouped together as one, even though their reports are
+ /// happening individually.
+ ///
/// @param [in] total The total units of work to be done if specified, if
/// set to UINT64_MAX then an indeterminate progress indicator should be
/// displayed.
///
/// @param [in] debugger An optional debugger pointer to specify that this
/// progress is to be reported only to specific debuggers.
- Progress(std::string title, uint64_t total = UINT64_MAX,
+ ///
+ Progress(std::string title,
+ ProgressReportType report_type =
+ ProgressReportType::eNonAggregateProgressReport,
+ uint64_t total = UINT64_MAX,
lldb_private::Debugger *debugger = nullptr);
/// Destroy the progress object.
@@ -97,6 +119,10 @@ class Progress {
/// The title of the progress activity.
std::string m_title;
std::mutex m_mutex;
+ /// Set to true if the progress event is aggregate; meaning it will happen
+ /// multiple times during a debug session as individual progress events
+ ProgressReportType m_report_type =
+ ProgressReportType::eNonAggregateProgressReport;
/// A unique integer identifier for progress reporting.
const uint64_t m_id;
/// How much work ([0...m_total]) that has been completed.
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index 21f71e449ca5ed0..e53bd264b334f00 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -15,6 +15,7 @@
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
#include "lldb/Core/StreamAsynchronousIO.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Expression/REPL.h"
@@ -1421,22 +1422,24 @@ void Debugger::SetDestroyCallback(
static void PrivateReportProgress(Debugger &debugger, uint64_t progress_id,
std::string title, std::string details,
uint64_t completed, uint64_t total,
- bool is_debugger_specific) {
+ bool is_debugger_specific,
+ Progress::ProgressReportType report_type) {
// Only deliver progress events if we have any progress listeners.
const uint32_t event_type = Debugger::eBroadcastBitProgress;
if (!debugger.GetBroadcaster().EventTypeHasListeners(event_type))
return;
EventSP event_sp(new Event(
- event_type,
- new ProgressEventData(progress_id, std::move(title), std::move(details),
- completed, total, is_debugger_specific)));
+ event_type, new ProgressEventData(progress_id, std::move(title),
+ std::move(details), completed, total,
+ is_debugger_specific, report_type)));
debugger.GetBroadcaster().BroadcastEvent(event_sp);
}
void Debugger::ReportProgress(uint64_t progress_id, std::string title,
std::string details, uint64_t completed,
uint64_t total,
- std::optional<lldb::user_id_t> debugger_id) {
+ std::optional<lldb::user_id_t> debugger_id,
+ Progress::ProgressReportType report_type) {
// Check if this progress is for a specific debugger.
if (debugger_id) {
// It is debugger specific, grab it and deliver the event if the debugger
@@ -1445,7 +1448,7 @@ void Debugger::ReportProgress(uint64_t progress_id, std::string title,
if (debugger_sp)
PrivateReportProgress(*debugger_sp, progress_id, std::move(title),
std::move(details), completed, total,
- /*is_debugger_specific*/ true);
+ /*is_debugger_specific*/ true, report_type);
return;
}
// The progress event is not debugger specific, iterate over all debuggers
@@ -1455,7 +1458,7 @@ void Debugger::ReportProgress(uint64_t progress_id, std::string title,
DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos)
PrivateReportProgress(*(*pos), progress_id, title, details, completed,
- total, /*is_debugger_specific*/ false);
+ total, /*is_debugger_specific*/ false, report_type);
}
}
diff --git a/lldb/source/Core/DebuggerEvents.cpp b/lldb/source/Core/DebuggerEvents.cpp
index dd77fff349a64a7..73797bc668a395f 100644
--- a/lldb/source/Core/DebuggerEvents.cpp
+++ b/lldb/source/Core/DebuggerEvents.cpp
@@ -67,6 +67,7 @@ ProgressEventData::GetAsStructuredData(const Event *event_ptr) {
dictionary_sp->AddIntegerItem("total", progress_data->GetTotal());
dictionary_sp->AddBooleanItem("debugger_specific",
progress_data->IsDebuggerSpecific());
+ dictionary_sp->AddBooleanItem("is_aggregate", progress_data->IsAggregate());
return dictionary_sp;
}
diff --git a/lldb/source/Core/Progress.cpp b/lldb/source/Core/Progress.cpp
index ea3f874916a999f..f4e4fde9d43ddfa 100644
--- a/lldb/source/Core/Progress.cpp
+++ b/lldb/source/Core/Progress.cpp
@@ -16,9 +16,10 @@ using namespace lldb_private;
std::atomic<uint64_t> Progress::g_id(0);
-Progress::Progress(std::string title, uint64_t total,
- lldb_private::Debugger *debugger)
- : m_title(title), m_id(++g_id), m_completed(0), m_total(total) {
+Progress::Progress(std::string title, ProgressReportType report_type,
+ uint64_t total, lldb_private::Debugger *debugger)
+ : m_title(title), m_report_type(report_type), m_id(++g_id), m_completed(0),
+ m_total(total) {
assert(total > 0);
if (debugger)
m_debugger_id = debugger->GetID();
@@ -54,6 +55,6 @@ void Progress::ReportProgress(std::string update) {
// complete.
m_complete = m_completed == m_total;
Debugger::ReportProgress(m_id, m_title, std::move(update), m_completed,
- m_total, m_debugger_id);
+ m_total, m_debugger_id, m_report_type);
}
}
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 24f3939a8f2ba5a..38dccf0b2aeef4d 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -55,9 +55,9 @@
#include <TargetConditionals.h>
// GetLLDBSharedCacheUUID() needs to call dlsym()
#include <dlfcn.h>
+#include <lldb/Host/SafeMachO.h>
#include <mach/mach_init.h>
#include <mach/vm_map.h>
-#include <lldb/Host/SafeMachO.h>
#endif
#ifndef __APPLE__
@@ -1451,7 +1451,8 @@ static lldb::SectionType GetSectionType(uint32_t flags,
static ConstString g_sect_name_dwarf_debug_line_str("__debug_line_str");
static ConstString g_sect_name_dwarf_debug_loc("__debug_loc");
static ConstString g_sect_name_dwarf_debug_loclists("__debug_loclists");
- static ConstString g_sect_name_dwarf_debug_loclists_dwo("__debug_loclists.dwo");
+ static ConstString g_sect_name_dwarf_debug_loclists_dwo(
+ "__debug_loclists.dwo");
static ConstString g_sect_name_dwarf_debug_macinfo("__debug_macinfo");
static ConstString g_sect_name_dwarf_debug_macro("__debug_macro");
static ConstString g_sect_name_dwarf_debug_macro_dwo("__debug_macro.dwo");
@@ -1463,7 +1464,8 @@ static lldb::SectionType GetSectionType(uint32_t flags,
static ConstString g_sect_name_dwarf_debug_str("__debug_str");
static ConstString g_sect_name_dwarf_debug_str_dwo("__debug_str.dwo");
static ConstString g_sect_name_dwarf_debug_str_offs("__debug_str_offs");
- static ConstString g_sect_name_dwarf_debug_str_offs_dwo("__debug_str_offs.dwo");
+ static ConstString g_sect_name_dwarf_debug_str_offs_dwo(
+ "__debug_str_offs.dwo");
static ConstString g_sect_name_dwarf_debug_tu_index("__debug_tu_index");
static ConstString g_sect_name_dwarf_debug_types("__debug_types");
static ConstString g_sect_name_dwarf_apple_names("__apple_names");
@@ -1973,7 +1975,8 @@ class MachSymtabSectionInfo {
std::string filename = "<unknown>";
SectionSP first_section_sp(m_section_list->GetSectionAtIndex(0));
if (first_section_sp)
- filename = first_section_sp->GetObjectFile()->GetFileSpec().GetPath();
+ filename =
+ first_section_sp->GetObjectFile()->GetFileSpec().GetPath();
Debugger::ReportError(
llvm::formatv("unable to find section {0} for a symbol in "
@@ -2228,9 +2231,11 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
Progress progress(llvm::formatv("Parsing symbol table for {0}", file_name));
llvm::MachO::symtab_command symtab_load_command = {0, 0, 0, 0, 0, 0};
- llvm::MachO::linkedit_data_command function_starts_load_command = {0, 0, 0, 0};
+ llvm::MachO::linkedit_data_command function_starts_load_command = {0, 0, 0,
+ 0};
llvm::MachO::linkedit_data_command exports_trie_load_command = {0, 0, 0, 0};
- llvm::MachO::dyld_info_command dyld_info = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ llvm::MachO::dyld_info_command dyld_info = {0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0};
llvm::MachO::dysymtab_command dysymtab = m_dysymtab;
// The data element of type bool indicates that this entry is thumb
// code.
@@ -2400,45 +2405,44 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
strtab_addr = linkedit_load_addr + symtab_load_command.stroff -
linkedit_file_offset;
- // Always load dyld - the dynamic linker - from memory if we didn't
- // find a binary anywhere else. lldb will not register
- // dylib/framework/bundle loads/unloads if we don't have the dyld
- // symbols, we force dyld to load from memory despite the user's
- // target.memory-module-load-level setting.
- if (memory_module_load_level == eMemoryModuleLoadLevelComplete ||
- m_header.filetype == llvm::MachO::MH_DYLINKER) {
- DataBufferSP nlist_data_sp(
- ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
- if (nlist_data_sp)
- nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
- if (dysymtab.nindirectsyms != 0) {
- const addr_t indirect_syms_addr = linkedit_load_addr +
- dysymtab.indirectsymoff -
- linkedit_file_offset;
- DataBufferSP indirect_syms_data_sp(ReadMemory(
- process_sp, indirect_syms_addr, dysymtab.nindirectsyms * 4));
- if (indirect_syms_data_sp)
- indirect_symbol_index_data.SetData(
- indirect_syms_data_sp, 0,
- indirect_syms_data_sp->GetByteSize());
- // If this binary is outside the shared cache,
- // cache the string table.
- // Binaries in the shared cache all share a giant string table,
- // and we can't share the string tables across multiple
- // ObjectFileMachO's, so we'd end up re-reading this mega-strtab
- // for every binary in the shared cache - it would be a big perf
- // problem. For binaries outside the shared cache, it's faster to
- // read the entire strtab at once instead of piece-by-piece as we
- // process the nlist records.
- if (!is_shared_cache_image) {
- DataBufferSP strtab_data_sp(
- ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
- if (strtab_data_sp) {
- strtab_data.SetData(strtab_data_sp, 0,
- strtab_data_sp->GetByteSize());
- }
+ // Always load dyld - the dynamic linker - from memory if we didn't
+ // find a binary anywhere else. lldb will not register
+ // dylib/framework/bundle loads/unloads if we don't have the dyld
+ // symbols, we force dyld to load from memory despite the user's
+ // target.memory-module-load-level setting.
+ if (memory_module_load_level == eMemoryModuleLoadLevelComplete ||
+ m_header.filetype == llvm::MachO::MH_DYLINKER) {
+ DataBufferSP nlist_data_sp(
+ ReadMemory(process_sp, symoff_addr, nlist_data_byte_size));
+ if (nlist_data_sp)
+ nlist_data.SetData(nlist_data_sp, 0, nlist_data_sp->GetByteSize());
+ if (dysymtab.nindirectsyms != 0) {
+ const addr_t indirect_syms_addr = linkedit_load_addr +
+ dysymtab.indirectsymoff -
+ linkedit_file_offset;
+ DataBufferSP indirect_syms_data_sp(ReadMemory(
+ process_sp, indirect_syms_addr, dysymtab.nindirectsyms * 4));
+ if (indirect_syms_data_sp)
+ indirect_symbol_index_data.SetData(
+ indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
+ // If this binary is outside the shared cache,
+ // cache the string table.
+ // Binaries in the shared cache all share a giant string table,
+ // and we can't share the string tables across multiple
+ // ObjectFileMachO's, so we'd end up re-reading this mega-strtab
+ // for every binary in the shared cache - it would be a big perf
+ // problem. For binaries outside the shared cache, it's faster to
+ // read the entire strtab at once instead of piece-by-piece as we
+ // process the nlist records.
+ if (!is_shared_cache_image) {
+ DataBufferSP strtab_data_sp(
+ ReadMemory(process_sp, strtab_addr, strtab_data_byte_size));
+ if (strtab_data_sp) {
+ strtab_data.SetData(strtab_data_sp, 0,
+ strtab_data_sp->GetByteSize());
}
}
+ }
if (memory_module_load_level >= eMemoryModuleLoadLevelPartial) {
if (function_starts_load_command.cmd) {
const addr_t func_start_addr =
@@ -2481,8 +2485,8 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
// We shouldn't have exports data from both the LC_DYLD_INFO command
// AND the LC_DYLD_EXPORTS_TRIE command in the same binary:
- lldbassert(!((dyld_info.export_size > 0)
- && (exports_trie_load_command.datasize > 0)));
+ lldbassert(!((dyld_info.export_size > 0) &&
+ (exports_trie_load_command.datasize > 0)));
if (dyld_info.export_size > 0) {
dyld_trie_data.SetData(m_data, dyld_info.export_off,
dyld_info.export_size);
@@ -2726,7 +2730,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
if (found_image)
return;
- if (process_shared_cache_uuid.IsValid() &&
+ if (process_shared_cache_uuid.IsValid() &&
process_shared_cache_uuid != UUID::fromData(&cache_uuid, 16))
return;
@@ -2793,59 +2797,55 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
byte_order, addr_byte_size);
unmapped_local_symbols_found = nlist_count;
- // The normal nlist code cannot correctly size the Symbols
- // array, we need to allocate it here.
- sym = symtab.Resize(
- symtab_load_command.nsyms + m_dysymtab.nindirectsyms +
- unmapped_local_symbols_found - m_dysymtab.nlocalsym);
- num_syms = symtab.GetNumSymbols();
+ // The normal nlist code cannot correctly size the Symbols
+ // array, we need to allocate it here.
+ sym = symtab.Resize(symtab_load_command.nsyms + m_dysymtab.nindirectsyms +
+ unmapped_local_symbols_found - m_dysymtab.nlocalsym);
+ num_syms = symtab.GetNumSymbols();
lldb::offset_t nlist_data_offset = 0;
- for (uint32_t nlist_index = 0;
- nlist_index < nlist_count;
- nlist_index++) {
- /////////////////////////////
- {
- std::optional<struct nlist_64> nlist_maybe =
- ParseNList(dsc_local_symbols_data, nlist_data_offset,
- nlist_byte_size);
- if (!nlist_maybe)
- break;
- struct nlist_64 nlist = *nlist_maybe;
+ for (uint32_t nlist_index = 0; nlist_index < nlist_count; nlist_index++) {
+ /////////////////////////////
+ {
+ std::optional<struct nlist_64> nlist_maybe = ParseNList(
+ dsc_local_symbols_data, nlist_data_offset, nlist_byte_size);
+ if (!nlist_maybe)
+ break;
+ struct nlist_64 nlist = *nlist_maybe;
- SymbolType type = eSymbolTypeInvalid;
+ SymbolType type = eSymbolTypeInvalid;
const char *symbol_name = string_table + nlist.n_strx;
- if (symbol_name == NULL) {
- // No symbol should be NULL, even the symbols with no
- // string values should have an offset zero which
- // points to an empty C-string
+ if (symbol_name == NULL) {
+ // No symbol should be NULL, even the symbols with no
+ // string values should have an offset zero which
+ // points to an empty C-string
Debugger::ReportError(llvm::formatv(
"DSC unmapped local symbol[{0}] has invalid "
"string table offset {1:x} in {2}, ignoring symbol",
nlist_index, nlist.n_strx,
module_sp->GetFileSpec().GetPath());
continue;
- }
- if (symbol_name[0] == '\0')
+ }
+ if (symbol_name[0] == '\0')
symbol_name = NULL;
- const char *symbol_name_non_abi_mangled = NULL;
+ const char *symbol_name_non_abi_mangled = NULL;
- SectionSP symbol_section;
- uint32_t symbol_byte_size = 0;
- bool add_nlist = true;
- bool is_debug = ((nlist.n_type & N_STAB) != 0);
- bool demangled_is_synthesized = false;
- bool is_gsym = false;
- bool set_value = true;
+ SectionSP symbol_section;
+ uint32_t symbol_byte_size = 0;
+ bool add_nlist = true;
+ bool is_debug = ((nlist.n_type & N_STAB) != 0);
+ bool demangled_is_synthesized = false;
+ bool is_gsym = false;
+ bool set_value = true;
- assert(sym_idx < num_syms);
+ assert(sym_idx < num_syms);
- sym[sym_idx].SetDebug(is_debug);
+ sym[sym_idx].SetDebug(is_debug);
- if (is_debug) {
+ if (is_debug) {
switch (nlist.n_type) {
case N_GSYM:
// global symbol: name,,NO_SECT,type,0
@@ -3231,7 +3231,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
default:
break;
}
- } else {
+ } else {
// uint8_t n_pext = N_PEXT & nlist.n_type;
uint8_t n_type = N_TYPE & nlist.n_type;
sym[sym_idx].SetExternal((N_EXT & nlist.n_type) != 0);
@@ -3383,14 +3383,12 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
if (symbol_name) {
llvm::StringRef symbol_name_ref(symbol_name);
if (symbol_name_ref.startswith("_OBJC_")) {
- llvm::StringRef
- g_objc_v2_prefix_class(
- "_OBJC_CLASS_$_");
- llvm::StringRef
- g_objc_v2_prefix_metaclass(
- "_OBJC_METACLASS_$_");
- llvm::StringRef
- g_objc_v2_prefix_ivar("_OBJC_IVAR_$_");
+ llvm::StringRef g_objc_v2_prefix_class(
+ "_OBJC_CLASS_$_");
+ llvm::StringRef g_objc_v2_prefix_metaclass(
+ "_OBJC_METACLASS_$_");
+ llvm::StringRef g_objc_v2_prefix_ivar(
+ "_OBJC_IVAR_$_");
if (symbol_name_ref.startswith(
g_objc_v2_prefix_class)) {
symbol_name_non_abi_mangled =
@@ -3439,8 +3437,8 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
type = eSymbolTypeRuntime;
if (symbol_name && symbol_name[0] == '.') {
llvm::StringRef symbol_name_ref(symbol_name);
- llvm::StringRef
- g_objc_v1_prefix_class(".objc_class_name_");
+ llvm::StringRef g_objc_v1_prefix_class(
+ ".objc_class_name_");
if (symbol_name_ref.startswith(
g_objc_v1_prefix_class)) {
symbol_name_non_abi_mangled = symbol_name;
@@ -3455,9 +3453,9 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
}
} break;
}
- }
+ }
- if (add_nlist) {
+ if (add_nlist) {
uint64_t symbol_value = nlist.n_value;
if (symbol_name_non_abi_mangled) {
sym[sym_idx].GetMangled().SetMangledName(
@@ -3675,25 +3673,25 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
if (demangled_is_synthesized)
sym[sym_idx].SetDemangledNameIsSynthesized(true);
++sym_idx;
- } else {
+ } else {
sym[sym_idx].Clear();
- }
- }
- /////////////////////////////
- }
- }
-
- for (const auto &pos : reexport_shlib_needs_fixup) {
- const auto undef_pos = undefined_name_to_desc.find(pos.second);
- if (undef_pos != undefined_name_to_desc.end()) {
- const uint8_t dylib_ordinal =
- llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
- if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
- sym[pos.first].SetReExportedSymbolSharedLibrary(
- dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
- }
- }
}
+ }
+ /////////////////////////////
+ }
+ }
+
+ for (const auto &pos : reexport_shlib_needs_fixup) {
+ const auto undef_pos = undefined_name_to_desc.find(pos.second);
+ if (undef_pos != undefined_name_to_desc.end()) {
+ const uint8_t dylib_ordinal =
+ llvm::MachO::GET_LIBRARY_ORDINAL(undef_pos->second);
+ if (dylib_ordinal > 0 && dylib_ordinal < dylib_files.GetSize())
+ sym[pos.first].SetReExportedSymbolSharedLibrary(
+ dylib_files.GetFileSpecAtIndex(dylib_ordinal - 1));
+ }
+ }
+ }
#endif
lldb::offset_t nlist_data_offset = 0;
@@ -3703,8 +3701,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
// If the sym array was not created while parsing the DSC unmapped
// symbols, create it now.
if (sym == nullptr) {
- sym =
- symtab.Resize(symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
+ sym = symtab.Resize(symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
num_syms = symtab.GetNumSymbols();
}
@@ -4251,12 +4248,10 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
if (symbol_name) {
llvm::StringRef symbol_name_ref(symbol_name);
if (symbol_name_ref.startswith("_OBJC_")) {
- llvm::StringRef g_objc_v2_prefix_class(
- "_OBJC_CLASS_$_");
+ llvm::StringRef g_objc_v2_prefix_class("_OBJC_CLASS_$_");
llvm::StringRef g_objc_v2_prefix_metaclass(
"_OBJC_METACLASS_$_");
- llvm::StringRef g_objc_v2_prefix_ivar(
- "_OBJC_IVAR_$_");
+ llvm::StringRef g_objc_v2_prefix_ivar("_OBJC_IVAR_$_");
if (symbol_name_ref.startswith(g_objc_v2_prefix_class)) {
symbol_name_non_abi_mangled = symbol_name + 1;
symbol_name =
@@ -4295,8 +4290,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
type = eSymbolTypeRuntime;
if (symbol_name && symbol_name[0] == '.') {
llvm::StringRef symbol_name_ref(symbol_name);
- llvm::StringRef g_objc_v1_prefix_class(
- ".objc_class_name_");
+ llvm::StringRef g_objc_v1_prefix_class(".objc_class_name_");
if (symbol_name_ref.startswith(g_objc_v1_prefix_class)) {
symbol_name_non_abi_mangled = symbol_name;
symbol_name = symbol_name + g_objc_v1_prefix_class.size();
@@ -4609,42 +4603,46 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
addr_t symbol_file_addr = func_start_entry->addr;
uint32_t symbol_flags = 0;
if (func_start_entry->data)
- symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
+ symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
Address symbol_addr;
if (module_sp->ResolveFileAddress(symbol_file_addr, symbol_addr)) {
- SectionSP symbol_section(symbol_addr.GetSection());
- uint32_t symbol_byte_size = 0;
- if (symbol_section) {
- const addr_t section_file_addr = symbol_section->GetFileAddress();
- const FunctionStarts::Entry *next_func_start_entry =
- function_starts.FindNextEntry(func_start_entry);
- const addr_t section_end_file_addr =
- section_file_addr + symbol_section->GetByteSize();
- if (next_func_start_entry) {
- addr_t next_symbol_file_addr = next_func_start_entry->addr;
- if (is_arm)
- next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
- symbol_byte_size = std::min<lldb::addr_t>(
- next_symbol_file_addr - symbol_file_addr,
- section_end_file_addr - symbol_file_addr);
- } else {
- symbol_byte_size = section_end_file_addr - symbol_file_addr;
- }
- sym[sym_idx].SetID(synthetic_sym_id++);
- // Don't set the name for any synthetic symbols, the Symbol
- // object will generate one if needed when the name is accessed
- // via accessors.
- sym[sym_idx].GetMangled().SetDemangledName(ConstString());
- sym[sym_idx].SetType(eSymbolTypeCode);
- sym[sym_idx].SetIsSynthetic(true);
- sym[sym_idx].GetAddressRef() = symbol_addr;
- add_symbol_addr(symbol_addr.GetFileAddress());
- if (symbol_flags)
- sym[sym_idx].SetFlags(symbol_flags);
- if (symbol_byte_size)
- sym[sym_idx].SetByteSize(symbol_byte_size);
- ++sym_idx;
- }
+ SectionSP symbol_section(symbol_addr.GetSection());
+ uint32_t symbol_byte_size = 0;
+ if (symbol_section) {
+ const addr_t section_file_addr =
+ symbol_section->GetFileAddress();
+ const FunctionStarts::Entry *next_func_start_entry =
+ function_starts.FindNextEntry(func_start_entry);
+ const addr_t section_end_file_addr =
+ section_file_addr + symbol_section->GetByteSize();
+ if (next_func_start_entry) {
+ addr_t next_symbol_file_addr =
+ next_func_start_entry->addr;
+ if (is_arm)
+ next_symbol_file_addr &= THUMB_ADDRESS_BIT_MASK;
+ symbol_byte_size = std::min<lldb::addr_t>(
+ next_symbol_file_addr - symbol_file_addr,
+ section_end_file_addr - symbol_file_addr);
+ } else {
+ symbol_byte_size =
+ section_end_file_addr - symbol_file_addr;
+ }
+ sym[sym_idx].SetID(synthetic_sym_id++);
+ // Don't set the name for any synthetic symbols, the
+ // Symbol object will generate one if needed when the
+ // name is accessed via accessors.
+ sym[sym_idx].GetMangled().SetDemangledName(
+ ConstString());
+ sym[sym_idx].SetType(eSymbolTypeCode);
+ sym[sym_idx].SetIsSynthetic(true);
+ sym[sym_idx].GetAddressRef() = symbol_addr;
+ add_symbol_addr(symbol_addr.GetFileAddress());
+ if (symbol_flags)
+ sym[sym_idx].SetFlags(symbol_flags);
+ if (symbol_byte_size)
+ sym[sym_idx].SetByteSize(symbol_byte_size);
+ ++sym_idx;
+ }
}
}
}
@@ -4670,87 +4668,97 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
S_SYMBOL_STUBS) {
uint32_t symbol_stub_byte_size = m_mach_sections[sect_idx].reserved2;
if (symbol_stub_byte_size == 0)
- continue;
+ continue;
const uint32_t num_symbol_stubs =
m_mach_sections[sect_idx].size / symbol_stub_byte_size;
if (num_symbol_stubs == 0)
- continue;
+ continue;
const uint32_t symbol_stub_index_offset =
m_mach_sections[sect_idx].reserved1;
for (uint32_t stub_idx = 0; stub_idx < num_symbol_stubs; ++stub_idx) {
- const uint32_t symbol_stub_index =
- symbol_stub_index_offset + stub_idx;
- const lldb::addr_t symbol_stub_addr =
- m_mach_sections[sect_idx].addr +
- (stub_idx * symbol_stub_byte_size);
- lldb::offset_t symbol_stub_offset = symbol_stub_index * 4;
- if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
- symbol_stub_offset, 4)) {
- const uint32_t stub_sym_id =
- indirect_symbol_index_data.GetU32(&symbol_stub_offset);
- if (stub_sym_id & (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
- continue;
-
- NListIndexToSymbolIndexMap::const_iterator index_pos =
- m_nlist_idx_to_sym_idx.find(stub_sym_id);
- Symbol *stub_symbol = nullptr;
- if (index_pos != end_index_pos) {
- // We have a remapping from the original nlist index to a
- // current symbol index, so just look this up by index
- stub_symbol = symtab.SymbolAtIndex(index_pos->second);
- } else {
- // We need to lookup a symbol using the original nlist symbol
- // index since this index is coming from the S_SYMBOL_STUBS
- stub_symbol = symtab.FindSymbolByID(stub_sym_id);
- }
+ const uint32_t symbol_stub_index =
+ symbol_stub_index_offset + stub_idx;
+ const lldb::addr_t symbol_stub_addr =
+ m_mach_sections[sect_idx].addr +
+ (stub_idx * symbol_stub_byte_size);
+ lldb::offset_t symbol_stub_offset = symbol_stub_index * 4;
+ if (indirect_symbol_index_data.ValidOffsetForDataOfSize(
+ symbol_stub_offset, 4)) {
+ const uint32_t stub_sym_id =
+ indirect_symbol_index_data.GetU32(
+ &symbol_stub_offset);
+ if (stub_sym_id &
+ (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL))
+ continue;
+
+ NListIndexToSymbolIndexMap::const_iterator index_pos =
+ m_nlist_idx_to_sym_idx.find(stub_sym_id);
+ Symbol *stub_symbol = nullptr;
+ if (index_pos != end_index_pos) {
+ // We have a remapping from the original nlist index
+ // to a current symbol index, so just look this up by
+ // index
+ stub_symbol = symtab.SymbolAtIndex(index_pos->second);
+ } else {
+ // We need to lookup a symbol using the original nlist
+ // symbol index since this index is coming from the
+ // S_SYMBOL_STUBS
+ stub_symbol = symtab.FindSymbolByID(stub_sym_id);
+ }
- if (stub_symbol) {
- Address so_addr(symbol_stub_addr, section_list);
-
- if (stub_symbol->GetType() == eSymbolTypeUndefined) {
- // Change the external symbol into a trampoline that makes
- // sense These symbols were N_UNDF N_EXT, and are useless
- // to us, so we can re-use them so we don't have to make up
- // a synthetic symbol for no good reason.
- if (resolver_addresses.find(symbol_stub_addr) ==
- resolver_addresses.end())
- stub_symbol->SetType(eSymbolTypeTrampoline);
- else
- stub_symbol->SetType(eSymbolTypeResolver);
- stub_symbol->SetExternal(false);
- stub_symbol->GetAddressRef() = so_addr;
- stub_symbol->SetByteSize(symbol_stub_byte_size);
- } else {
- // Make a synthetic symbol to describe the trampoline stub
- Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
- if (sym_idx >= num_syms) {
- sym = symtab.Resize(++num_syms);
- stub_symbol = nullptr; // this pointer no longer valid
- }
- sym[sym_idx].SetID(synthetic_sym_id++);
- sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
- if (resolver_addresses.find(symbol_stub_addr) ==
- resolver_addresses.end())
- sym[sym_idx].SetType(eSymbolTypeTrampoline);
- else
- sym[sym_idx].SetType(eSymbolTypeResolver);
- sym[sym_idx].SetIsSynthetic(true);
- sym[sym_idx].GetAddressRef() = so_addr;
- add_symbol_addr(so_addr.GetFileAddress());
- sym[sym_idx].SetByteSize(symbol_stub_byte_size);
- ++sym_idx;
- }
- } else {
- if (log)
- log->Warning("symbol stub referencing symbol table symbol "
- "%u that isn't in our minimal symbol table, "
- "fix this!!!",
- stub_sym_id);
- }
- }
+ if (stub_symbol) {
+ Address so_addr(symbol_stub_addr, section_list);
+
+ if (stub_symbol->GetType() == eSymbolTypeUndefined) {
+ // Change the external symbol into a trampoline that
+ // makes sense These symbols were N_UNDF N_EXT, and
+ // are useless to us, so we can re-use them so we
+ // don't have to make up a synthetic symbol for no
+ // good reason.
+ if (resolver_addresses.find(symbol_stub_addr) ==
+ resolver_addresses.end())
+ stub_symbol->SetType(eSymbolTypeTrampoline);
+ else
+ stub_symbol->SetType(eSymbolTypeResolver);
+ stub_symbol->SetExternal(false);
+ stub_symbol->GetAddressRef() = so_addr;
+ stub_symbol->SetByteSize(symbol_stub_byte_size);
+ } else {
+ // Make a synthetic symbol to describe the
+ // trampoline stub
+ Mangled stub_symbol_mangled_name(
+ stub_symbol->GetMangled());
+ if (sym_idx >= num_syms) {
+ sym = symtab.Resize(++num_syms);
+ stub_symbol =
+ nullptr; // this pointer no longer valid
+ }
+ sym[sym_idx].SetID(synthetic_sym_id++);
+ sym[sym_idx].GetMangled() =
+ stub_symbol_mangled_name;
+ if (resolver_addresses.find(symbol_stub_addr) ==
+ resolver_addresses.end())
+ sym[sym_idx].SetType(eSymbolTypeTrampoline);
+ else
+ sym[sym_idx].SetType(eSymbolTypeResolver);
+ sym[sym_idx].SetIsSynthetic(true);
+ sym[sym_idx].GetAddressRef() = so_addr;
+ add_symbol_addr(so_addr.GetFileAddress());
+ sym[sym_idx].SetByteSize(symbol_stub_byte_size);
+ ++sym_idx;
+ }
+ } else {
+ if (log)
+ log->Warning(
+ "symbol stub referencing symbol table symbol "
+ "%u that isn't in our minimal symbol table, "
+ "fix this!!!",
+ stub_sym_id);
+ }
+ }
}
}
}
@@ -4766,15 +4774,15 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
indirect_symbol_names.end()) {
// Make a synthetic symbol to describe re-exported symbol.
if (sym_idx >= num_syms)
- sym = symtab.Resize(++num_syms);
+ sym = symtab.Resize(++num_syms);
sym[sym_idx].SetID(synthetic_sym_id++);
sym[sym_idx].GetMangled() = Mangled(e.entry.name);
sym[sym_idx].SetType(eSymbolTypeReExported);
sym[sym_idx].SetIsSynthetic(true);
sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize()) {
- sym[sym_idx].SetReExportedSymbolSharedLibrary(
- dylib_files.GetFileSpecAtIndex(e.entry.other - 1));
+ sym[sym_idx].SetReExportedSymbolSharedLibrary(
+ dylib_files.GetFileSpecAtIndex(e.entry.other - 1));
}
++sym_idx;
}
@@ -5131,20 +5139,21 @@ uint32_t ObjectFileMachO::GetDependentModules(FileSpecList &files) {
const char *path = m_data.PeekCStr(name_offset);
if (path) {
if (load_cmd.cmd == LC_RPATH)
- rpath_paths.push_back(path);
+ rpath_paths.push_back(path);
else {
- if (path[0] == '@') {
- if (strncmp(path, "@rpath", strlen("@rpath")) == 0)
- rpath_relative_paths.push_back(path + strlen("@rpath"));
- else if (strncmp(path, "@executable_path",
- strlen("@executable_path")) == 0)
- at_exec_relative_paths.push_back(path +
- strlen("@executable_path"));
- } else {
- FileSpec file_spec(path);
- if (files.AppendIfUnique(file_spec))
- count++;
- }
+ if (path[0] == '@') {
+ if (strncmp(path, "@rpath", strlen("@rpath")) == 0)
+ rpath_relative_paths.push_back(path +
+ strlen("@rpath"));
+ else if (strncmp(path, "@executable_path",
+ strlen("@executable_path")) == 0)
+ at_exec_relative_paths.push_back(
+ path + strlen("@executable_path"));
+ } else {
+ FileSpec file_spec(path);
+ if (files.AppendIfUnique(file_spec))
+ count++;
+ }
}
}
} break;
@@ -5182,8 +5191,8 @@ uint32_t ObjectFileMachO::GetDependentModules(FileSpecList &files) {
FileSystem::Instance().Resolve(file_spec);
if (FileSystem::Instance().Exists(file_spec) &&
files.AppendIfUnique(file_spec)) {
- count++;
- break;
+ count++;
+ break;
}
}
}
@@ -5262,59 +5271,60 @@ lldb_private::Address ObjectFileMachO::GetEntryPointAddress() {
uint32_t flavor = m_data.GetU32(&offset);
uint32_t count = m_data.GetU32(&offset);
if (count == 0) {
- // We've gotten off somehow, log and exit;
- return m_entry_point_address;
+ // We've gotten off somehow, log and exit;
+ return m_entry_point_address;
}
switch (m_header.cputype) {
case llvm::MachO::CPU_TYPE_ARM:
- if (flavor == 1 ||
- flavor == 9) // ARM_THREAD_STATE/ARM_THREAD_STATE32
- // from mach/arm/thread_status.h
- {
- offset += 60; // This is the offset of pc in the GPR thread state
- // data structure.
- start_address = m_data.GetU32(&offset);
- done = true;
- }
- break;
+ if (flavor == 1 ||
+ flavor == 9) // ARM_THREAD_STATE/ARM_THREAD_STATE32
+ // from mach/arm/thread_status.h
+ {
+ offset += 60; // This is the offset of pc in the GPR
+ // thread state data structure.
+ start_address = m_data.GetU32(&offset);
+ done = true;
+ }
+ break;
case llvm::MachO::CPU_TYPE_ARM64:
case llvm::MachO::CPU_TYPE_ARM64_32:
- if (flavor == 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h
- {
- offset += 256; // This is the offset of pc in the GPR thread state
- // data structure.
- start_address = m_data.GetU64(&offset);
- done = true;
- }
- break;
+ if (flavor ==
+ 6) // ARM_THREAD_STATE64 from mach/arm/thread_status.h
+ {
+ offset += 256; // This is the offset of pc in the GPR
+ // thread state data structure.
+ start_address = m_data.GetU64(&offset);
+ done = true;
+ }
+ break;
case llvm::MachO::CPU_TYPE_I386:
- if (flavor ==
- 1) // x86_THREAD_STATE32 from mach/i386/thread_status.h
- {
- offset += 40; // This is the offset of eip in the GPR thread state
- // data structure.
- start_address = m_data.GetU32(&offset);
- done = true;
- }
- break;
+ if (flavor == 1) // x86_THREAD_STATE32 from
+ // mach/i386/thread_status.h
+ {
+ offset += 40; // This is the offset of eip in the GPR
+ // thread state data structure.
+ start_address = m_data.GetU32(&offset);
+ done = true;
+ }
+ break;
case llvm::MachO::CPU_TYPE_X86_64:
- if (flavor ==
- 4) // x86_THREAD_STATE64 from mach/i386/thread_status.h
- {
- offset += 16 * 8; // This is the offset of rip in the GPR thread
- // state data structure.
- start_address = m_data.GetU64(&offset);
- done = true;
- }
- break;
+ if (flavor == 4) // x86_THREAD_STATE64 from
+ // mach/i386/thread_status.h
+ {
+ offset += 16 * 8; // This is the offset of rip in the
+ // GPR thread state data structure.
+ start_address = m_data.GetU64(&offset);
+ done = true;
+ }
+ break;
default:
- return m_entry_point_address;
+ return m_entry_point_address;
}
// Haven't found the GPR flavor yet, skip over the data for this
// flavor:
if (done)
- break;
+ break;
offset += count * 4;
}
} break;
@@ -5369,7 +5379,7 @@ lldb_private::Address ObjectFileMachO::GetEntryPointAddress() {
eSymbolTypeCode, contexts);
if (contexts.GetSize()) {
if (contexts.GetContextAtIndex(0, context))
- m_entry_point_address = context.symbol->GetAddress();
+ m_entry_point_address = context.symbol->GetAddress();
}
}
}
@@ -5467,7 +5477,7 @@ std::string ObjectFileMachO::GetIdentifierString() {
std::string result(strsize, '\0');
m_data.CopyData(payload_offset, strsize, result.data());
while (result.back() == '\0')
- result.resize(result.size() - 1);
+ result.resize(result.size() - 1);
LLDB_LOGF(log, "LC_NOTE 'kern ver str' found with text '%s'",
result.c_str());
return result;
@@ -5488,7 +5498,7 @@ std::string ObjectFileMachO::GetIdentifierString() {
if (m_data.CopyData(offset, ident_command.cmdsize, result.data()) ==
ident_command.cmdsize) {
while (result.back() == '\0')
- result.resize(result.size() - 1);
+ result.resize(result.size() - 1);
LLDB_LOGF(log, "LC_IDENT found with text '%s'", result.c_str());
return result;
}
@@ -5524,9 +5534,10 @@ AddressableBits ObjectFileMachO::GetAddressableBits() {
uint32_t hi_addr_bits = m_data.GetU32_unchecked(&payload_offset);
if (lo_addr_bits == hi_addr_bits)
- addressable_bits.SetAddressableBits(lo_addr_bits);
+ addressable_bits.SetAddressableBits(lo_addr_bits);
else
- addressable_bits.SetAddressableBits(lo_addr_bits, hi_addr_bits);
+ addressable_bits.SetAddressableBits(lo_addr_bits,
+ hi_addr_bits);
LLDB_LOGF(log, "LC_NOTE 'addrable bits' v4 found, value %d & %d bits",
lo_addr_bits, hi_addr_bits);
}
@@ -5613,21 +5624,21 @@ bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &value,
const char *typestr = "unrecognized type";
switch (binspec_type) {
case 0:
- type = eBinaryTypeUnknown;
- typestr = "uknown";
- break;
+ type = eBinaryTypeUnknown;
+ typestr = "uknown";
+ break;
case 1:
- type = eBinaryTypeKernel;
- typestr = "xnu kernel";
- break;
+ type = eBinaryTypeKernel;
+ typestr = "xnu kernel";
+ break;
case 2:
- type = eBinaryTypeUser;
- typestr = "userland dyld";
- break;
+ type = eBinaryTypeUser;
+ typestr = "userland dyld";
+ break;
case 3:
- type = eBinaryTypeStandalone;
- typestr = "standalone";
- break;
+ type = eBinaryTypeStandalone;
+ typestr = "standalone";
+ break;
}
LLDB_LOGF(log,
"LC_NOTE 'main bin spec' found, version %d type %d "
@@ -5636,9 +5647,9 @@ bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &value,
value_is_offset ? "true" : "false",
uuid.GetAsString().c_str());
if (!m_data.GetU32(&payload_offset, &log2_pagesize, 1))
- return false;
+ return false;
if (version > 1 && !m_data.GetU32(&payload_offset, &platform, 1))
- return false;
+ return false;
return true;
}
}
@@ -5701,7 +5712,7 @@ bool ObjectFileMachO::GetCorefileThreadExtraInfos(std::vector<tid_t> &tids) {
tid_t tid = LLDB_INVALID_THREAD_ID;
if (thread->GetValueForKeyAsInteger<tid_t>("thread_id", tid))
if (tid == 0)
- tid = LLDB_INVALID_THREAD_ID;
+ tid = LLDB_INVALID_THREAD_ID;
tids.push_back(tid);
}
@@ -5879,7 +5890,7 @@ llvm::VersionTuple ObjectFileMachO::GetVersion() {
if (version_cmd == 0) {
version_cmd = load_cmd.cmd;
if (m_data.GetU32(&offset, &load_cmd.dylib, 4) == nullptr)
- break;
+ break;
version = load_cmd.dylib.current_version;
}
break; // Break for now unless there is another more complete version
@@ -5964,20 +5975,20 @@ void ObjectFileMachO::GetLLDBSharedCacheUUID(addr_t &base_addr, UUID &uuid) {
(uuid_t *)((uint8_t *)dyld_all_image_infos_address +
160); // sharedCacheUUID <mach-o/dyld_images.h>
if (*version >= 15)
- base_addr =
- *(uint64_t
- *)((uint8_t *)dyld_all_image_infos_address +
- 176); // sharedCacheBaseAddress <mach-o/dyld_images.h>
+ base_addr = *(
+ uint64_t *)((uint8_t *)dyld_all_image_infos_address +
+ 176); // sharedCacheBaseAddress
+ // <mach-o/dyld_images.h>
} else {
sharedCacheUUID_address =
(uuid_t *)((uint8_t *)dyld_all_image_infos_address +
84); // sharedCacheUUID <mach-o/dyld_images.h>
if (*version >= 15) {
- base_addr = 0;
- base_addr =
- *(uint32_t
- *)((uint8_t *)dyld_all_image_infos_address +
- 100); // sharedCacheBaseAddress <mach-o/dyld_images.h>
+ base_addr = 0;
+ base_addr = *(
+ uint32_t *)((uint8_t *)dyld_all_image_infos_address +
+ 100); // sharedCacheBaseAddress
+ // <mach-o/dyld_images.h>
}
}
uuid = UUID(sharedCacheUUID_address, sizeof(uuid_t));
@@ -6212,7 +6223,7 @@ bool ObjectFileMachO::SetLoadAddress(Target &target, lldb::addr_t value,
if (section_load_addr != LLDB_INVALID_ADDRESS) {
if (target.GetSectionLoadList().SetSectionLoadAddress(
section_sp, section_load_addr, warn_multiple))
- ++num_loaded_sections;
+ ++num_loaded_sections;
}
}
}
@@ -6516,20 +6527,20 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
uint32_t cmd_type = LC_SEGMENT_64;
uint32_t segment_size = sizeof(llvm::MachO::segment_command_64);
if (addr_byte_size == 4) {
- cmd_type = LC_SEGMENT;
- segment_size = sizeof(llvm::MachO::segment_command);
+ cmd_type = LC_SEGMENT;
+ segment_size = sizeof(llvm::MachO::segment_command);
}
// Skip any ranges with no read/write/execute permissions and empty
// ranges.
if (core_range.lldb_permissions == 0 || core_range.range.size() == 0)
- continue;
+ continue;
uint32_t vm_prot = 0;
if (core_range.lldb_permissions & ePermissionsReadable)
- vm_prot |= VM_PROT_READ;
+ vm_prot |= VM_PROT_READ;
if (core_range.lldb_permissions & ePermissionsWritable)
- vm_prot |= VM_PROT_WRITE;
+ vm_prot |= VM_PROT_WRITE;
if (core_range.lldb_permissions & ePermissionsExecutable)
- vm_prot |= VM_PROT_EXECUTE;
+ vm_prot |= VM_PROT_EXECUTE;
const addr_t vm_addr = core_range.range.start();
const addr_t vm_size = core_range.range.size();
llvm::MachO::segment_command_64 segment = {
@@ -6573,28 +6584,28 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx));
if (thread_sp) {
- switch (mach_header.cputype) {
- case llvm::MachO::CPU_TYPE_ARM64:
- case llvm::MachO::CPU_TYPE_ARM64_32:
- RegisterContextDarwin_arm64_Mach::Create_LC_THREAD(
- thread_sp.get(), LC_THREAD_datas[thread_idx]);
- break;
+ switch (mach_header.cputype) {
+ case llvm::MachO::CPU_TYPE_ARM64:
+ case llvm::MachO::CPU_TYPE_ARM64_32:
+ RegisterContextDarwin_arm64_Mach::Create_LC_THREAD(
+ thread_sp.get(), LC_THREAD_datas[thread_idx]);
+ break;
- case llvm::MachO::CPU_TYPE_ARM:
- RegisterContextDarwin_arm_Mach::Create_LC_THREAD(
- thread_sp.get(), LC_THREAD_datas[thread_idx]);
- break;
+ case llvm::MachO::CPU_TYPE_ARM:
+ RegisterContextDarwin_arm_Mach::Create_LC_THREAD(
+ thread_sp.get(), LC_THREAD_datas[thread_idx]);
+ break;
- case llvm::MachO::CPU_TYPE_I386:
- RegisterContextDarwin_i386_Mach::Create_LC_THREAD(
- thread_sp.get(), LC_THREAD_datas[thread_idx]);
- break;
+ case llvm::MachO::CPU_TYPE_I386:
+ RegisterContextDarwin_i386_Mach::Create_LC_THREAD(
+ thread_sp.get(), LC_THREAD_datas[thread_idx]);
+ break;
- case llvm::MachO::CPU_TYPE_X86_64:
- RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD(
- thread_sp.get(), LC_THREAD_datas[thread_idx]);
- break;
- }
+ case llvm::MachO::CPU_TYPE_X86_64:
+ RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD(
+ thread_sp.get(), LC_THREAD_datas[thread_idx]);
+ break;
+ }
}
}
@@ -6745,15 +6756,15 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
buffer.PutHex32(segment.cmdsize);
buffer.PutRawBytes(segment.segname, sizeof(segment.segname));
if (addr_byte_size == 8) {
- buffer.PutHex64(segment.vmaddr);
- buffer.PutHex64(segment.vmsize);
- buffer.PutHex64(segment.fileoff);
- buffer.PutHex64(segment.filesize);
+ buffer.PutHex64(segment.vmaddr);
+ buffer.PutHex64(segment.vmsize);
+ buffer.PutHex64(segment.fileoff);
+ buffer.PutHex64(segment.filesize);
} else {
- buffer.PutHex32(static_cast<uint32_t>(segment.vmaddr));
- buffer.PutHex32(static_cast<uint32_t>(segment.vmsize));
- buffer.PutHex32(static_cast<uint32_t>(segment.fileoff));
- buffer.PutHex32(static_cast<uint32_t>(segment.filesize));
+ buffer.PutHex32(static_cast<uint32_t>(segment.vmaddr));
+ buffer.PutHex32(static_cast<uint32_t>(segment.vmsize));
+ buffer.PutHex32(static_cast<uint32_t>(segment.fileoff));
+ buffer.PutHex32(static_cast<uint32_t>(segment.filesize));
}
buffer.PutHex32(segment.maxprot);
buffer.PutHex32(segment.initprot);
@@ -6776,63 +6787,73 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
core_file.get()->Write(buffer.GetString().data(), bytes_written);
if (error.Success()) {
- for (auto &lcnote : lc_notes) {
- if (core_file.get()->SeekFromStart(lcnote->payload_file_offset) ==
- -1) {
- error.SetErrorStringWithFormat("Unable to seek to corefile pos "
- "to write '%s' LC_NOTE payload",
- lcnote->name.c_str());
- return false;
- }
- bytes_written = lcnote->payload.GetSize();
- error = core_file.get()->Write(lcnote->payload.GetData(),
- bytes_written);
- if (!error.Success())
- return false;
- }
+ for (auto &lcnote : lc_notes) {
+ if (core_file.get()->SeekFromStart(
+ lcnote->payload_file_offset) == -1) {
+ error.SetErrorStringWithFormat(
+ "Unable to seek to corefile pos "
+ "to write '%s' LC_NOTE payload",
+ lcnote->name.c_str());
+ return false;
+ }
+ bytes_written = lcnote->payload.GetSize();
+ error = core_file.get()->Write(
+ lcnote->payload.GetData(), bytes_written);
+ if (!error.Success())
+ return false;
+ }
- // Now write the file data for all memory segments in the process
- for (const auto &segment : segment_load_commands) {
- if (core_file.get()->SeekFromStart(segment.fileoff) == -1) {
- error.SetErrorStringWithFormat(
- "unable to seek to offset 0x%" PRIx64 " in '%s'",
- segment.fileoff, core_file_path.c_str());
- break;
- }
+ // Now write the file data for all memory segments in the
+ // process
+ for (const auto &segment : segment_load_commands) {
+ if (core_file.get()->SeekFromStart(segment.fileoff) ==
+ -1) {
+ error.SetErrorStringWithFormat(
+ "unable to seek to offset 0x%" PRIx64 " in '%s'",
+ segment.fileoff, core_file_path.c_str());
+ break;
+ }
- target.GetDebugger().GetAsyncOutputStream()->Printf(
- "Saving %" PRId64
- " bytes of data for memory region at 0x%" PRIx64 "\n",
- segment.vmsize, segment.vmaddr);
- addr_t bytes_left = segment.vmsize;
- addr_t addr = segment.vmaddr;
- Status memory_read_error;
- while (bytes_left > 0 && error.Success()) {
- const size_t bytes_to_read =
- bytes_left > sizeof(bytes) ? sizeof(bytes) : bytes_left;
-
- // In a savecore setting, we don't really care about caching,
- // as the data is dumped and very likely never read again,
- // so we call ReadMemoryFromInferior to bypass it.
- const size_t bytes_read = process_sp->ReadMemoryFromInferior(
- addr, bytes, bytes_to_read, memory_read_error);
-
- if (bytes_read == bytes_to_read) {
- size_t bytes_written = bytes_read;
- error = core_file.get()->Write(bytes, bytes_written);
- bytes_left -= bytes_read;
- addr += bytes_read;
- } else {
- // Some pages within regions are not readable, those should
- // be zero filled
- memset(bytes, 0, bytes_to_read);
- size_t bytes_written = bytes_to_read;
- error = core_file.get()->Write(bytes, bytes_written);
- bytes_left -= bytes_to_read;
- addr += bytes_to_read;
- }
- }
- }
+ target.GetDebugger().GetAsyncOutputStream()->Printf(
+ "Saving %" PRId64
+ " bytes of data for memory region at 0x%" PRIx64
+ "\n",
+ segment.vmsize, segment.vmaddr);
+ addr_t bytes_left = segment.vmsize;
+ addr_t addr = segment.vmaddr;
+ Status memory_read_error;
+ while (bytes_left > 0 && error.Success()) {
+ const size_t bytes_to_read =
+ bytes_left > sizeof(bytes) ? sizeof(bytes)
+ : bytes_left;
+
+ // In a savecore setting, we don't really care about
+ // caching, as the data is dumped and very likely
+ // never read again, so we call ReadMemoryFromInferior
+ // to bypass it.
+ const size_t bytes_read =
+ process_sp->ReadMemoryFromInferior(
+ addr, bytes, bytes_to_read,
+ memory_read_error);
+
+ if (bytes_read == bytes_to_read) {
+ size_t bytes_written = bytes_read;
+ error =
+ core_file.get()->Write(bytes, bytes_written);
+ bytes_left -= bytes_read;
+ addr += bytes_read;
+ } else {
+ // Some pages within regions are not readable, those
+ // should be zero filled
+ memset(bytes, 0, bytes_to_read);
+ size_t bytes_written = bytes_to_read;
+ error =
+ core_file.get()->Write(bytes, bytes_written);
+ bytes_left -= bytes_to_read;
+ addr += bytes_to_read;
+ }
+ }
+ }
}
}
}
@@ -7005,12 +7026,12 @@ bool ObjectFileMachO::LoadCoreFileImages(lldb_private::Process &process) {
for (auto name_vmaddr_tuple : image.segment_load_addresses) {
SectionList *sectlist = module_sp->GetObjectFile()->GetSectionList();
if (sectlist) {
- SectionSP sect_sp =
- sectlist->FindSectionByName(std::get<0>(name_vmaddr_tuple));
- if (sect_sp) {
- process.GetTarget().SetSectionLoadAddress(
- sect_sp, std::get<1>(name_vmaddr_tuple));
- }
+ SectionSP sect_sp = sectlist->FindSectionByName(
+ std::get<0>(name_vmaddr_tuple));
+ if (sect_sp) {
+ process.GetTarget().SetSectionLoadAddress(
+ sect_sp, std::get<1>(name_vmaddr_tuple));
+ }
}
}
} else {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
index 16ff5f7d4842cae..afd71592148c9af 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
@@ -77,7 +77,7 @@ void ManualDWARFIndex::Index() {
const uint64_t total_progress = units_to_index.size() * 2 + 8;
Progress progress(
llvm::formatv("Manually indexing DWARF for {0}", module_desc.GetData()),
- total_progress);
+ Progress::ProgressReportType::eAggregateProgressReport, total_progress);
std::vector<IndexSet> sets(units_to_index.size());
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index b8b2eb58a8bd85c..64eeec7311e4e82 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -472,7 +472,8 @@ void SymbolFileDWARF::InitializeObject() {
if (apple_names.GetByteSize() > 0 || apple_namespaces.GetByteSize() > 0 ||
apple_types.GetByteSize() > 0 || apple_objc.GetByteSize() > 0) {
Progress progress(llvm::formatv("Loading Apple DWARF index for {0}",
- module_desc.GetData()));
+ module_desc.GetData()),
+ Progress::ProgressReportType::eAggregateProgressReport);
m_index = AppleDWARFIndex::Create(
*GetObjectFile()->GetModule(), apple_names, apple_namespaces,
apple_types, apple_objc, m_context.getOrLoadStrData());
@@ -485,7 +486,8 @@ void SymbolFileDWARF::InitializeObject() {
LoadSectionData(eSectionTypeDWARFDebugNames, debug_names);
if (debug_names.GetByteSize() > 0) {
Progress progress(
- llvm::formatv("Loading DWARF5 index for {0}", module_desc.GetData()));
+ llvm::formatv("Loading DWARF5 index for {0}", module_desc.GetData()),
+ Progress::ProgressReportType::eAggregateProgressReport);
llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> index_or =
DebugNamesDWARFIndex::Create(*GetObjectFile()->GetModule(),
debug_names,
diff --git a/lldb/test/API/functionalities/progress_reporting/TestProgressReporting.py b/lldb/test/API/functionalities/progress_reporting/TestProgressReporting.py
index 0e72770e350366d..634c0fb07180774 100644
--- a/lldb/test/API/functionalities/progress_reporting/TestProgressReporting.py
+++ b/lldb/test/API/functionalities/progress_reporting/TestProgressReporting.py
@@ -37,5 +37,14 @@ def test_dwarf_symbol_loading_progress_report_structured_data(self):
event = lldbutil.fetch_next_event(self, self.listener, self.broadcaster)
progress_data = lldb.SBDebugger.GetProgressDataFromEvent(event)
- message = progress_data.GetValueForKey("message").GetStringValue(100)
- self.assertGreater(len(message), 0)
+ title = progress_data.GetValueForKey("title").GetStringValue(100)
+ self.assertGreater(len(title), 0)
+
+ is_aggregate = progress_data.GetValueForKey("is_aggregate")
+ self.assertTrue(
+ is_aggregate.IsValid(),
+ "ProgressEventData key 'is_aggregate' does not exist.",
+ )
+ self.assertTrue(
+ is_aggregate, "ProgressEventData key 'is_aggregate' should be true."
+ )
More information about the lldb-commits
mailing list