diff --git a/lldb/include/lldb/Core/UserSettingsController.h b/lldb/include/lldb/Core/UserSettingsController.h index 1dfdaed12c55..c271268c01da 100644 --- a/lldb/include/lldb/Core/UserSettingsController.h +++ b/lldb/include/lldb/Core/UserSettingsController.h @@ -208,6 +208,7 @@ public: UpdateBooleanVariable (VarSetOperationType op, bool &bool_var, const char *new_value, + bool clear_value, // Used for op == eVarSetOperationClear Error &err); static void diff --git a/lldb/include/lldb/Interpreter/NamedOptionValue.h b/lldb/include/lldb/Interpreter/NamedOptionValue.h index d3001e63bed8..3204827d387f 100644 --- a/lldb/include/lldb/Interpreter/NamedOptionValue.h +++ b/lldb/include/lldb/Interpreter/NamedOptionValue.h @@ -60,11 +60,11 @@ namespace lldb_private { virtual void DumpValue (Stream &strm) = 0; - virtual bool + virtual Error SetValueFromCString (const char *value) = 0; virtual bool - ResetValueToDefault () = 0; + Clear () = 0; //----------------------------------------------------------------- // Subclasses should NOT override these functions as they use the @@ -76,6 +76,18 @@ namespace lldb_private { return 1u << GetType(); } + static uint32_t + ConvertTypeToMask (OptionValue::Type type) + { + return 1u << type; + } + + // Get this value as a uint64_t value if it is encoded as a boolean, + // uint64_t or int64_t. Other types will cause "fail_value" to be + // returned + uint64_t + GetUInt64Value (uint64_t fail_value, bool *success_ptr); + OptionValueBoolean * GetAsBooleanValue (); @@ -89,13 +101,21 @@ namespace lldb_private { GetAsStringValue (); OptionValueFileSpec * - GetAsFileSpecValue() ; + GetAsFileSpecValue(); OptionValueArray * - GetAsArrayValue() ; + GetAsArrayValue(); OptionValueDictionary * - GetAsDictionaryValue() ; + GetAsDictionaryValue(); + + protected: + bool m_value_was_set; // This can be used to see if a value has been set + // by a call to SetValueFromCString(). It is often + // handy to know if an option value was set from + // the command line or as a setting, versus if we + // just have the default value that was already + // populated in the option value. }; @@ -131,13 +151,14 @@ namespace lldb_private { virtual void DumpValue (Stream &strm); - virtual bool + virtual Error SetValueFromCString (const char *value); virtual bool - ResetValueToDefault () + Clear () { m_current_value = m_default_value; + m_value_was_set = false; return true; } @@ -145,6 +166,26 @@ namespace lldb_private { // Subclass specific functions //--------------------------------------------------------------------- + //------------------------------------------------------------------ + /// Convert to bool operator. + /// + /// This allows code to check a OptionValueBoolean in conditions. + /// + /// @code + /// OptionValueBoolean bool_value(...); + /// if (bool_value) + /// { ... + /// @endcode + /// + /// @return + /// /b True this object contains a valid namespace decl, \b + /// false otherwise. + //------------------------------------------------------------------ + operator bool() const + { + return m_current_value; + } + bool GetCurrentValue() const { @@ -180,10 +221,16 @@ namespace lldb_private { class OptionValueSInt64 : public OptionValue { public: + OptionValueSInt64 () : + m_current_value (0), + m_default_value (0) + { + } + OptionValueSInt64 (int64_t current_value, int64_t default_value) : - m_current_value (current_value), - m_default_value (default_value) + m_current_value (current_value), + m_default_value (default_value) { } @@ -205,13 +252,14 @@ namespace lldb_private { virtual void DumpValue (Stream &strm); - virtual bool + virtual Error SetValueFromCString (const char *value); virtual bool - ResetValueToDefault () + Clear () { m_current_value = m_default_value; + m_value_was_set = false; return true; } @@ -254,10 +302,16 @@ namespace lldb_private { class OptionValueUInt64 : public OptionValue { public: + OptionValueUInt64 () : + m_current_value (0), + m_default_value (0) + { + } + OptionValueUInt64 (uint64_t current_value, uint64_t default_value) : - m_current_value (current_value), - m_default_value (default_value) + m_current_value (current_value), + m_default_value (default_value) { } @@ -266,6 +320,14 @@ namespace lldb_private { { } + //--------------------------------------------------------------------- + // Decode a uint64_t from "value_cstr" return a OptionValueUInt64 object + // inside of a lldb::OptionValueSP object if all goes well. If the + // string isn't a uint64_t value or any other error occurs, return an + // empty lldb::OptionValueSP and fill error in with the correct stuff. + //--------------------------------------------------------------------- + static lldb::OptionValueSP + Create (const char *value_cstr, Error &error); //--------------------------------------------------------------------- // Virtual subclass pure virtual overrides //--------------------------------------------------------------------- @@ -279,13 +341,14 @@ namespace lldb_private { virtual void DumpValue (Stream &strm); - virtual bool + virtual Error SetValueFromCString (const char *value); virtual bool - ResetValueToDefault () + Clear () { m_current_value = m_default_value; + m_value_was_set = false; return true; } @@ -363,13 +426,14 @@ namespace lldb_private { virtual void DumpValue (Stream &strm); - virtual bool + virtual Error SetValueFromCString (const char *value); virtual bool - ResetValueToDefault () + Clear () { m_current_value = m_default_value; + m_value_was_set = false; return true; } @@ -455,13 +519,14 @@ namespace lldb_private { virtual void DumpValue (Stream &strm); - virtual bool + virtual Error SetValueFromCString (const char *value); virtual bool - ResetValueToDefault () + Clear () { m_current_value = m_default_value; + m_value_was_set = false; return true; } @@ -528,13 +593,14 @@ namespace lldb_private { virtual void DumpValue (Stream &strm); - virtual bool + virtual Error SetValueFromCString (const char *value); virtual bool - ResetValueToDefault () + Clear () { m_values.clear(); + m_value_was_set = false; return true; } @@ -543,7 +609,7 @@ namespace lldb_private { //--------------------------------------------------------------------- uint32_t - GetNumValues() const + GetSize () const { return m_values.size(); } @@ -557,6 +623,11 @@ 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) { @@ -652,13 +723,14 @@ namespace lldb_private { virtual void DumpValue (Stream &strm); - virtual bool + virtual Error SetValueFromCString (const char *value); virtual bool - ResetValueToDefault () + Clear () { m_values.clear(); + m_value_was_set = false; return true; } diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 0fd68f4aabfd..2c9e4a6a2642 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -71,7 +71,13 @@ public: { return m_prefer_dynamic_value; } - + + bool + GetSkipPrologue() + { + return m_skip_prologue; + } + protected: void @@ -84,6 +90,7 @@ protected: std::string m_expr_prefix_path; std::string m_expr_prefix_contents; bool m_prefer_dynamic_value; + bool m_skip_prologue; }; diff --git a/lldb/scripts/build-llvm.pl b/lldb/scripts/build-llvm.pl index 37874059422a..267eb943766c 100644 --- a/lldb/scripts/build-llvm.pl +++ b/lldb/scripts/build-llvm.pl @@ -83,7 +83,7 @@ our @archive_files = ( "$llvm_configuration/lib/libLLVMX86Utils.a", ); -if (-e "$llvm_srcroot/lib") +if ($ENV{CONFIGURATION} ne "BuildAndIntegration" and -e "$llvm_srcroot/lib") { print "Using standard LLVM build directory...\n"; # LLVM in the "lldb" root is a symlink which indicates we are using a diff --git a/lldb/source/Breakpoint/BreakpointResolverName.cpp b/lldb/source/Breakpoint/BreakpointResolverName.cpp index f244e3b56dee..87acb521bd08 100644 --- a/lldb/source/Breakpoint/BreakpointResolverName.cpp +++ b/lldb/source/Breakpoint/BreakpointResolverName.cpp @@ -16,7 +16,7 @@ #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Log.h" #include "lldb/Core/StreamString.h" -#include "lldb/lldb-private-log.h" +#include "lldb/Target/Target.h" using namespace lldb; using namespace lldb_private; @@ -146,6 +146,11 @@ BreakpointResolverName::SearchCallback Address break_addr; assert (m_breakpoint != NULL); + if (context.target_sp) + { + skip_prologue = context.target_sp->GetSkipPrologue(); + } + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); if (m_class_name) diff --git a/lldb/source/Commands/CommandObjectImage.cpp b/lldb/source/Commands/CommandObjectImage.cpp index ae1612e4cf69..080d16bb5d18 100644 --- a/lldb/source/Commands/CommandObjectImage.cpp +++ b/lldb/source/Commands/CommandObjectImage.cpp @@ -324,7 +324,7 @@ LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *mod static void -DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolContextList &sc_list, bool prepend_addr) +DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolContextList &sc_list, bool prepend_addr, bool verbose) { strm.IndentMore (); uint32_t i; @@ -336,31 +336,50 @@ DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolCont if (sc_list.GetContextAtIndex(i, sc)) { strm.Indent(); + ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope (); + if (prepend_addr) { if (sc.line_entry.range.GetBaseAddress().IsValid()) { - lldb::addr_t vm_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(interpreter.GetExecutionContext().target); - int addr_size = sizeof (addr_t); - Process *process = interpreter.GetExecutionContext().process; - if (process) - addr_size = process->GetTarget().GetArchitecture().GetAddressByteSize(); - if (vm_addr != LLDB_INVALID_ADDRESS) - strm.Address (vm_addr, addr_size); - else - sc.line_entry.range.GetBaseAddress().Dump (&strm, NULL, Address::DumpStyleSectionNameOffset); - + sc.line_entry.range.GetBaseAddress().Dump (&strm, + exe_scope, + Address::DumpStyleLoadAddress, + Address::DumpStyleModuleWithFileAddress); strm.PutCString(" in "); } } - sc.DumpStopContext(&strm, interpreter.GetExecutionContext().process, sc.line_entry.range.GetBaseAddress(), true, true, false); + sc.DumpStopContext(&strm, + exe_scope, + sc.line_entry.range.GetBaseAddress(), + true, + true, + false); + strm.EOL(); + if (verbose) + { + if (sc.line_entry.range.GetBaseAddress().IsValid()) + { + if (sc.line_entry.range.GetBaseAddress().Dump (&strm, + exe_scope, + Address::DumpStyleDetailedSymbolContext)) + strm.PutCString("\n\n"); + } + else if (sc.function->GetAddressRange().GetBaseAddress().IsValid()) + { + if (sc.function->GetAddressRange().GetBaseAddress().Dump (&strm, + exe_scope, + Address::DumpStyleDetailedSymbolContext)) + strm.PutCString("\n\n"); + } + } } } strm.IndentLess (); } static uint32_t -LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex) +LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose) { if (module && name && name[0]) { @@ -392,7 +411,7 @@ LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *m strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); DumpFullpath (strm, &module->GetFileSpec(), 0); strm.PutCString(":\n"); - DumpSymbolContextList (interpreter, strm, sc_list, true); + DumpSymbolContextList (interpreter, strm, sc_list, true, verbose); } return num_matches; } @@ -457,7 +476,13 @@ LookupTypeInModule } static uint32_t -LookupFileAndLineInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const FileSpec &file_spec, uint32_t line, bool check_inlines) +LookupFileAndLineInModule (CommandInterpreter &interpreter, + Stream &strm, + Module *module, + const FileSpec &file_spec, + uint32_t line, + bool check_inlines, + bool verbose) { if (module && file_spec) { @@ -474,7 +499,7 @@ LookupFileAndLineInModule (CommandInterpreter &interpreter, Stream &strm, Module strm << " in "; DumpFullpath (strm, &module->GetFileSpec(), 0); strm.PutCString(":\n"); - DumpSymbolContextList (interpreter, strm, sc_list, true); + DumpSymbolContextList (interpreter, strm, sc_list, true, verbose); return num_matches; } } @@ -1550,7 +1575,8 @@ public: module, m_options.m_file, m_options.m_line_number, - m_options.m_check_inlines)) + m_options.m_check_inlines, + m_options.m_verbose)) { result.SetStatus(eReturnStatusSuccessFinishResult); return true; @@ -1565,7 +1591,8 @@ public: result.GetOutputStream(), module, m_options.m_str.c_str(), - m_options.m_use_regex)) + m_options.m_use_regex, + m_options.m_verbose)) { result.SetStatus(eReturnStatusSuccessFinishResult); return true; diff --git a/lldb/source/Commands/CommandObjectRegister.cpp b/lldb/source/Commands/CommandObjectRegister.cpp index d3c8d63be015..9c74c1711f37 100644 --- a/lldb/source/Commands/CommandObjectRegister.cpp +++ b/lldb/source/Commands/CommandObjectRegister.cpp @@ -19,6 +19,7 @@ #include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/NamedOptionValue.h" #include "lldb/Interpreter/Options.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/RegisterContext.h" @@ -66,6 +67,85 @@ public: return &m_options; } + bool + DumpRegister (const ExecutionContext &exe_ctx, + Stream &strm, + RegisterContext *reg_ctx, + const RegisterInfo *reg_info) + { + if (reg_info) + { + uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; + + DataExtractor reg_data; + + if (reg_ctx->ReadRegisterBytes(reg, reg_data)) + { + strm.Indent (); + strm.Printf ("%-12s = ", reg_info ? reg_info->name : ""); + Format format; + if (m_options.format == eFormatDefault) + format = reg_info->format; + else + format = m_options.format; + + reg_data.Dump(&strm, 0, format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); + if (m_options.lookup_addresses && ((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint))) + { + addr_t reg_addr = reg_ctx->ReadRegisterAsUnsigned (reg, 0); + if (reg_addr) + { + Address so_reg_addr; + if (exe_ctx.target->GetSectionLoadList().ResolveLoadAddress(reg_addr, so_reg_addr)) + { + strm.PutCString (" "); + so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription); + } + else + { + } + } + } + strm.EOL(); + return true; + } + } + return false; + } + + bool + DumpRegisterSet (const ExecutionContext &exe_ctx, + Stream &strm, + RegisterContext *reg_ctx, + uint32_t set_idx) + { + uint32_t unavailable_count = 0; + uint32_t available_count = 0; + const RegisterSet * const reg_set = reg_ctx->GetRegisterSet(set_idx); + if (reg_set) + { + strm.Printf ("%s:\n", reg_set->name); + strm.IndentMore (); + const uint32_t num_registers = reg_set->num_registers; + for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) + { + const uint32_t reg = reg_set->registers[reg_idx]; + if (DumpRegister (exe_ctx, strm, reg_ctx, reg_ctx->GetRegisterInfoAtIndex(reg))) + ++available_count; + else + ++unavailable_count; + } + strm.IndentLess (); + if (unavailable_count) + { + strm.Indent (); + strm.Printf("%u registers were unavailable.\n", unavailable_count); + } + strm.EOL(); + } + return available_count > 0; + } + virtual bool Execute ( @@ -73,73 +153,80 @@ public: CommandReturnObject &result ) { - Stream &output_stream = result.GetOutputStream(); - DataExtractor reg_data; + Stream &strm = result.GetOutputStream(); ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - RegisterContext *reg_context = exe_ctx.GetRegisterContext (); + RegisterContext *reg_ctx = exe_ctx.GetRegisterContext (); - if (reg_context) + if (reg_ctx) { const RegisterInfo *reg_info = NULL; if (command.GetArgumentCount() == 0) { uint32_t set_idx; - const uint32_t num_register_sets = reg_context->GetRegisterSetCount(); - for (set_idx = 0; set_idx < num_register_sets; ++set_idx) + + uint32_t num_register_sets = 1; + const uint32_t set_array_size = m_options.set_indexes.GetSize(); + if (set_array_size > 0) { - uint32_t unavailable_count = 0; - const RegisterSet * const reg_set = reg_context->GetRegisterSet(set_idx); - output_stream.Printf ("%s:\n", reg_set->name); - output_stream.IndentMore (); - const uint32_t num_registers = reg_set->num_registers; - for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) + for (uint32_t i=0; iregisters[reg_idx]; - reg_info = reg_context->GetRegisterInfoAtIndex(reg); - if (reg_context->ReadRegisterBytes(reg, reg_data)) + set_idx = m_options.set_indexes.GetUInt64ValueAtIndex (i, UINT32_MAX, NULL); + if (set_idx != UINT32_MAX) { - output_stream.Indent (); - output_stream.Printf ("%-12s = ", reg_info ? reg_info->name : ""); - reg_data.Dump(&output_stream, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); - output_stream.EOL(); + if (!DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx)) + { + result.AppendErrorWithFormat ("invalid register set index: %u\n", set_idx); + result.SetStatus (eReturnStatusFailed); + break; + } } else { - ++unavailable_count; + result.AppendError ("invalid register set index\n"); + result.SetStatus (eReturnStatusFailed); + break; } } - if (unavailable_count) + } + else + { + if (m_options.dump_all_sets) + num_register_sets = reg_ctx->GetRegisterSetCount(); + + for (set_idx = 0; set_idx < num_register_sets; ++set_idx) { - output_stream.Indent (); - output_stream.Printf("%u registers were unavailable.\n", unavailable_count); + DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx); } - output_stream.IndentLess (); - output_stream.EOL(); } } else { - const char *arg_cstr; - for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) + if (m_options.dump_all_sets) { - reg_info = reg_context->GetRegisterInfoByName(arg_cstr); - - if (reg_info) + result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n"); + result.SetStatus (eReturnStatusFailed); + } + else if (m_options.set_indexes.GetSize() > 0) + { + result.AppendError ("the --set option can't be used when registers names are supplied as arguments\n"); + result.SetStatus (eReturnStatusFailed); + } + else + { + const char *arg_cstr; + for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) { - output_stream.Printf("%-12s = ", reg_info->name); - if (reg_context->ReadRegisterBytes(reg_info->kinds[eRegisterKindLLDB], reg_data)) + reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr); + + if (reg_info) { - reg_data.Dump(&output_stream, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); + if (!DumpRegister (exe_ctx, strm, reg_ctx, reg_info)) + strm.Printf("%-12s = error: unavailable\n", reg_info->name); } else { - output_stream.PutCString ("error: unavailable"); + result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr); } - output_stream.EOL(); - } - else - { - result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr); } } } @@ -157,7 +244,10 @@ protected: { public: CommandOptions (CommandInterpreter &interpreter) : - Options(interpreter) + Options(interpreter), + set_indexes (OptionValue::ConvertTypeToMask (OptionValue::eTypeUInt64)), + dump_all_sets (false, false), // Initial and default values are false + lookup_addresses (false, false) // Initial and default values are false { OptionParsingStarting(); } @@ -175,9 +265,25 @@ protected: switch (short_option) { case 'f': - error = Args::StringToFormat (option_arg, m_format); + error = Args::StringToFormat (option_arg, format); break; - + + case 's': + { + OptionValueSP value_sp (OptionValueUInt64::Create (option_arg, error)); + if (value_sp) + set_indexes.AppendValue (value_sp); + } + break; + + case 'a': + dump_all_sets.SetCurrentValue(true); + break; + + case 'l': + lookup_addresses.SetCurrentValue(true); + break; + default: error.SetErrorStringWithFormat("Unrecognized short option '%c'\n", short_option); break; @@ -188,7 +294,10 @@ protected: void OptionParsingStarting () { - m_format = eFormatBytes; + format = eFormatDefault; + set_indexes.Clear(); + dump_all_sets.Clear(); + lookup_addresses.Clear(); } const OptionDefinition* @@ -202,7 +311,10 @@ protected: static OptionDefinition g_option_table[]; // Instance variables to hold the values for command options. - lldb::Format m_format; + lldb::Format format; + OptionValueArray set_indexes; + OptionValueBoolean dump_all_sets; + OptionValueBoolean lookup_addresses; }; CommandOptions m_options; @@ -211,13 +323,10 @@ protected: OptionDefinition CommandObjectRegisterRead::CommandOptions::g_option_table[] = { - //{ LLDB_OPT_SET_ALL, false, "language", 'l', required_argument, NULL, 0, "[c|c++|objc|objc++]", "Sets the language to use when parsing the expression."}, - //{ LLDB_OPT_SET_1, false, "format", 'f', required_argument, NULL, 0, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]", "Specify the format that the expression output should use."}, - { LLDB_OPT_SET_1, false, "format", 'f', required_argument, NULL, 0, eArgTypeExprFormat, "Specify the format that the expression output should use."}, - { LLDB_OPT_SET_2, false, "object-description", 'o', no_argument, NULL, 0, eArgTypeNone, "Print the object description of the value resulting from the expression."}, - { LLDB_OPT_SET_ALL, false, "unwind-on-error", 'u', required_argument, NULL, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, breakpoint hit or signal."}, - { LLDB_OPT_SET_ALL, false, "debug", 'g', no_argument, NULL, 0, eArgTypeNone, "Enable verbose debug logging of the expression parsing and evaluation."}, - { LLDB_OPT_SET_ALL, false, "use-ir", 'i', no_argument, NULL, 0, eArgTypeNone, "[Temporary] Instructs the expression evaluator to use IR instead of ASTs."}, + { LLDB_OPT_SET_ALL, false, "format", 'f', required_argument, NULL, 0, eArgTypeExprFormat, "Specify the format to use when dumping register values."}, + { LLDB_OPT_SET_ALL, false, "lookup", 'l', no_argument , NULL, 0, eArgTypeNone , "Lookup the register values as addresses and show that each value maps to in the address space."}, + { LLDB_OPT_SET_1 , false, "set" , 's', required_argument, NULL, 0, eArgTypeIndex , "Specify which register sets to dump by index."}, + { LLDB_OPT_SET_2 , false, "all" , 'a', no_argument , NULL, 0, eArgTypeNone , "Show all register sets."}, { 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL } }; @@ -275,9 +384,9 @@ public: { DataExtractor reg_data; ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - RegisterContext *reg_context = exe_ctx.GetRegisterContext (); + RegisterContext *reg_ctx = exe_ctx.GetRegisterContext (); - if (reg_context) + if (reg_ctx) { if (command.GetArgumentCount() != 2) { @@ -288,7 +397,7 @@ public: { const char *reg_name = command.GetArgumentAtIndex(0); const char *value_str = command.GetArgumentAtIndex(1); - const RegisterInfo *reg_info = reg_context->GetRegisterInfoByName(reg_name); + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name); if (reg_info) { @@ -296,7 +405,7 @@ public: Error error(scalar.SetValueFromCString (value_str, reg_info->encoding, reg_info->byte_size)); if (error.Success()) { - if (reg_context->WriteRegisterValue(reg_info->kinds[eRegisterKindLLDB], scalar)) + if (reg_ctx->WriteRegisterValue(reg_info->kinds[eRegisterKindLLDB], scalar)) { result.SetStatus (eReturnStatusSuccessFinishNoResult); return true; diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 073986ac3a90..f1a64b982090 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -1439,11 +1439,11 @@ DebuggerInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var } else if (var_name == UseExternalEditorVarName ()) { - UserSettingsController::UpdateBooleanVariable (op, m_use_external_editor, value, err); + UserSettingsController::UpdateBooleanVariable (op, m_use_external_editor, value, false, err); } else if (var_name == AutoConfirmName ()) { - UserSettingsController::UpdateBooleanVariable (op, m_auto_confirm_on, value, err); + UserSettingsController::UpdateBooleanVariable (op, m_auto_confirm_on, value, false, err); } } diff --git a/lldb/source/Core/Mangled.cpp b/lldb/source/Core/Mangled.cpp index 3452bc030f49..110fa6562811 100644 --- a/lldb/source/Core/Mangled.cpp +++ b/lldb/source/Core/Mangled.cpp @@ -109,15 +109,23 @@ Mangled::Compare (const Mangled& a, const Mangled& b) void Mangled::SetValue (const char *s, bool mangled) { - m_mangled.Clear(); - m_demangled.Clear(); - if (s) { if (mangled) + { + m_demangled.Clear(); m_mangled.SetCString (s); + } else + { m_demangled.SetCString(s); + m_mangled.Clear(); + } + } + else + { + m_demangled.Clear(); + m_mangled.Clear(); } } diff --git a/lldb/source/Core/UserSettingsController.cpp b/lldb/source/Core/UserSettingsController.cpp index da1b49b7a7d2..def41798ee8d 100644 --- a/lldb/source/Core/UserSettingsController.cpp +++ b/lldb/source/Core/UserSettingsController.cpp @@ -2028,32 +2028,51 @@ UserSettingsController::UpdateStringVariable (VarSetOperationType op, void UserSettingsController::UpdateBooleanVariable (VarSetOperationType op, - bool &bool_var, - const char *new_value, + bool &bool_value, + const char *value_cstr, + bool clear_value, Error &err) { - if (op != eVarSetOperationAssign) - err.SetErrorString ("Invalid operation for Boolean variable. Cannot update value.\n"); - - if (new_value && new_value[0]) + switch (op) { - if ((::strcasecmp(new_value, "true") == 0) || - (::strcasecmp(new_value, "yes") == 0) || - (::strcasecmp(new_value, "on") == 0) || - (::strcasecmp(new_value, "1") == 0)) - bool_var = true; - else - if ((::strcasecmp(new_value, "false") == 0) || - (::strcasecmp(new_value, "no") == 0) || - (::strcasecmp(new_value, "off") == 0) || - (::strcasecmp(new_value, "0") == 0)) - bool_var = false; - else - err.SetErrorStringWithFormat ("Invalid boolean value '%s'\n", new_value); - } - else - err.SetErrorString ("Invalid value. Cannot perform update.\n"); + case eVarSetOperationReplace: + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + default: + err.SetErrorString ("Invalid operation for Boolean variable. Cannot update value.\n"); + break; + case eVarSetOperationClear: + err.Clear(); + bool_value = clear_value; + break; + + case eVarSetOperationAssign: + { + bool success = false; + + + if (value_cstr == NULL) + err.SetErrorStringWithFormat ("invalid boolean string value (NULL)\n", value_cstr); + else if (value_cstr[0] == '\0') + err.SetErrorStringWithFormat ("invalid boolean string value (empty)\n", value_cstr); + else + { + bool new_value = Args::StringToBoolean (value_cstr, false, &success); + if (success) + { + err.Clear(); + bool_value = new_value; + } + else + err.SetErrorStringWithFormat ("invalid boolean string value: '%s'\n", value_cstr); + } + } + break; + } } void diff --git a/lldb/source/Interpreter/NamedOptionValue.cpp b/lldb/source/Interpreter/NamedOptionValue.cpp index 987ab472aaa3..7c1284f8067c 100644 --- a/lldb/source/Interpreter/NamedOptionValue.cpp +++ b/lldb/source/Interpreter/NamedOptionValue.cpp @@ -23,6 +23,29 @@ using namespace lldb_private; //------------------------------------------------------------------------- // OptionValue //------------------------------------------------------------------------- + +// Get this value as a uint64_t value if it is encoded as a boolean, +// uint64_t or int64_t. Other types will cause "fail_value" to be +// returned +uint64_t +OptionValue::GetUInt64Value (uint64_t fail_value, bool *success_ptr) +{ + if (success_ptr) + *success_ptr = true; + switch (GetType()) + { + case OptionValue::eTypeBoolean: return static_cast(this)->GetCurrentValue(); + case OptionValue::eTypeSInt64: return static_cast(this)->GetCurrentValue(); + case OptionValue::eTypeUInt64: return static_cast(this)->GetCurrentValue(); + default: + break; + } + if (success_ptr) + *success_ptr = false; + return fail_value; +} + + OptionValueBoolean * OptionValue::GetAsBooleanValue () { @@ -105,17 +128,22 @@ OptionValueBoolean::DumpValue (Stream &strm) strm.PutCString (m_current_value ? "true" : "false"); } -bool +Error OptionValueBoolean::SetValueFromCString (const char *value_cstr) { + Error error; bool success = false; bool value = Args::StringToBoolean(value_cstr, false, &success); if (success) { + m_value_was_set = true; m_current_value = value; - return true; } - return false; + else + { + error.SetErrorStringWithFormat ("invalid boolean string value: '%s'\n", value_cstr); + } + return error; } //------------------------------------------------------------------------- @@ -127,39 +155,62 @@ OptionValueSInt64::DumpValue (Stream &strm) strm.Printf ("%lli", m_current_value); } -bool +Error OptionValueSInt64::SetValueFromCString (const char *value_cstr) { + + Error error; bool success = false; int64_t value = Args::StringToSInt64 (value_cstr, 0, 0, &success); if (success) { + m_value_was_set = true; m_current_value = value; - return true; } - return false; + else + { + error.SetErrorStringWithFormat ("invalid int64_t string value: '%s'\n", value_cstr); + } + return error; } //------------------------------------------------------------------------- // OptionValueUInt64 //------------------------------------------------------------------------- + +lldb::OptionValueSP +OptionValueUInt64::Create (const char *value_cstr, Error &error) +{ + lldb::OptionValueSP value_sp (new OptionValueUInt64()); + error = value_sp->SetValueFromCString (value_cstr); + if (error.Fail()) + value_sp.reset(); + return value_sp; +} + + void OptionValueUInt64::DumpValue (Stream &strm) { strm.Printf ("0x%llx", m_current_value); } -bool +Error OptionValueUInt64::SetValueFromCString (const char *value_cstr) { + Error error; bool success = false; uint64_t value = Args::StringToUInt64 (value_cstr, 0, 0, &success); if (success) { + m_value_was_set = true; m_current_value = value; - return true; } - return false; + else + { + error.SetErrorStringWithFormat ("invalid uint64_t string value: '%s'\n", value_cstr); + } + return error; } //------------------------------------------------------------------------- @@ -171,11 +222,12 @@ OptionValueString::DumpValue (Stream &strm) strm.Printf ("\"%s\"", m_current_value.c_str()); } -bool +Error OptionValueString::SetValueFromCString (const char *value_cstr) { + m_value_was_set = true; SetCurrentValue (value_cstr); - return true; + return Error (); } @@ -202,14 +254,15 @@ OptionValueFileSpec::DumpValue (Stream &strm) } } -bool +Error OptionValueFileSpec::SetValueFromCString (const char *value_cstr) { if (value_cstr && value_cstr[0]) m_current_value.SetFile(value_cstr, false); else m_current_value.Clear(); - return true; + m_value_was_set = true; + return Error(); } @@ -227,13 +280,25 @@ OptionValueArray::DumpValue (Stream &strm) } } -bool +Error OptionValueArray::SetValueFromCString (const char *value_cstr) { - // We must be able to set this using the array specific functions - return false; + Error error; + error.SetErrorStringWithFormat ("array option values don't yet support being set by string: '%s'\n", 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 //------------------------------------------------------------------------- @@ -249,11 +314,12 @@ OptionValueDictionary::DumpValue (Stream &strm) } } -bool +Error OptionValueDictionary::SetValueFromCString (const char *value_cstr) { - // We must be able to set this using the array specific functions - return false; + Error error; + error.SetErrorStringWithFormat ("dictionary option values don't yet support being set by string: '%s'\n", value_cstr); + return error; } lldb::OptionValueSP diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index b0037bf0ef91..5ad5ac22445c 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -4062,9 +4062,9 @@ ProcessInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_ else if (var_name == ErrorPathVarName()) UserSettingsController::UpdateStringVariable (op, m_error_path, value, err); else if (var_name == DisableASLRVarName()) - UserSettingsController::UpdateBooleanVariable (op, m_disable_aslr, value, err); + UserSettingsController::UpdateBooleanVariable (op, m_disable_aslr, value, true, err); else if (var_name == DisableSTDIOVarName ()) - UserSettingsController::UpdateBooleanVariable (op, m_disable_stdio, value, err); + UserSettingsController::UpdateBooleanVariable (op, m_disable_stdio, value, false, err); } void diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 1dadb50e856a..3a1ae1e0102b 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -1290,6 +1290,7 @@ Target::SettingsController::CreateInstanceSettings (const char *instance_name) #define TSC_DEFAULT_ARCH "default-arch" #define TSC_EXPR_PREFIX "expr-prefix" #define TSC_PREFER_DYNAMIC "prefer-dynamic-value" +#define TSC_SKIP_PROLOGUE "skip-prologue" static const ConstString & @@ -1315,6 +1316,15 @@ GetSettingNameForPreferDynamicValue () } +static const ConstString & +GetSettingNameForSkipPrologue () +{ + static ConstString g_const_string (TSC_SKIP_PROLOGUE); + return g_const_string; +} + + + bool Target::SettingsController::SetGlobalVariable (const ConstString &var_name, const char *index_value, @@ -1364,7 +1374,8 @@ TargetInstanceSettings::TargetInstanceSettings InstanceSettings (owner, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance), m_expr_prefix_path (), m_expr_prefix_contents (), - m_prefer_dynamic_value (true) + m_prefer_dynamic_value (true), + m_skip_prologue (true) { // 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. @@ -1381,7 +1392,6 @@ TargetInstanceSettings::TargetInstanceSettings { const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name); CopyInstanceSettings (pending_settings,false); - //m_owner.RemovePendingSettings (m_instance_name); } } @@ -1392,7 +1402,6 @@ TargetInstanceSettings::TargetInstanceSettings (const TargetInstanceSettings &rh { const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name); CopyInstanceSettings (pending_settings,false); - //m_owner.RemovePendingSettings (m_instance_name); } } @@ -1464,36 +1473,11 @@ TargetInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_n } else if (var_name == GetSettingNameForPreferDynamicValue()) { - switch (op) - { - default: - err.SetErrorToGenericError (); - err.SetErrorString ("Unrecognized operation. Cannot update value.\n"); - return; - case eVarSetOperationAssign: - { - bool success; - bool result = Args::StringToBoolean(value, false, &success); - - if (success) - { - m_prefer_dynamic_value = result; - } - else - { - err.SetErrorStringWithFormat ("Bad value \"%s\" for %s, should be Boolean.", - value, - GetSettingNameForPreferDynamicValue().AsCString()); - } - return; - } - case eVarSetOperationClear: - m_prefer_dynamic_value = true; - case eVarSetOperationAppend: - err.SetErrorToGenericError (); - err.SetErrorString ("Cannot append to a bool.\n"); - return; - } + UserSettingsController::UpdateBooleanVariable (op, m_prefer_dynamic_value, value, true, err); + } + else if (var_name == GetSettingNameForSkipPrologue()) + { + UserSettingsController::UpdateBooleanVariable (op, m_skip_prologue, value, true, err); } } @@ -1527,6 +1511,13 @@ TargetInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry, else value.AppendString ("false"); } + else if (var_name == GetSettingNameForSkipPrologue()) + { + if (m_skip_prologue) + value.AppendString ("true"); + else + value.AppendString ("false"); + } else { if (err) @@ -1570,5 +1561,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." }, { NULL , eSetVarTypeNone , NULL , NULL, false, false, NULL } };