Fixed the SymbolContext::DumpStopContext() to correctly indent and dump
inline contexts when the deepest most block is not inlined.
Added source path remappings to the lldb_private::Target class that allow it
to remap paths found in debug info so we can find source files that are elsewhere
on the current system.
Fixed disassembly by function name to disassemble inline functions that are
inside other functions much better and to show enough context before the
disassembly output so you can tell where things came from.
Added the ability to get more than one address range from a SymbolContext
class for the case where a block or function has discontiguous address ranges.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@130044 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/API/SBSourceManager.cpp b/source/API/SBSourceManager.cpp
index 0fa98e3..16193dd 100644
--- a/source/API/SBSourceManager.cpp
+++ b/source/API/SBSourceManager.cpp
@@ -61,7 +61,8 @@
if (file.IsValid())
{
- return m_opaque_ptr->DisplaySourceLinesWithLineNumbers (*file,
+ return m_opaque_ptr->DisplaySourceLinesWithLineNumbers (NULL,
+ *file,
line,
context_before,
context_after,
diff --git a/source/Commands/CommandObjectRegister.cpp b/source/Commands/CommandObjectRegister.cpp
index 9c74c17..8005960 100644
--- a/source/Commands/CommandObjectRegister.cpp
+++ b/source/Commands/CommandObjectRegister.cpp
@@ -170,7 +170,7 @@
{
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/source/Commands/CommandObjectSource.cpp b/source/Commands/CommandObjectSource.cpp
index 40d35e5..ee55642 100644
--- a/source/Commands/CommandObjectSource.cpp
+++ b/source/Commands/CommandObjectSource.cpp
@@ -429,7 +429,8 @@
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 @@
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/source/Core/Disassembler.cpp b/source/Core/Disassembler.cpp
index 0e0ea05..c765e6c 100644
--- a/source/Core/Disassembler.cpp
+++ b/source/Core/Disassembler.cpp
@@ -119,12 +119,13 @@
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 @@
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 @@
{
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 @@
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 @@
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/source/Core/SourceManager.cpp b/source/Core/SourceManager.cpp
index 04a0d76..ecea72d 100644
--- a/source/Core/SourceManager.cpp
+++ b/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 @@
size_t
SourceManager::DisplaySourceLines
(
+ Target *target,
const FileSpec &file_spec,
uint32_t line,
uint32_t context_before,
@@ -54,7 +56,7 @@
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::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 @@
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 @@
size_t
SourceManager::DisplaySourceLinesWithLineNumbers
(
+ Target *target,
const FileSpec &file_spec,
uint32_t line,
uint32_t context_before,
@@ -161,7 +164,7 @@
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::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/source/Core/UserSettingsController.cpp b/source/Core/UserSettingsController.cpp
index def4179..ac50f29 100644
--- a/source/Core/UserSettingsController.cpp
+++ b/source/Core/UserSettingsController.cpp
@@ -737,8 +737,15 @@
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 @@
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 @@
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/source/Host/common/FileSpec.cpp b/source/Host/common/FileSpec.cpp
index d83b182..1b6a69b 100644
--- a/source/Host/common/FileSpec.cpp
+++ b/source/Host/common/FileSpec.cpp
@@ -39,7 +39,7 @@
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/source/Interpreter/Args.cpp b/source/Interpreter/Args.cpp
index 13ecd11..e7dd536 100644
--- a/source/Interpreter/Args.cpp
+++ b/source/Interpreter/Args.cpp
@@ -893,10 +893,13 @@
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 @@
" 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/source/Interpreter/NamedOptionValue.cpp b/source/Interpreter/NamedOptionValue.cpp
index 6b5dd7e..4721b9d 100644
--- a/source/Interpreter/NamedOptionValue.cpp
+++ b/source/Interpreter/NamedOptionValue.cpp
@@ -156,7 +156,12 @@
}
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 @@
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/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
index 1040994..d7edeeb 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
@@ -1215,7 +1215,7 @@
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 @@
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/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index 077aa4d..4a27d3b 100644
--- a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -92,7 +92,7 @@
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 @@
}
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 @@
{
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/source/Symbol/Block.cpp b/source/Symbol/Block.cpp
index dbb727e..6827473 100644
--- a/source/Symbol/Block.cpp
+++ b/source/Symbol/Block.cpp
@@ -160,9 +160,15 @@
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 @@
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 @@
}
}
+ // 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 @@
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 @@
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/source/Symbol/SymbolContext.cpp b/source/Symbol/SymbolContext.cpp
index 717657b..135cf3b 100644
--- a/source/Symbol/SymbolContext.cpp
+++ b/source/Symbol/SymbolContext.cpp
@@ -343,36 +343,61 @@
}
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;
- }
- else if ((scope & eSymbolContextSymbol) && symbol != NULL && symbol->GetAddressRangePtr())
- {
- range = *symbol->GetAddressRangePtr();
-
- if (range.GetByteSize() == 0)
+ if (use_inline_block_range)
{
- if (module_sp)
+ Block *inline_block = block->GetContainingInlinedBlock();
+ if (inline_block)
+ return inline_block->GetRangeAtIndex (range_idx, range);
+ }
+ else
+ {
+ return block->GetRangeAtIndex (range_idx, range);
+ }
+ }
+
+ if ((scope & eSymbolContextFunction) && (function != NULL))
+ {
+ if (range_idx == 0)
+ {
+ 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/source/Symbol/UnwindTable.cpp b/source/Symbol/UnwindTable.cpp
index d185655..3fe1ebb 100644
--- a/source/Symbol/UnwindTable.cpp
+++ b/source/Symbol/UnwindTable.cpp
@@ -94,7 +94,7 @@
}
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/source/Target/PathMappingList.cpp b/source/Target/PathMappingList.cpp
index 23eea22..5067422 100644
--- a/source/Target/PathMappingList.cpp
+++ b/source/Target/PathMappingList.cpp
@@ -33,6 +33,28 @@
{
}
+
+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 @@
}
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/source/Target/StackFrame.cpp b/source/Target/StackFrame.cpp
index 1c49ca8..169497a 100644
--- a/source/Target/StackFrame.cpp
+++ b/source/Target/StackFrame.cpp
@@ -1013,7 +1013,9 @@
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/source/Target/Target.cpp b/source/Target/Target.cpp
index abda39f..1180479 100644
--- a/source/Target/Target.cpp
+++ b/source/Target/Target.cpp
@@ -877,7 +877,9 @@
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 @@
#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 @@
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 @@
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 (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 @@
{
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())
+ default:
+ break;
+ case eVarSetOperationAssign:
+ case eVarSetOperationAppend:
{
- err.SetErrorToGenericError ();
- err.SetErrorStringWithFormat ("%s does not exist.\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();
+ }
}
-
- DataBufferSP data_sp (file_spec.ReadFileContents());
-
- if (!data_sp && data_sp->GetByteSize() == 0)
- {
- err.SetErrorToGenericError ();
- err.SetErrorStringWithFormat ("Couldn't read from %s\n", value);
- return;
- }
-
- 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 @@
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 @@
{
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 @@
else
value.AppendString ("false");
}
+ else if (var_name == GetSettingNameForSourcePathMap ())
+ {
+ }
else
{
if (err)
@@ -1562,5 +1630,6 @@
{ 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 }
};