diff options
24 files changed, 649 insertions, 142 deletions
diff --git a/lldb/include/lldb/Core/SourceManager.h b/lldb/include/lldb/Core/SourceManager.h index 0705b5f7a5c..fa63d9cc7d1 100644 --- a/lldb/include/lldb/Core/SourceManager.h +++ b/lldb/include/lldb/Core/SourceManager.h @@ -29,7 +29,7 @@ public: class File { public: - File (const FileSpec &file_spec); + File (const FileSpec &file_spec, Target *target); ~File(); size_t @@ -58,8 +58,9 @@ public: bool CalculateLineOffsets (uint32_t line = UINT32_MAX); - FileSpec m_file_spec; - TimeValue m_mod_time; // Keep the modification time that this file data is valid for + FileSpec m_file_spec_orig; // The original file spec that was used (can be different from m_file_spec) + FileSpec m_file_spec; // The actualy file spec being used (if the target has source mappings, this might be different from m_file_spec_orig) + TimeValue m_mod_time; // Keep the modification time that this file data is valid for lldb::DataBufferSP m_data_sp; typedef std::vector<uint32_t> LineOffsets; LineOffsets m_offsets; @@ -77,23 +78,22 @@ public: typedef lldb::SharedPtr<File>::Type FileSP; FileSP - GetFile (const FileSpec &file_spec); - - FileSP GetLastFile () { return m_last_file_sp; } size_t - DisplaySourceLines (const FileSpec &file, + DisplaySourceLines (Target *target, + const FileSpec &file, uint32_t line, uint32_t context_before, uint32_t context_after, Stream *s); size_t - DisplaySourceLinesWithLineNumbers (const FileSpec &file, + DisplaySourceLinesWithLineNumbers (Target *target, + const FileSpec &file, uint32_t line, uint32_t context_before, uint32_t context_after, @@ -115,6 +115,11 @@ public: const SymbolContextList *bp_locs = NULL); protected: + + FileSP + GetFile (const FileSpec &file_spec, Target *target); + + //------------------------------------------------------------------ // Classes that inherit from SourceManager can see and modify these //------------------------------------------------------------------ diff --git a/lldb/include/lldb/Core/UserSettingsController.h b/lldb/include/lldb/Core/UserSettingsController.h index c271268c01d..2e3d182d354 100644 --- a/lldb/include/lldb/Core/UserSettingsController.h +++ b/lldb/include/lldb/Core/UserSettingsController.h @@ -25,6 +25,7 @@ #include "lldb/Core/Stream.h" #include "lldb/Core/StreamString.h" #include "lldb/Host/Mutex.h" +#include "lldb/Interpreter/NamedOptionValue.h" namespace lldb_private { @@ -231,6 +232,21 @@ public: const char *new_value, Error &err); + static Error + UpdateStringOptionValue (const char *new_value_cstr, + VarSetOperationType op, + OptionValueString &option_value); + + static Error + UpdateBooleanOptionValue (const char *new_value_cstr, + VarSetOperationType op, + OptionValueBoolean &option_value); + + static Error + UpdateFileSpecOptionValue (const char *new_value_cstr, + VarSetOperationType op, + OptionValueFileSpec &option_value); + static bool InitializeSettingsController (lldb::UserSettingsControllerSP &controller_sp, SettingEntry *global_settings, diff --git a/lldb/include/lldb/Interpreter/NamedOptionValue.h b/lldb/include/lldb/Interpreter/NamedOptionValue.h index 282cc21638e..db5d02c3cc9 100644 --- a/lldb/include/lldb/Interpreter/NamedOptionValue.h +++ b/lldb/include/lldb/Interpreter/NamedOptionValue.h @@ -192,6 +192,13 @@ namespace lldb_private { { return m_current_value; } + + const bool & + operator = (bool b) + { + m_current_value = b; + return m_current_value; + } bool GetCurrentValue() const @@ -274,6 +281,13 @@ namespace lldb_private { // Subclass specific functions //--------------------------------------------------------------------- + const int64_t & + operator = (int64_t value) + { + m_current_value = value; + return m_current_value; + } + int64_t GetCurrentValue() const { @@ -363,6 +377,13 @@ namespace lldb_private { // Subclass specific functions //--------------------------------------------------------------------- + const uint64_t & + operator = (uint64_t value) + { + m_current_value = value; + return m_current_value; + } + uint64_t GetCurrentValue() const { @@ -449,6 +470,16 @@ namespace lldb_private { //--------------------------------------------------------------------- const char * + operator = (const char *value) + { + if (value && value[0]) + m_current_value.assign (value); + else + m_current_value.clear(); + return m_current_value.c_str(); + } + + const char * GetCurrentValue() const { return m_current_value.c_str(); @@ -468,7 +499,14 @@ namespace lldb_private { else m_current_value.clear(); } - + + void + AppendToCurrentValue (const char *value) + { + if (value && value[0]) + m_current_value.append (value); + } + void SetDefaultValue (const char *value) { @@ -541,8 +579,8 @@ namespace lldb_private { // Subclass specific functions //--------------------------------------------------------------------- - const FileSpec & - GetCurrentValue() const + FileSpec & + GetCurrentValue() { return m_current_value; } @@ -622,6 +660,15 @@ namespace lldb_private { } lldb::OptionValueSP + operator[](uint32_t idx) const + { + lldb::OptionValueSP value_sp; + if (idx < m_values.size()) + value_sp = m_values[idx]; + return value_sp; + } + + lldb::OptionValueSP GetValueAtIndex (uint32_t idx) const { lldb::OptionValueSP value_sp; @@ -630,11 +677,6 @@ namespace lldb_private { return value_sp; } - uint64_t - GetUInt64ValueAtIndex (uint32_t idx, - uint64_t fail_value, - bool *success_ptr) const; - bool AppendValue (const lldb::OptionValueSP &value_sp) { diff --git a/lldb/include/lldb/Symbol/Block.h b/lldb/include/lldb/Symbol/Block.h index 557b257740a..20222a61873 100644 --- a/lldb/include/lldb/Symbol/Block.h +++ b/lldb/include/lldb/Symbol/Block.h @@ -420,6 +420,14 @@ public: bool GetRangeContainingAddress (const Address& addr, AddressRange &range); + //------------------------------------------------------------------ + // Since blocks might have multiple discontiguous addresss ranges, + // we need to be able to get at any of the address ranges in a block. + //------------------------------------------------------------------ + bool + GetRangeAtIndex (uint32_t range_idx, + AddressRange &range); + bool GetStartAddress (Address &addr); diff --git a/lldb/include/lldb/Symbol/SymbolContext.h b/lldb/include/lldb/Symbol/SymbolContext.h index ec6953dd050..feceb64b587 100644 --- a/lldb/include/lldb/Symbol/SymbolContext.h +++ b/lldb/include/lldb/Symbol/SymbolContext.h @@ -172,10 +172,29 @@ public: /// Get the address range contained within a symbol context. /// /// Address range priority is as follows: - /// - line_entry address range if line_entry is valid - /// - function address range if function is not NULL - /// - symbol address range if symbol is not NULL - /// + /// - line_entry address range if line_entry is valid and eSymbolContextLineEntry is set in \a scope + /// - block address range if block is not NULL and eSymbolContextBlock is set in \a scope + /// - function address range if function is not NULL and eSymbolContextFunction is set in \a scope + /// - symbol address range if symbol is not NULL and eSymbolContextSymbol is set in \a scope + /// + /// @param[in] scope + /// A mask of symbol context bits telling this function which + /// address ranges it can use when trying to extract one from + /// the valid (non-NULL) symbol context classes. + /// + /// @param[in] range_idx + /// The address range index to grab. Since many functions and + /// blocks are not always contiguous, they may have more than + /// one address range. + /// + /// @param[in] use_inline_block_range + /// If \a scope has the eSymbolContextBlock bit set, and there + /// is a valid block in the symbol context, return the block + /// address range for the containing inline function block, not + /// the deepest most block. This allows us to extract information + /// for the address range of the inlined function block, not + /// the deepest lexical block. + /// /// @param[out] range /// An address range object that will be filled in if \b true /// is returned. @@ -185,7 +204,10 @@ public: /// an address range, \b false otherwise. //------------------------------------------------------------------ bool - GetAddressRange (uint32_t scope, AddressRange &range) const; + GetAddressRange (uint32_t scope, + uint32_t range_idx, + bool use_inline_block_range, + AddressRange &range) const; void diff --git a/lldb/include/lldb/Target/PathMappingList.h b/lldb/include/lldb/Target/PathMappingList.h index 3881437ffd4..94f90dfe02a 100644 --- a/lldb/include/lldb/Target/PathMappingList.h +++ b/lldb/include/lldb/Target/PathMappingList.h @@ -34,9 +34,14 @@ public: PathMappingList (ChangedCallback callback, void *callback_baton); + PathMappingList (const PathMappingList &rhs); + virtual ~PathMappingList (); + const PathMappingList & + operator =(const PathMappingList &rhs); + void Append (const ConstString &path, const ConstString &replacement, bool notify); @@ -49,6 +54,9 @@ public: size_t GetSize (); + bool + GetPathsAtIndex (uint32_t idx, ConstString &path, ConstString &new_path) const; + void Insert (const ConstString &path, const ConstString &replacement, @@ -59,22 +67,34 @@ public: Remove (off_t index, bool notify); bool + Remove (const ConstString &path, bool notify); + + bool + Replace (const ConstString &path, + const ConstString &new_path, + bool notify); + + bool RemapPath (const ConstString &path, ConstString &new_path); + uint32_t + FindIndexForPath (const ConstString &path) const; + protected: typedef std::pair <ConstString, ConstString> pair; typedef std::vector <pair> collection; typedef collection::iterator iterator; typedef collection::const_iterator const_iterator; + iterator + FindIteratorForPath (const ConstString &path); + + const_iterator + FindIteratorForPath (const ConstString &path) const; + collection m_pairs; ChangedCallback m_callback; void * m_callback_baton; -private: - //------------------------------------------------------------------ - // For PathMappingList only - //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (PathMappingList); }; } // namespace lldb_private diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 2c9e4a6a264..7343384b65a 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -23,6 +23,7 @@ #include "lldb/Core/ModuleList.h" #include "lldb/Core/UserSettingsController.h" #include "lldb/Expression/ClangPersistentVariables.h" +#include "lldb/Interpreter/NamedOptionValue.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/ABI.h" #include "lldb/Target/ExecutionContextScope.h" @@ -78,6 +79,12 @@ public: return m_skip_prologue; } + PathMappingList & + GetSourcePathMap () + { + return m_source_map; + } + protected: void @@ -87,10 +94,11 @@ protected: const ConstString CreateInstanceName (); - std::string m_expr_prefix_path; - std::string m_expr_prefix_contents; - bool m_prefer_dynamic_value; - bool m_skip_prologue; + OptionValueFileSpec m_expr_prefix_file; + lldb::DataBufferSP m_expr_prefix_contents_sp; + OptionValueBoolean m_prefer_dynamic_value; + OptionValueBoolean m_skip_prologue; + PathMappingList m_source_map; }; diff --git a/lldb/source/API/SBSourceManager.cpp b/lldb/source/API/SBSourceManager.cpp index 0fa98e35dea..16193dd027b 100644 --- a/lldb/source/API/SBSourceManager.cpp +++ b/lldb/source/API/SBSourceManager.cpp @@ -61,7 +61,8 @@ SBSourceManager::DisplaySourceLinesWithLineNumbers if (file.IsValid()) { - return m_opaque_ptr->DisplaySourceLinesWithLineNumbers (*file, + return m_opaque_ptr->DisplaySourceLinesWithLineNumbers (NULL, + *file, line, context_before, context_after, diff --git a/lldb/source/Commands/CommandObjectRegister.cpp b/lldb/source/Commands/CommandObjectRegister.cpp index 9c74c1711f3..80059607166 100644 --- a/lldb/source/Commands/CommandObjectRegister.cpp +++ b/lldb/source/Commands/CommandObjectRegister.cpp @@ -170,7 +170,7 @@ public: { for (uint32_t i=0; i<set_array_size; ++i) { - set_idx = m_options.set_indexes.GetUInt64ValueAtIndex (i, UINT32_MAX, NULL); + set_idx = m_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL); if (set_idx != UINT32_MAX) { if (!DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx)) diff --git a/lldb/source/Commands/CommandObjectSource.cpp b/lldb/source/Commands/CommandObjectSource.cpp index 40d35e5ef10..ee55642b4b6 100644 --- a/lldb/source/Commands/CommandObjectSource.cpp +++ b/lldb/source/Commands/CommandObjectSource.cpp @@ -429,7 +429,8 @@ public: m_breakpoint_locations.Clear(); result.AppendMessageWithFormat("File: %s.\n", path_buf); - m_interpreter.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbers (start_file, + m_interpreter.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbers (target, + start_file, line_no, 0, m_options.num_lines, @@ -580,7 +581,8 @@ public: else m_breakpoint_locations.Clear(); - m_interpreter.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.comp_unit, + m_interpreter.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbers (target, + sc.comp_unit, m_options.start_line, 0, m_options.num_lines, diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp index 0e0ea053ef0..c765e6cb939 100644 --- a/lldb/source/Core/Disassembler.cpp +++ b/lldb/source/Core/Disassembler.cpp @@ -119,12 +119,13 @@ Disassembler::Disassemble const size_t count = sc_list.GetSize(); SymbolContext sc; AddressRange range; - + const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol; + const bool use_inline_block_range = true; for (size_t i=0; i<count; ++i) { if (sc_list.GetContextAtIndex(i, sc) == false) break; - if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range)) + for (uint32_t range_idx = 0; sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); ++range_idx) { if (Disassemble (debugger, arch, @@ -340,8 +341,11 @@ Disassembler::PrintInstructions SymbolContext prev_sc; AddressRange sc_range; Address *pc_addr_ptr = NULL; + ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope(); if (exe_ctx.frame) pc_addr_ptr = &exe_ctx.frame->GetFrameCodeAddress(); + const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol; + const bool use_inline_block_range = false; for (size_t i=0; i<num_instructions_found; ++i) { @@ -363,7 +367,7 @@ Disassembler::PrintInstructions { if (!sc_range.ContainsFileAddress (addr)) { - sc.GetAddressRange (eSymbolContextEverything, sc_range); + sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range); if (sc != prev_sc) { @@ -375,7 +379,8 @@ Disassembler::PrintInstructions if (sc.comp_unit && sc.line_entry.IsValid()) { - debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file, + debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (debugger.GetTargetList().GetSelectedTarget().get(), + sc.line_entry.file, sc.line_entry.line, num_mixed_context_lines, num_mixed_context_lines, @@ -390,12 +395,16 @@ Disassembler::PrintInstructions if (prev_sc.function || prev_sc.symbol) strm.EOL(); - strm << sc.module_sp->GetFileSpec().GetFilename(); + bool show_fullpaths = false; + bool show_module = true; + bool show_inlined_frames = true; + sc.DumpStopContext (&strm, + exe_scope, + addr, + show_fullpaths, + show_module, + show_inlined_frames); - if (sc.function) - strm << '`' << sc.function->GetMangled().GetName(); - else if (sc.symbol) - strm << '`' << sc.symbol->GetMangled().GetName(); strm << ":\n"; } } diff --git a/lldb/source/Core/SourceManager.cpp b/lldb/source/Core/SourceManager.cpp index 04a0d766c0f..ecea72daeec 100644 --- a/lldb/source/Core/SourceManager.cpp +++ b/lldb/source/Core/SourceManager.cpp @@ -16,6 +16,7 @@ #include "lldb/Core/DataBuffer.h" #include "lldb/Core/Stream.h" #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Target/Target.h" using namespace lldb_private; @@ -47,6 +48,7 @@ SourceManager::~SourceManager() size_t SourceManager::DisplaySourceLines ( + Target *target, const FileSpec &file_spec, uint32_t line, uint32_t context_before, @@ -54,7 +56,7 @@ SourceManager::DisplaySourceLines Stream *s ) { - m_last_file_sp = GetFile (file_spec); + m_last_file_sp = GetFile (file_spec, target); m_last_file_line = line + context_after + 1; m_last_file_context_before = context_before; m_last_file_context_after = context_after; @@ -65,7 +67,7 @@ SourceManager::DisplaySourceLines } SourceManager::FileSP -SourceManager::GetFile (const FileSpec &file_spec) +SourceManager::GetFile (const FileSpec &file_spec, Target *target) { FileSP file_sp; FileCache::iterator pos = m_file_cache.find(file_spec); @@ -73,7 +75,7 @@ SourceManager::GetFile (const FileSpec &file_spec) file_sp = pos->second; else { - file_sp.reset (new File (file_spec)); + file_sp.reset (new File (file_spec, target)); m_file_cache[file_spec] = file_sp; } return file_sp; @@ -149,6 +151,7 @@ SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile size_t SourceManager::DisplaySourceLinesWithLineNumbers ( + Target *target, const FileSpec &file_spec, uint32_t line, uint32_t context_before, @@ -161,7 +164,7 @@ SourceManager::DisplaySourceLinesWithLineNumbers bool same_as_previous = m_last_file_sp && m_last_file_sp->FileSpecMatches (file_spec); if (!same_as_previous) - m_last_file_sp = GetFile (file_spec); + m_last_file_sp = GetFile (file_spec, target); if (line == 0) { @@ -186,12 +189,21 @@ SourceManager::DisplayMoreWithLineNumbers (Stream *s, const SymbolContextList *b -SourceManager::File::File(const FileSpec &file_spec) : +SourceManager::File::File(const FileSpec &file_spec, Target *target) : + m_file_spec_orig (file_spec), m_file_spec(file_spec), - m_mod_time (m_file_spec.GetModificationTime()), - m_data_sp(file_spec.ReadFileContents ()), + m_mod_time (file_spec.GetModificationTime()), + m_data_sp(), m_offsets() { + if (!m_mod_time.IsValid()) + { + if (target->GetSourcePathMap().RemapPath(file_spec.GetDirectory(), m_file_spec.GetDirectory())) + m_mod_time = file_spec.GetModificationTime(); + } + + if (m_mod_time.IsValid()) + m_data_sp = m_file_spec.ReadFileContents (); } SourceManager::File::~File() diff --git a/lldb/source/Core/UserSettingsController.cpp b/lldb/source/Core/UserSettingsController.cpp index def41798ee8..ac50f29de83 100644 --- a/lldb/source/Core/UserSettingsController.cpp +++ b/lldb/source/Core/UserSettingsController.cpp @@ -737,8 +737,15 @@ UserSettingsController::CreateDefaultInstanceSettings () if (entry.var_type == eSetVarTypeEnum) value = entry.enum_values[0].string_value; - m_default_settings->UpdateInstanceSettingsVariable (var_name, NULL, value, default_name, entry, - eVarSetOperationAssign, err, true); + if (value != NULL) + m_default_settings->UpdateInstanceSettingsVariable (var_name, + NULL, + value, + default_name, + entry, + eVarSetOperationAssign, + err, + true); } } @@ -2026,6 +2033,75 @@ UserSettingsController::UpdateStringVariable (VarSetOperationType op, err.SetErrorString ("Unrecognized operation. Cannot update value.\n"); } +Error +UserSettingsController::UpdateStringOptionValue (const char *value, + VarSetOperationType op, + OptionValueString &option_value) +{ + Error error; + if (op == eVarSetOperationAssign) + { + option_value.SetCurrentValue (value); + } + else if (op == eVarSetOperationAppend) + { + option_value.AppendToCurrentValue (value); + } + else if (op == eVarSetOperationClear) + { + option_value.Clear(); + } + else + { + error.SetErrorString ("Unrecognized operation. Cannot update value.\n"); + } + return error; +} + +Error +UserSettingsController::UpdateFileSpecOptionValue (const char *value, + VarSetOperationType op, + OptionValueFileSpec &option_value) +{ + Error error; + if (op == eVarSetOperationAssign) + { + option_value.GetCurrentValue().SetFile (value, false); + } + else if (op == eVarSetOperationAppend) + { + char path[PATH_MAX]; + if (option_value.GetCurrentValue().GetPath (path, sizeof(path))) + { + int path_len = ::strlen (path); + int value_len = ::strlen (value); + if (value_len + 1 > sizeof(path) - path_len) + { + error.SetErrorString("path too long."); + } + else + { + ::strncat (path, value, sizeof(path) - path_len - 1); + option_value.GetCurrentValue().SetFile (path, false); + } + } + else + { + error.SetErrorString("path too long."); + } + } + else if (op == eVarSetOperationClear) + { + option_value.Clear(); + } + else + { + error.SetErrorString ("operation not supported for FileSpec option value type."); + } + return error; +} + + void UserSettingsController::UpdateBooleanVariable (VarSetOperationType op, bool &bool_value, @@ -2074,6 +2150,53 @@ UserSettingsController::UpdateBooleanVariable (VarSetOperationType op, break; } } +Error +UserSettingsController::UpdateBooleanOptionValue (const char *value, + VarSetOperationType op, + OptionValueBoolean &option_value) +{ + Error error; + switch (op) + { + case eVarSetOperationReplace: + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + default: + error.SetErrorString ("Invalid operation for Boolean variable. Cannot update value.\n"); + break; + + case eVarSetOperationClear: + option_value.Clear(); + break; + + case eVarSetOperationAssign: + { + bool success = false; + error = option_value.SetValueFromCString(value); + + if (value == NULL) + error.SetErrorStringWithFormat ("invalid boolean string value (NULL)\n", value); + else if (value[0] == '\0') + error.SetErrorStringWithFormat ("invalid boolean string value (empty)\n", value); + else + { + bool new_value = Args::StringToBoolean (value, false, &success); + if (success) + { + error.Clear(); + option_value = new_value; + } + else + error.SetErrorStringWithFormat ("invalid boolean string value: '%s'\n", value); + } + } + break; + } + return error; +} void UserSettingsController::UpdateStringArrayVariable (VarSetOperationType op, diff --git a/lldb/source/Host/common/FileSpec.cpp b/lldb/source/Host/common/FileSpec.cpp index d83b182e618..1b6a69b3ef8 100644 --- a/lldb/source/Host/common/FileSpec.cpp +++ b/lldb/source/Host/common/FileSpec.cpp @@ -39,7 +39,7 @@ static bool GetFileStats (const FileSpec *file_spec, struct stat *stats_ptr) { char resolved_path[PATH_MAX]; - if (file_spec->GetPath(&resolved_path[0], sizeof(resolved_path))) + if (file_spec->GetPath (resolved_path, sizeof(resolved_path))) return ::stat (resolved_path, stats_ptr) == 0; return false; } diff --git a/lldb/source/Interpreter/Args.cpp b/lldb/source/Interpreter/Args.cpp index 13ecd116adc..e7dd536c2c4 100644 --- a/lldb/source/Interpreter/Args.cpp +++ b/lldb/source/Interpreter/Args.cpp @@ -893,10 +893,13 @@ Args::StringToFormat case 'c': format = eFormatChar; break; case 'C': format = eFormatCharPrintable; break; case 'o': format = eFormatOctal; break; + case 'O': format = eFormatOSType; break; case 'i': case 'd': format = eFormatDecimal; break; + case 'I': format = eFormatComplexInteger; break; case 'u': format = eFormatUnsigned; break; case 'x': format = eFormatHex; break; + case 'X': format = eFormatComplex; break; case 'f': case 'e': case 'g': format = eFormatFloat; break; @@ -913,10 +916,14 @@ Args::StringToFormat " f - float\n" " g - float\n" " i - signed decimal\n" + " i - complex integer\n" " o - octal\n" + " O - OSType\n" + " p - pointer\n" " s - c-string\n" " u - unsigned decimal\n" " x - hex\n" + " X - complex float\n" " y - bytes\n" " Y - bytes with ASCII\n", s[0]); break; diff --git a/lldb/source/Interpreter/NamedOptionValue.cpp b/lldb/source/Interpreter/NamedOptionValue.cpp index 6b5dd7e3c0b..4721b9d47ed 100644 --- a/lldb/source/Interpreter/NamedOptionValue.cpp +++ b/lldb/source/Interpreter/NamedOptionValue.cpp @@ -156,7 +156,12 @@ OptionValueBoolean::SetValueFromCString (const char *value_cstr) } else { - error.SetErrorStringWithFormat ("invalid boolean string value: '%s'\n", value_cstr); + if (value_cstr == NULL) + error.SetErrorString ("invalid boolean string value: NULL\n"); + else if (value_cstr[0] == '\0') + error.SetErrorString ("invalid boolean string value <empty>\n"); + else + error.SetErrorStringWithFormat ("invalid boolean string value: '%s'\n", value_cstr); } return error; } @@ -303,17 +308,6 @@ OptionValueArray::SetValueFromCString (const char *value_cstr) return error; } - -uint64_t -OptionValueArray::GetUInt64ValueAtIndex (uint32_t idx, uint64_t fail_value, bool *success_ptr) const -{ - if (idx < m_values.size()) - return m_values[idx]->GetUInt64Value (fail_value, success_ptr); - return fail_value; -} - - - //------------------------------------------------------------------------- // OptionValueDictionary //------------------------------------------------------------------------- diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp index 104099450fa..d7edeeb5154 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp @@ -1215,7 +1215,7 @@ DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop AddressRange addr_range; if (target_symbols.GetContextAtIndex(0, context)) { - context.GetAddressRange (eSymbolContextEverything, addr_range); + context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range); thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addr_range.GetBaseAddress(), stop_others)); } else @@ -1234,7 +1234,7 @@ DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop AddressRange addr_range; if (target_symbols.GetContextAtIndex(i, context)) { - context.GetAddressRange (eSymbolContextEverything, addr_range); + context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range); lldb::addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(&thread.GetProcess().GetTarget()); addresses[i] = load_addr; } diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp index 077aa4df81a..4a27d3b63fd 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -92,7 +92,7 @@ RegisterContextLLDB::InitializeZerothFrame() m_sym_ctx = frame_sp->GetSymbolContext (eSymbolContextFunction | eSymbolContextSymbol); m_sym_ctx_valid = true; AddressRange addr_range; - m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, addr_range); + m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, addr_range); m_current_pc = frame_sp->GetFrameCodeAddress(); @@ -302,7 +302,7 @@ RegisterContextLLDB::InitializeNonZerothFrame() } AddressRange addr_range; - if (!m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, addr_range)) + if (!m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, addr_range)) { m_sym_ctx_valid = false; } @@ -339,7 +339,7 @@ RegisterContextLLDB::InitializeNonZerothFrame() { m_sym_ctx_valid = true; } - if (!m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, addr_range)) + if (!m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, addr_range)) { m_sym_ctx_valid = false; } diff --git a/lldb/source/Symbol/Block.cpp b/lldb/source/Symbol/Block.cpp index dbb727e9ac8..6827473be1c 100644 --- a/lldb/source/Symbol/Block.cpp +++ b/lldb/source/Symbol/Block.cpp @@ -160,9 +160,15 @@ Block::DumpStopContext bool show_fullpaths, bool show_inline_blocks) { - Block* parent_block = GetParent(); + const InlineFunctionInfo* inline_info = NULL; + Block* inlined_block; + if (sc_ptr) + inlined_block = GetContainingInlinedBlock (); + else + inlined_block = GetInlinedParent(); - const InlineFunctionInfo* inline_info = GetInlinedFunctionInfo (); + if (inlined_block) + inline_info = inlined_block->GetInlinedFunctionInfo(); const Declaration *inline_call_site = child_inline_call_site; if (inline_info) { @@ -176,7 +182,10 @@ Block::DumpStopContext s->EOL(); else s->PutChar(' '); - + + if (sc_ptr == NULL) + s->Indent(); + s->PutCString(inline_info->GetName ().AsCString()); if (child_inline_call_site && child_inline_call_site->IsValid()) @@ -186,6 +195,12 @@ Block::DumpStopContext } } + // The first call to this function from something that has a symbol + // context will pass in a valid sc_ptr. Subsequent calls to this function + // from this function for inline purposes will NULL out sc_ptr. So on the + // first time through we dump the line table entry (which is always at the + // deepest inline code block). And subsequent calls to this function we + // will use hte inline call site information to print line numbers. if (sc_ptr) { // If we have any inlined functions, this will be the deepest most @@ -199,13 +214,13 @@ Block::DumpStopContext if (show_inline_blocks) { - if (parent_block) + if (inlined_block) { - parent_block->Block::DumpStopContext (s, - NULL, - inline_call_site, - show_fullpaths, - show_inline_blocks); + inlined_block->Block::DumpStopContext (s, + NULL, + inline_call_site, + show_fullpaths, + show_inline_blocks); } else if (child_inline_call_site) { @@ -358,6 +373,23 @@ Block::GetRangeContainingAddress (const Address& addr, AddressRange &range) return false; } +bool +Block::GetRangeAtIndex (uint32_t range_idx, AddressRange &range) +{ + if (range_idx < m_ranges.size()) + { + SymbolContext sc; + CalculateSymbolContext(&sc); + if (sc.function) + { + range.GetBaseAddress() = sc.function->GetAddressRange().GetBaseAddress(); + range.GetBaseAddress().Slide(m_ranges[range_idx].GetBaseAddress ()); + range.SetByteSize (m_ranges[range_idx].GetByteSize()); + return true; + } + } + return false; +} bool Block::GetStartAddress (Address &addr) diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp index 717657b1ee1..135cf3b7a3d 100644 --- a/lldb/source/Symbol/SymbolContext.cpp +++ b/lldb/source/Symbol/SymbolContext.cpp @@ -343,36 +343,61 @@ lldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs) } bool -SymbolContext::GetAddressRange (uint32_t scope, AddressRange &range) const +SymbolContext::GetAddressRange (uint32_t scope, + uint32_t range_idx, + bool use_inline_block_range, + AddressRange &range) const { if ((scope & eSymbolContextLineEntry) && line_entry.IsValid()) { range = line_entry.range; return true; } - else if ((scope & eSymbolContextFunction) && function != NULL) + + if ((scope & eSymbolContextBlock) && (block != NULL)) { - range = function->GetAddressRange(); - return true; + if (use_inline_block_range) + { + Block *inline_block = block->GetContainingInlinedBlock(); + if (inline_block) + return inline_block->GetRangeAtIndex (range_idx, range); + } + else + { + return block->GetRangeAtIndex (range_idx, range); + } } - else if ((scope & eSymbolContextSymbol) && symbol != NULL && symbol->GetAddressRangePtr()) - { - range = *symbol->GetAddressRangePtr(); - if (range.GetByteSize() == 0) + if ((scope & eSymbolContextFunction) && (function != NULL)) + { + if (range_idx == 0) { - if (module_sp) + range = function->GetAddressRange(); + return true; + } + } + + if ((scope & eSymbolContextSymbol) && (symbol != NULL) && (symbol->GetAddressRangePtr() != NULL)) + { + if (range_idx == 0) + { + range = *symbol->GetAddressRangePtr(); + + if (range.GetByteSize() == 0) { - ObjectFile *objfile = module_sp->GetObjectFile(); - if (objfile) + if (module_sp) { - Symtab *symtab = objfile->GetSymtab(); - if (symtab) - range.SetByteSize(symtab->CalculateSymbolSize (symbol)); + ObjectFile *objfile = module_sp->GetObjectFile(); + if (objfile) + { + Symtab *symtab = objfile->GetSymtab(); + if (symtab) + range.SetByteSize(symtab->CalculateSymbolSize (symbol)); + } } } + return true; } - return true; } range.Clear(); return false; diff --git a/lldb/source/Symbol/UnwindTable.cpp b/lldb/source/Symbol/UnwindTable.cpp index d185655fcbf..3fe1ebb537f 100644 --- a/lldb/source/Symbol/UnwindTable.cpp +++ b/lldb/source/Symbol/UnwindTable.cpp @@ -94,7 +94,7 @@ UnwindTable::GetFuncUnwindersContainingAddress (const Address& addr, SymbolConte } AddressRange range; - if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range) || !range.GetBaseAddress().IsValid()) + if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0, false, range) || !range.GetBaseAddress().IsValid()) { // Does the eh_frame unwind info has a function bounds for this addr? if (m_eh_frame == NULL || !m_eh_frame->GetAddressRange (addr, range)) diff --git a/lldb/source/Target/PathMappingList.cpp b/lldb/source/Target/PathMappingList.cpp index 23eea225900..506742220b1 100644 --- a/lldb/source/Target/PathMappingList.cpp +++ b/lldb/source/Target/PathMappingList.cpp @@ -33,6 +33,28 @@ PathMappingList::PathMappingList { } + +PathMappingList::PathMappingList (const PathMappingList &rhs) : + m_pairs (rhs.m_pairs), + m_callback (NULL), + m_callback_baton (NULL) +{ + +} + +const PathMappingList & +PathMappingList::operator =(const PathMappingList &rhs) +{ + if (this != &rhs) + { + m_pairs = rhs.m_pairs; + m_callback = NULL; + m_callback_baton = NULL; + } + return *this; +} + + //---------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------- @@ -124,3 +146,91 @@ PathMappingList::RemapPath (const ConstString &path, ConstString &new_path) } return false; } + +bool +PathMappingList::Replace (const ConstString &path, const ConstString &new_path, bool notify) +{ + uint32_t idx = FindIndexForPath (path); + if (idx < m_pairs.size()) + { + m_pairs[idx].second = new_path; + if (notify && m_callback) + m_callback (*this, m_callback_baton); + return true; + } + return false; +} + +bool +PathMappingList::Remove (const ConstString &path, bool notify) +{ + iterator pos = FindIteratorForPath (path); + if (pos != m_pairs.end()) + { + m_pairs.erase (pos); + if (notify && m_callback) + m_callback (*this, m_callback_baton); + return true; + } + return false; +} + +PathMappingList::const_iterator +PathMappingList::FindIteratorForPath (const ConstString &path) const +{ + const_iterator pos; + const_iterator begin = m_pairs.begin(); + const_iterator end = m_pairs.end(); + + for (pos = begin; pos != end; ++pos) + { + if (pos->first == path) + break; + } + return pos; +} + +PathMappingList::iterator +PathMappingList::FindIteratorForPath (const ConstString &path) +{ + iterator pos; + iterator begin = m_pairs.begin(); + iterator end = m_pairs.end(); + + for (pos = begin; pos != end; ++pos) + { + if (pos->first == path) + break; + } + return pos; +} + +bool +PathMappingList::GetPathsAtIndex (uint32_t idx, ConstString &path, ConstString &new_path) const +{ + if (idx < m_pairs.size()) + { + path = m_pairs[idx].first; + new_path = m_pairs[idx].second; + return true; + } + return false; +} + + + +uint32_t +PathMappingList::FindIndexForPath (const ConstString &path) const +{ + const_iterator pos; + const_iterator begin = m_pairs.begin(); + const_iterator end = m_pairs.end(); + + for (pos = begin; pos != end; ++pos) + { + if (pos->first == path) + return std::distance (begin, pos); + } + return UINT32_MAX; +} + diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp index 1c49ca8f073..169497ad047 100644 --- a/lldb/source/Target/StackFrame.cpp +++ b/lldb/source/Target/StackFrame.cpp @@ -1013,7 +1013,9 @@ StackFrame::GetStatus (Stream& strm, if (m_sc.comp_unit && m_sc.line_entry.IsValid()) { - GetThread().GetProcess().GetTarget().GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbers ( + Target &target = GetThread().GetProcess().GetTarget(); + target.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbers ( + &target, m_sc.line_entry.file, m_sc.line_entry.line, 3, diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index abda39f44a0..11804798490 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -877,7 +877,9 @@ Target::UpdateInstanceName () const char * Target::GetExpressionPrefixContentsAsCString () { - return m_expr_prefix_contents.c_str(); + if (m_expr_prefix_contents_sp) + return (const char *)m_expr_prefix_contents_sp->GetBytes(); + return NULL; } ExecutionResults @@ -1291,13 +1293,13 @@ Target::SettingsController::CreateInstanceSettings (const char *instance_name) #define TSC_EXPR_PREFIX "expr-prefix" #define TSC_PREFER_DYNAMIC "prefer-dynamic-value" #define TSC_SKIP_PROLOGUE "skip-prologue" +#define TSC_SOURCE_MAP "source-map" static const ConstString & GetSettingNameForDefaultArch () { static ConstString g_const_string (TSC_DEFAULT_ARCH); - return g_const_string; } @@ -1315,6 +1317,12 @@ GetSettingNameForPreferDynamicValue () return g_const_string; } +static const ConstString & +GetSettingNameForSourcePathMap () +{ + static ConstString g_const_string (TSC_SOURCE_MAP); + return g_const_string; +} static const ConstString & GetSettingNameForSkipPrologue () @@ -1372,10 +1380,11 @@ TargetInstanceSettings::TargetInstanceSettings const char *name ) : InstanceSettings (owner, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance), - m_expr_prefix_path (), - m_expr_prefix_contents (), - m_prefer_dynamic_value (true), - m_skip_prologue (true) + m_expr_prefix_file (), + m_expr_prefix_contents_sp (), + m_prefer_dynamic_value (true, true), + m_skip_prologue (true, true), + m_source_map (NULL, NULL) { // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called // until the vtables for TargetInstanceSettings are properly set up, i.e. AFTER all the initializers. @@ -1396,7 +1405,12 @@ TargetInstanceSettings::TargetInstanceSettings } TargetInstanceSettings::TargetInstanceSettings (const TargetInstanceSettings &rhs) : - InstanceSettings (*Target::GetSettingsController(), CreateInstanceName().AsCString()) + InstanceSettings (*Target::GetSettingsController(), CreateInstanceName().AsCString()), + m_expr_prefix_file (rhs.m_expr_prefix_file), + m_expr_prefix_contents_sp (rhs.m_expr_prefix_contents_sp), + m_prefer_dynamic_value (rhs.m_prefer_dynamic_value), + m_skip_prologue (rhs.m_skip_prologue), + m_source_map (rhs.m_source_map) { if (m_instance_name != InstanceSettings::GetDefaultName()) { @@ -1431,53 +1445,100 @@ TargetInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_n { if (var_name == GetSettingNameForExpressionPrefix ()) { - switch (op) + err = UserSettingsController::UpdateFileSpecOptionValue (value, op, m_expr_prefix_file); + if (err.Success()) { - default: - err.SetErrorToGenericError (); - err.SetErrorString ("Unrecognized operation. Cannot update value.\n"); - return; - case eVarSetOperationAssign: + switch (op) { - FileSpec file_spec(value, true); - - if (!file_spec.Exists()) - { - err.SetErrorToGenericError (); - err.SetErrorStringWithFormat ("%s does not exist.\n", value); - return; - } - - DataBufferSP data_sp (file_spec.ReadFileContents()); - - if (!data_sp && data_sp->GetByteSize() == 0) + default: + break; + case eVarSetOperationAssign: + case eVarSetOperationAppend: { - err.SetErrorToGenericError (); - err.SetErrorStringWithFormat ("Couldn't read from %s\n", value); - return; + if (!m_expr_prefix_file.GetCurrentValue().Exists()) + { + err.SetErrorToGenericError (); + err.SetErrorStringWithFormat ("%s does not exist.\n", value); + return; + } + + m_expr_prefix_contents_sp = m_expr_prefix_file.GetCurrentValue().ReadFileContents(); + + if (!m_expr_prefix_contents_sp && m_expr_prefix_contents_sp->GetByteSize() == 0) + { + err.SetErrorStringWithFormat ("Couldn't read data from '%s'\n", value); + m_expr_prefix_contents_sp.reset(); + } } - - m_expr_prefix_path = value; - m_expr_prefix_contents.assign(reinterpret_cast<const char *>(data_sp->GetBytes()), data_sp->GetByteSize()); + break; + case eVarSetOperationClear: + m_expr_prefix_contents_sp.reset(); } - return; - case eVarSetOperationAppend: - err.SetErrorToGenericError (); - err.SetErrorString ("Cannot append to a path.\n"); - return; - case eVarSetOperationClear: - m_expr_prefix_path.clear (); - m_expr_prefix_contents.clear (); - return; } } else if (var_name == GetSettingNameForPreferDynamicValue()) { - UserSettingsController::UpdateBooleanVariable (op, m_prefer_dynamic_value, value, true, err); + err = UserSettingsController::UpdateBooleanOptionValue (value, op, m_prefer_dynamic_value); } else if (var_name == GetSettingNameForSkipPrologue()) { - UserSettingsController::UpdateBooleanVariable (op, m_skip_prologue, value, true, err); + err = UserSettingsController::UpdateBooleanOptionValue (value, op, m_skip_prologue); + } + else if (var_name == GetSettingNameForSourcePathMap ()) + { + switch (op) + { + case eVarSetOperationReplace: + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + default: + break; + case eVarSetOperationAssign: + m_source_map.Clear(true); + // Fall through to append.... + case eVarSetOperationAppend: + { + Args args(value); + const uint32_t argc = args.GetArgumentCount(); + if (argc & 1 || argc == 0) + { + err.SetErrorStringWithFormat ("an even number of paths must be supplied to to the source-map setting: %u arguments given", argc); + } + else + { + char resolved_new_path[PATH_MAX]; + FileSpec file_spec; + const char *old_path; + for (uint32_t idx = 0; (old_path = args.GetArgumentAtIndex(idx)) != NULL; idx += 2) + { + const char *new_path = args.GetArgumentAtIndex(idx+1); + assert (new_path); // We have an even number of paths, this shouldn't happen! + + file_spec.SetFile(new_path, true); + if (file_spec.Exists()) + { + if (file_spec.GetPath (resolved_new_path, sizeof(resolved_new_path)) >= sizeof(resolved_new_path)) + { + err.SetErrorStringWithFormat("new path '%s' is too long", new_path); + return; + } + } + else + { + err.SetErrorStringWithFormat("new path '%s' doesn't exist", new_path); + return; + } + m_source_map.Append(ConstString (old_path), ConstString (resolved_new_path), true); + } + } + } + break; + + case eVarSetOperationClear: + m_source_map.Clear(true); + break; + } } } @@ -1489,9 +1550,10 @@ TargetInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &ne if (!new_settings_ptr) return; - m_expr_prefix_path = new_settings_ptr->m_expr_prefix_path; - m_expr_prefix_contents = new_settings_ptr->m_expr_prefix_contents; - m_prefer_dynamic_value = new_settings_ptr->m_prefer_dynamic_value; + m_expr_prefix_file = new_settings_ptr->m_expr_prefix_file; + m_expr_prefix_contents_sp = new_settings_ptr->m_expr_prefix_contents_sp; + m_prefer_dynamic_value = new_settings_ptr->m_prefer_dynamic_value; + m_skip_prologue = new_settings_ptr->m_skip_prologue; } bool @@ -1502,7 +1564,10 @@ TargetInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry, { if (var_name == GetSettingNameForExpressionPrefix ()) { - value.AppendString (m_expr_prefix_path.c_str(), m_expr_prefix_path.size()); + char path[PATH_MAX]; + const size_t path_len = m_expr_prefix_file.GetCurrentValue().GetPath (path, sizeof(path)); + if (path_len > 0) + value.AppendString (path, path_len); } else if (var_name == GetSettingNameForPreferDynamicValue()) { @@ -1518,6 +1583,9 @@ TargetInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry, else value.AppendString ("false"); } + else if (var_name == GetSettingNameForSourcePathMap ()) + { + } else { if (err) @@ -1562,5 +1630,6 @@ Target::SettingsController::instance_settings_table[] = { TSC_EXPR_PREFIX , eSetVarTypeString , NULL , NULL, false, false, "Path to a file containing expressions to be prepended to all expressions." }, { TSC_PREFER_DYNAMIC, eSetVarTypeBoolean ,"true" , NULL, false, false, "Should printed values be shown as their dynamic value." }, { TSC_SKIP_PROLOGUE , eSetVarTypeBoolean ,"true" , NULL, false, false, "Skip function prologues when setting breakpoints by name." }, + { TSC_SOURCE_MAP , eSetVarTypeArray ,NULL , NULL, false, false, "Source path remappings to use when locating source files from debug information." }, { NULL , eSetVarTypeNone , NULL , NULL, false, false, NULL } }; |

