diff --git a/lldb/include/lldb/Core/ArchSpec.h b/lldb/include/lldb/Core/ArchSpec.h index 618048217e72fc6427b2e40c495bb5aa0290fd2c..d00098003033adf02639c7314aadcf4e57abcc2f 100644 --- a/lldb/include/lldb/Core/ArchSpec.h +++ b/lldb/include/lldb/Core/ArchSpec.h @@ -46,7 +46,8 @@ public: eCore_arm_armv7f, eCore_arm_armv7k, eCore_arm_armv7s, - eCore_arm_xscale, + eCore_arm_xscale, + eCore_thumb_generic, eCore_ppc_generic, eCore_ppc_ppc601, @@ -258,7 +259,16 @@ public: /// and the default/assumed byte order may be incorrect. //------------------------------------------------------------------ void - SetByteOrder (lldb::ByteOrder byteorder); + SetByteOrder (lldb::ByteOrder byte_order) + { + m_byte_order = byte_order; + } + + uint32_t + GetMinimumOpcodeByteSize() const; + + uint32_t + GetMaximumOpcodeByteSize() const; Core GetCore () const diff --git a/lldb/include/lldb/Core/Disassembler.h b/lldb/include/lldb/Core/Disassembler.h index 836c695373926d4b31206466fe956a554609591b..40167f9d9d8c773b24cc1a503f49a2a8bf235f5c 100644 --- a/lldb/include/lldb/Core/Disassembler.h +++ b/lldb/include/lldb/Core/Disassembler.h @@ -27,7 +27,7 @@ namespace lldb_private { class Instruction { public: - Instruction (const Address &address); + Instruction (const Address &address, AddressClass addr_class); virtual ~Instruction(); @@ -38,14 +38,21 @@ public: return m_address; } + AddressClass + GetAddressClass (); + void SetAddress (const Address &addr) { + // Invalidate the address class to lazily discover + // it if we need to. + m_address_class = eAddressClassInvalid; m_address = addr; } virtual void Dump (Stream *s, + uint32_t max_opcode_byte_size, bool show_address, bool show_bytes, const ExecutionContext *exe_ctx, @@ -55,9 +62,9 @@ public: DoesBranch () const = 0; virtual size_t - Extract (const Disassembler &disassembler, - const DataExtractor& data, - uint32_t data_offset) = 0; + Decode (const Disassembler &disassembler, + const DataExtractor& data, + uint32_t data_offset) = 0; const Opcode & GetOpcode () const @@ -67,6 +74,13 @@ public: protected: Address m_address; // The section offset address of this instruction + // We include an address class in the Instruction class to + // allow the instruction specify the eAddressClassCodeAlternateISA + // (currently used for thumb), and also to specify data (eAddressClassData). + // The usual value will be eAddressClassCode, but often when + // disassembling memory, you might run into data. This can + // help us to disassemble appropriately. + AddressClass m_address_class; Opcode m_opcode; // The opcode for this instruction }; @@ -79,6 +93,9 @@ public: size_t GetSize() const; + + uint32_t + GetMaxOpcocdeByteSize () const; lldb::InstructionSP GetInstructionAtIndex (uint32_t idx) const; @@ -194,14 +211,12 @@ public: size_t ParseInstructions (const ExecutionContext *exe_ctx, - const AddressRange &range, - DataExtractor& data); + const AddressRange &range); size_t ParseInstructions (const ExecutionContext *exe_ctx, const Address &range, - uint32_t num_instructions, - DataExtractor& data); + uint32_t num_instructions); virtual size_t DecodeInstructions (const Address &base_addr, diff --git a/lldb/include/lldb/Core/Opcode.h b/lldb/include/lldb/Core/Opcode.h index 77f58c2b7f112db14741dc31c60bbfaec2de59a1..cfa283636cc48de595adeb76d585d9188adf8fa3 100644 --- a/lldb/include/lldb/Core/Opcode.h +++ b/lldb/include/lldb/Core/Opcode.h @@ -11,8 +11,6 @@ #define lldb_Opcode_h // C Includes -#include - // C++ Includes // Other libraries and framework includes // Project includes @@ -163,6 +161,7 @@ namespace lldb_private { if (bytes && length > 0) { m_type = eTypeBytes; + m_data.inst.length = length; assert (length < sizeof (m_data.inst.bytes)); memcpy (m_data.inst.bytes, bytes, length); } diff --git a/lldb/include/lldb/Symbol/SymbolContext.h b/lldb/include/lldb/Symbol/SymbolContext.h index 9f096f6c8fb15c4b0f5e493769fe5b371eff0e60..512493bb23ebc217eb446749c6dba06cd19669cb 100644 --- a/lldb/include/lldb/Symbol/SymbolContext.h +++ b/lldb/include/lldb/Symbol/SymbolContext.h @@ -347,7 +347,7 @@ public: Append (const SymbolContext& sc); bool - AppendIfUnique (const SymbolContext& sc); + AppendIfUnique (const SymbolContext& sc, bool merge_symbol_into_function); //------------------------------------------------------------------ /// Clear the object's state. diff --git a/lldb/source/API/SBInstruction.cpp b/lldb/source/API/SBInstruction.cpp index 48b2e7399ff37c6943813026187fca2c852d2628..75683f600e8d10f18db021f5637771a2fd972853 100644 --- a/lldb/source/API/SBInstruction.cpp +++ b/lldb/source/API/SBInstruction.cpp @@ -89,7 +89,7 @@ SBInstruction::GetDescription (lldb::SBStream &s) { // Use the "ref()" instead of the "get()" accessor in case the SBStream // didn't have a stream already created, one will get created... - m_opaque_sp->Dump (&s.ref(), true, false, NULL, false); + m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL, false); return true; } return false; @@ -104,6 +104,6 @@ SBInstruction::Print (FILE *out) if (m_opaque_sp) { StreamFile out_stream (out, false); - m_opaque_sp->Dump (&out_stream, true, false, NULL, false); + m_opaque_sp->Dump (&out_stream, 0, true, false, NULL, false); } } diff --git a/lldb/source/API/SBInstructionList.cpp b/lldb/source/API/SBInstructionList.cpp index 37c7f874e19a53d8e20bfded1b35214c19217095..312922fd825d5f031851026078d730b4265fac19 100644 --- a/lldb/source/API/SBInstructionList.cpp +++ b/lldb/source/API/SBInstructionList.cpp @@ -93,12 +93,13 @@ SBInstructionList::GetDescription (lldb::SBStream &description) // Call the ref() to make sure a stream is created if one deesn't // exist already inside description... Stream &sref = description.ref(); + const uint32_t max_opcode_byte_size = m_opaque_sp->GetInstructionList().GetMaxOpcocdeByteSize(); for (size_t i=0; iGetInstructionList().GetInstructionAtIndex (i).get(); if (inst == NULL) break; - inst->Dump (&sref, true, false, NULL, false); + inst->Dump (&sref, max_opcode_byte_size, true, false, NULL, false); sref.EOL(); } return true; diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp index c7bbf85c0b06791628bccc93c2d95a8c609d0d22..6bf408b2460fc670770117ca8ea2dfc984734494 100644 --- a/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp @@ -155,7 +155,7 @@ CommandObjectBreakpointSet::CommandOptions::SetOptionValue (int option_idx, cons break; case 'f': - m_filename = option_arg; + m_filename.assign (option_arg); break; case 'l': @@ -163,32 +163,32 @@ CommandObjectBreakpointSet::CommandOptions::SetOptionValue (int option_idx, cons break; case 'b': - m_func_name = option_arg; + m_func_name.assign (option_arg); m_func_name_type_mask |= eFunctionNameTypeBase; break; case 'n': - m_func_name = option_arg; + m_func_name.assign (option_arg); m_func_name_type_mask |= eFunctionNameTypeAuto; break; case 'F': - m_func_name = option_arg; + m_func_name.assign (option_arg); m_func_name_type_mask |= eFunctionNameTypeFull; break; case 'S': - m_func_name = option_arg; + m_func_name.assign (option_arg); m_func_name_type_mask |= eFunctionNameTypeSelector; break; case 'M': - m_func_name = option_arg; + m_func_name.assign (option_arg); m_func_name_type_mask |= eFunctionNameTypeMethod; break; case 'r': - m_func_regexp = option_arg; + m_func_regexp.assign (option_arg); break; case 's': @@ -211,10 +211,10 @@ CommandObjectBreakpointSet::CommandOptions::SetOptionValue (int option_idx, cons } break; case 'T': - m_thread_name = option_arg; + m_thread_name.assign (option_arg); break; case 'q': - m_queue_name = option_arg; + m_queue_name.assign (option_arg); break; case 'x': { @@ -1087,7 +1087,7 @@ CommandObjectBreakpointClear::CommandOptions::SetOptionValue (int option_idx, co switch (short_option) { case 'f': - m_filename = option_arg; + m_filename.assign (option_arg); break; case 'l': @@ -1406,7 +1406,7 @@ CommandObjectBreakpointModify::CommandOptions::SetOptionValue (int option_idx, c { case 'c': if (option_arg != NULL) - m_condition = option_arg; + m_condition.assign (option_arg); else m_condition.clear(); m_condition_passed = true; @@ -1445,14 +1445,14 @@ CommandObjectBreakpointModify::CommandOptions::SetOptionValue (int option_idx, c break; case 'T': if (option_arg != NULL) - m_thread_name = option_arg; + m_thread_name.assign (option_arg); else m_thread_name.clear(); m_name_passed = true; break; case 'q': if (option_arg != NULL) - m_queue_name = option_arg; + m_queue_name.assign (option_arg); else m_queue_name.clear(); m_queue_passed = true; diff --git a/lldb/source/Commands/CommandObjectDisassemble.cpp b/lldb/source/Commands/CommandObjectDisassemble.cpp index c3b52cfeab81ca668a1fc92ca08d8d0e4e1bb8ec..74c27e39090730f59b3aeef99d03d95a073de976 100644 --- a/lldb/source/Commands/CommandObjectDisassemble.cpp +++ b/lldb/source/Commands/CommandObjectDisassemble.cpp @@ -40,7 +40,8 @@ CommandObjectDisassemble::CommandOptions::CommandOptions () : m_start_addr(), m_end_addr (), m_at_pc (false), - m_plugin_name () + m_plugin_name (), + m_arch() { ResetOptionValues(); } @@ -64,7 +65,7 @@ CommandObjectDisassemble::CommandOptions::SetOptionValue (int option_idx, const show_mixed = true; break; - case 'x': + case 'C': num_lines_context = Args::StringToUInt32(option_arg, 0, 0, &success); if (!success) error.SetErrorStringWithFormat ("Invalid num context lines string: \"%s\".\n", option_arg); @@ -118,6 +119,10 @@ CommandObjectDisassemble::CommandOptions::SetOptionValue (int option_idx, const // There's no need to set any flag. break; + case 'a': + m_arch.SetTriple (option_arg); + break; + default: error.SetErrorStringWithFormat("Unrecognized short option '%c'.\n", short_option); break; @@ -140,6 +145,7 @@ CommandObjectDisassemble::CommandOptions::ResetOptionValues () m_end_addr = LLDB_INVALID_ADDRESS; raw = false; m_plugin_name.clear(); + m_arch.Clear(); } const OptionDefinition* @@ -151,28 +157,23 @@ CommandObjectDisassemble::CommandOptions::GetDefinitions () OptionDefinition CommandObjectDisassemble::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_ALL, false, "bytes", 'b', no_argument, NULL, 0, eArgTypeNone, "Show opcode bytes when disassembling."}, -{ LLDB_OPT_SET_ALL, false, "context", 'x', required_argument, NULL, 0, eArgTypeNumLines,"Number of context lines of source to show."}, -{ LLDB_OPT_SET_ALL, false, "mixed", 'm', no_argument, NULL, 0, eArgTypeNone, "Enable mixed source and assembly display."}, -{ LLDB_OPT_SET_ALL, false, "raw", 'r', no_argument, NULL, 0, eArgTypeNone, "Print raw disassembly with no symbol information."}, -{ LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin, "Name of the disassembler plugin you want to use."}, - -{ LLDB_OPT_SET_1, true, "start-address", 's', required_argument, NULL, 0, eArgTypeStartAddress, "Address at which to start disassembling."}, -{ LLDB_OPT_SET_1, false, "end-address", 'e', required_argument, NULL, 0, eArgTypeEndAddress, "Address at which to end disassembling."}, - -{ LLDB_OPT_SET_2, true, "start-address", 's', required_argument, NULL, 0, eArgTypeStartAddress, "Address at which to start disassembling."}, -{ LLDB_OPT_SET_2, false, "instruction-count", 'c', required_argument, NULL, 0, eArgTypeNumLines, "Number of instructions to display."}, - -{ LLDB_OPT_SET_3, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Disassemble entire contents of the given function name."}, -{ LLDB_OPT_SET_3, false, "instruction-count", 'c', required_argument, NULL, 0, eArgTypeNumLines, "Number of instructions to display."}, - -{ LLDB_OPT_SET_4, true, "current-frame", 'f', no_argument, NULL, 0, eArgTypeNone, "Disassemble from the start of the current frame's function."}, -{ LLDB_OPT_SET_4, false, "instruction-count", 'c', required_argument, NULL, 0, eArgTypeNumLines, "Number of instructions to display."}, - -{ LLDB_OPT_SET_5, true, "current-pc", 'p', no_argument, NULL, 0, eArgTypeNone, "Disassemble from the current pc."}, -{ LLDB_OPT_SET_5, false, "instruction-count", 'c', required_argument, NULL, 0, eArgTypeNumLines, "Number of instructions to display."}, - -{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +{ LLDB_OPT_SET_ALL , false , "bytes", 'b', no_argument , NULL, 0, eArgTypeNone, "Show opcode bytes when disassembling."}, +{ LLDB_OPT_SET_ALL , false , "context", 'C', required_argument , NULL, 0, eArgTypeNumLines, "Number of context lines of source to show."}, +{ LLDB_OPT_SET_ALL , false , "mixed", 'm', no_argument , NULL, 0, eArgTypeNone, "Enable mixed source and assembly display."}, +{ LLDB_OPT_SET_ALL , false , "raw", 'r', no_argument , NULL, 0, eArgTypeNone, "Print raw disassembly with no symbol information."}, +{ LLDB_OPT_SET_ALL , false , "plugin", 'P', required_argument , NULL, 0, eArgTypePlugin, "Name of the disassembler plugin you want to use."}, +{ LLDB_OPT_SET_ALL , false , "arch", 'a', required_argument , NULL, 0, eArgTypeArchitecture,"Specify the architecture to use from cross disassembly."}, +{ LLDB_OPT_SET_1 | + LLDB_OPT_SET_2 , true , "start-address" , 's', required_argument , NULL, 0, eArgTypeStartAddress,"Address at which to start disassembling."}, +{ LLDB_OPT_SET_1 , false , "end-address" , 'e', required_argument , NULL, 0, eArgTypeEndAddress, "Address at which to end disassembling."}, +{ LLDB_OPT_SET_2 | + LLDB_OPT_SET_3 | + LLDB_OPT_SET_4 | + LLDB_OPT_SET_5 , false , "count", 'c', required_argument , NULL, 0, eArgTypeNumLines, "Number of instructions to display."}, +{ LLDB_OPT_SET_3 , true , "name", 'n', required_argument , NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Disassemble entire contents of the given function name."}, +{ LLDB_OPT_SET_4 , true , "frame", 'f', no_argument , NULL, 0, eArgTypeNone, "Disassemble from the start of the current frame's function."}, +{ LLDB_OPT_SET_5 , true , "pc", 'p', no_argument , NULL, 0, eArgTypeNone, "Disassemble from the current pc."}, +{ 0 , false , NULL, 0, 0 , NULL, 0, eArgTypeNone, NULL } }; @@ -207,27 +208,28 @@ CommandObjectDisassemble::Execute result.SetStatus (eReturnStatusFailed); return false; } + if (!m_options.m_arch.IsValid()) + m_options.m_arch = target->GetArchitecture(); - ArchSpec arch(target->GetArchitecture()); - if (!arch.IsValid()) + if (!m_options.m_arch.IsValid()) { - result.AppendError ("target needs valid architecure in order to be able to disassemble"); + result.AppendError ("use the --arch option or set the target architecure to disassemble"); result.SetStatus (eReturnStatusFailed); return false; } const char *plugin_name = m_options.GetPluginName (); - Disassembler *disassembler = Disassembler::FindPlugin(arch, plugin_name); + Disassembler *disassembler = Disassembler::FindPlugin(m_options.m_arch, plugin_name); if (disassembler == NULL) { if (plugin_name) - result.AppendErrorWithFormat ("Unable to find Disassembler plug-in for %s architecture named '%s'.\n", - arch.GetArchitectureName(), - plugin_name); + result.AppendErrorWithFormat ("Unable to find Disassembler plug-in named '%s' that supports the '%s' architecture.\n", + plugin_name, + m_options.m_arch.GetArchitectureName()); else - result.AppendErrorWithFormat ("Unable to find Disassembler plug-in for %s architecture.\n", - arch.GetArchitectureName()); + result.AppendErrorWithFormat ("Unable to find Disassembler plug-in for the '%s' architecture.\n", + m_options.m_arch.GetArchitectureName()); result.SetStatus (eReturnStatusFailed); return false; } @@ -255,7 +257,7 @@ CommandObjectDisassemble::Execute ConstString name(m_options.m_func_name.c_str()); if (Disassembler::Disassemble (m_interpreter.GetDebugger(), - arch, + m_options.m_arch, plugin_name, exe_ctx, name, @@ -337,7 +339,7 @@ CommandObjectDisassemble::Execute } if (Disassembler::Disassemble (m_interpreter.GetDebugger(), - arch, + m_options.m_arch, plugin_name, exe_ctx, start_addr, @@ -387,7 +389,7 @@ CommandObjectDisassemble::Execute range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE); if (Disassembler::Disassemble (m_interpreter.GetDebugger(), - arch, + m_options.m_arch, plugin_name, exe_ctx, range, diff --git a/lldb/source/Commands/CommandObjectDisassemble.h b/lldb/source/Commands/CommandObjectDisassemble.h index 91812af31876bfd49cfce4d38ba23ef50824ae2d..42ede79787dfc1b0ee746c11b0a9debfbbd44e6d 100644 --- a/lldb/source/Commands/CommandObjectDisassemble.h +++ b/lldb/source/Commands/CommandObjectDisassemble.h @@ -63,6 +63,7 @@ public: lldb::addr_t m_end_addr; bool m_at_pc; std::string m_plugin_name; + ArchSpec m_arch; static OptionDefinition g_option_table[]; }; diff --git a/lldb/source/Core/ArchSpec.cpp b/lldb/source/Core/ArchSpec.cpp index 17134938d09ddbac5b2954fad51212e83f83e8f9..210d32aa42144f3fb72f1de867d69d64aed76cc7 100644 --- a/lldb/source/Core/ArchSpec.cpp +++ b/lldb/source/Core/ArchSpec.cpp @@ -30,6 +30,8 @@ namespace lldb_private { { ByteOrder default_byte_order; uint32_t addr_byte_size; + uint32_t min_opcode_byte_size; + uint32_t max_opcode_byte_size; llvm::Triple::ArchType machine; ArchSpec::Core core; const char *name; @@ -40,45 +42,47 @@ namespace lldb_private { // This core information can be looked using the ArchSpec::Core as the index static const CoreDefinition g_core_definitions[ArchSpec::kNumCores] = { - { eByteOrderLittle, 4, llvm::Triple::alpha , ArchSpec::eCore_alpha_generic , "alpha" }, - - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_generic , "arm" }, - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv4 , "armv4" }, - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv4t , "armv4t" }, - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv5 , "armv5" }, - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv5t , "armv5t" }, - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv6 , "armv6" }, - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7 , "armv7" }, - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7f , "armv7f" }, - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7k , "armv7k" }, - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7s , "armv7s" }, - { eByteOrderLittle, 4, llvm::Triple::arm , ArchSpec::eCore_arm_xscale , "xscale" }, + // TODO: verify alpha has 32 bit fixed instructions + { eByteOrderLittle, 4, 4, 4, llvm::Triple::alpha , ArchSpec::eCore_alpha_generic , "alpha" }, + + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_generic , "arm" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv4 , "armv4" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv4t , "armv4t" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv5 , "armv5" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv5t , "armv5t" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv6 , "armv6" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7 , "armv7" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7f , "armv7f" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7k , "armv7k" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7s , "armv7s" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_xscale , "xscale" }, + { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumb_generic , "thumb" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_generic , "ppc" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc601 , "ppc601" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc602 , "ppc602" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603 , "ppc603" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603e , "ppc603e" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603ev , "ppc603ev" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc604 , "ppc604" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc604e , "ppc604e" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc620 , "ppc620" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc750 , "ppc750" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc7400 , "ppc7400" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc7450 , "ppc7450" }, - { eByteOrderLittle, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc970 , "ppc970" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_generic , "ppc" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc601 , "ppc601" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc602 , "ppc602" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603 , "ppc603" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603e , "ppc603e" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603ev , "ppc603ev" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc604 , "ppc604" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc604e , "ppc604e" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc620 , "ppc620" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc750 , "ppc750" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc7400 , "ppc7400" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc7450 , "ppc7450" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc970 , "ppc970" }, - { eByteOrderLittle, 8, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_generic , "ppc64" }, - { eByteOrderLittle, 8, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_ppc970_64 , "ppc970-64" }, + { eByteOrderLittle, 8, 4, 4, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_generic , "ppc64" }, + { eByteOrderLittle, 8, 4, 4, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_ppc970_64 , "ppc970-64" }, - { eByteOrderLittle, 4, llvm::Triple::sparc , ArchSpec::eCore_sparc_generic , "sparc" }, - { eByteOrderLittle, 8, llvm::Triple::sparcv9, ArchSpec::eCore_sparc9_generic , "sparcv9" }, + { eByteOrderLittle, 4, 4, 4, llvm::Triple::sparc , ArchSpec::eCore_sparc_generic , "sparc" }, + { eByteOrderLittle, 8, 4, 4, llvm::Triple::sparcv9, ArchSpec::eCore_sparc9_generic , "sparcv9" }, - { eByteOrderLittle, 4, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i386 , "i386" }, - { eByteOrderLittle, 4, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i486 , "i486" }, - { eByteOrderLittle, 4, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i486sx , "i486sx" }, + { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i386 , "i386" }, + { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i486 , "i486" }, + { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i486sx , "i486sx" }, - { eByteOrderLittle, 8, llvm::Triple::x86_64 , ArchSpec::eCore_x86_64_x86_64 , "x86_64" } + { eByteOrderLittle, 8, 1, 15, llvm::Triple::x86_64 , ArchSpec::eCore_x86_64_x86_64 , "x86_64" } }; struct ArchDefinitionEntry @@ -118,6 +122,7 @@ static const ArchDefinitionEntry g_macho_arch_entries[] = { ArchSpec::eCore_arm_armv7f , llvm::MachO::CPUTypeARM , 10 }, { ArchSpec::eCore_arm_armv7k , llvm::MachO::CPUTypeARM , 12 }, { ArchSpec::eCore_arm_armv7s , llvm::MachO::CPUTypeARM , 11 }, + { ArchSpec::eCore_thumb_generic , llvm::MachO::CPUTypeARM , 0 }, { ArchSpec::eCore_ppc_generic , llvm::MachO::CPUTypePowerPC , CPU_ANY }, { ArchSpec::eCore_ppc_generic , llvm::MachO::CPUTypePowerPC , 0 }, { ArchSpec::eCore_ppc_ppc601 , llvm::MachO::CPUTypePowerPC , 1 }, @@ -496,10 +501,22 @@ ArchSpec::SetArchitecture (ArchitectureType arch_type, uint32_t cpu, uint32_t su return IsValid(); } -void -ArchSpec::SetByteOrder (lldb::ByteOrder byte_order) +uint32_t +ArchSpec::GetMinimumOpcodeByteSize() const +{ + const CoreDefinition *core_def = FindCoreDefinition (m_core); + if (core_def) + return core_def->min_opcode_byte_size; + return 0; +} + +uint32_t +ArchSpec::GetMaximumOpcodeByteSize() const { - m_byte_order = byte_order; + const CoreDefinition *core_def = FindCoreDefinition (m_core); + if (core_def) + return core_def->max_opcode_byte_size; + return 0; } //===----------------------------------------------------------------------===// diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp index 9f3897752fe94663fc48b7291dcc28bdeb3b6b78..e37f4818c9c9b97dc3b3869cde1aec7bd582f959 100644 --- a/lldb/source/Core/Disassembler.cpp +++ b/lldb/source/Core/Disassembler.cpp @@ -69,6 +69,33 @@ Disassembler::FindPlugin (const ArchSpec &arch, const char *plugin_name) } +static void +ResolveAddress (const ExecutionContext &exe_ctx, + const Address &addr, + Address &resolved_addr) +{ + if (!addr.IsSectionOffset()) + { + // If we weren't passed in a section offset address range, + // try and resolve it to something + if (exe_ctx.target) + { + if (exe_ctx.target->GetSectionLoadList().IsEmpty()) + { + exe_ctx.target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr); + } + else + { + exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr); + } + // We weren't able to resolve the address, just treat it as a + // raw address + if (resolved_addr.IsValid()) + return; + } + } + resolved_addr = addr; +} size_t Disassembler::Disassemble @@ -192,8 +219,7 @@ Disassembler::DisassembleRange if (disasm_sp) { - DataExtractor data; - size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, data); + size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range); if (bytes_disassembled == 0) disasm_sp.reset(); } @@ -223,27 +249,11 @@ Disassembler::Disassemble if (disasm_ap.get()) { - AddressRange range(disasm_range); + AddressRange range; + ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress()); + range.SetByteSize (disasm_range.GetByteSize()); - // If we weren't passed in a section offset address range, - // try and resolve it to something - if (range.GetBaseAddress().IsSectionOffset() == false) - { - if (exe_ctx.target) - { - if (exe_ctx.target->GetSectionLoadList().IsEmpty()) - { - exe_ctx.target->GetImages().ResolveFileAddress (range.GetBaseAddress().GetOffset(), range.GetBaseAddress()); - } - else - { - exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (range.GetBaseAddress().GetOffset(), range.GetBaseAddress()); - } - } - } - - DataExtractor data; - size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range, data); + size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, range); if (bytes_disassembled == 0) return false; @@ -280,29 +290,12 @@ Disassembler::Disassemble if (num_instructions > 0) { std::auto_ptr disasm_ap (Disassembler::FindPlugin(arch, plugin_name)); - Address addr = start_address; - if (disasm_ap.get()) { - // If we weren't passed in a section offset address range, - // try and resolve it to something - if (addr.IsSectionOffset() == false) - { - if (exe_ctx.target) - { - if (exe_ctx.target->GetSectionLoadList().IsEmpty()) - { - exe_ctx.target->GetImages().ResolveFileAddress (addr.GetOffset(), addr); - } - else - { - exe_ctx.target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), addr); - } - } - } + Address addr; + ResolveAddress (exe_ctx, start_address, addr); - DataExtractor data; - size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions, data); + size_t bytes_disassembled = disasm_ap->ParseInstructions (&exe_ctx, addr, num_instructions); if (bytes_disassembled == 0) return false; return PrintInstructions (disasm_ap.get(), @@ -341,11 +334,12 @@ Disassembler::PrintInstructions if (num_instructions > 0 && num_instructions < num_instructions_found) num_instructions_found = num_instructions; + const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize (); uint32_t offset = 0; SymbolContext sc; SymbolContext prev_sc; AddressRange sc_range; - Address addr = start_addr; + Address addr (start_addr); if (num_mixed_context_lines) strm.IndentMore (); @@ -425,7 +419,7 @@ Disassembler::PrintInstructions if (num_mixed_context_lines) strm.IndentMore (); strm.Indent(); - inst->Dump(&strm, true, show_bytes, &exe_ctx, raw); + inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw); strm.EOL(); addr.Slide(inst->GetOpcode().GetByteSize()); @@ -492,8 +486,9 @@ Disassembler::Disassemble strm); } -Instruction::Instruction(const Address &address) : +Instruction::Instruction(const Address &address, AddressClass addr_class) : m_address (address), + m_address_class (addr_class), m_opcode() { } @@ -502,6 +497,13 @@ Instruction::~Instruction() { } +AddressClass +Instruction::GetAddressClass () +{ + if (m_address_class == eAddressClassInvalid) + m_address_class = m_address.GetAddressClass(); + return m_address_class; +} InstructionList::InstructionList() : m_instructions() @@ -518,6 +520,23 @@ InstructionList::GetSize() const return m_instructions.size(); } +uint32_t +InstructionList::GetMaxOpcocdeByteSize () const +{ + uint32_t max_inst_size = 0; + collection::const_iterator pos, end; + for (pos = m_instructions.begin(), end = m_instructions.end(); + pos != end; + ++pos) + { + uint32_t inst_size = (*pos)->GetOpcode().GetByteSize(); + if (max_inst_size < inst_size) + max_inst_size = inst_size; + } + return max_inst_size; +} + + InstructionSP InstructionList::GetInstructionAtIndex (uint32_t idx) const @@ -546,8 +565,7 @@ size_t Disassembler::ParseInstructions ( const ExecutionContext *exe_ctx, - const AddressRange &range, - DataExtractor& data + const AddressRange &range ) { Target *target = exe_ctx->target; @@ -559,17 +577,20 @@ Disassembler::ParseInstructions DataBufferSP data_sp(heap_buffer); Error error; - bool prefer_file_cache = true; - const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), prefer_file_cache, heap_buffer->GetBytes(), heap_buffer->GetByteSize(), error); + const bool prefer_file_cache = true; + const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), + prefer_file_cache, + heap_buffer->GetBytes(), + heap_buffer->GetByteSize(), + error); if (bytes_read > 0) { if (bytes_read != heap_buffer->GetByteSize()) heap_buffer->SetByteSize (bytes_read); - - data.SetData(data_sp); - data.SetByteOrder(target->GetArchitecture().GetByteOrder()); - data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); + DataExtractor data (data_sp, + m_arch.GetByteOrder(), + m_arch.GetAddressByteSize()); return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false); } @@ -581,64 +602,45 @@ Disassembler::ParseInstructions ( const ExecutionContext *exe_ctx, const Address &start, - uint32_t num_instructions, - DataExtractor& data + uint32_t num_instructions ) { - Address addr = start; - - if (num_instructions == 0) + m_instruction_list.Clear(); + + if (num_instructions == 0 || !start.IsValid()) return 0; Target *target = exe_ctx->target; - // We'll guess at a size for the buffer, if we don't get all the instructions we want we can just re-fill & reuse it. - const addr_t byte_size = num_instructions * 2; - addr_t data_offset = 0; - addr_t next_instruction_offset = 0; - size_t buffer_size = byte_size; + // Calculate the max buffer size we will need in order to disassemble + const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize(); - uint32_t num_instructions_found = 0; - - if (target == NULL || byte_size == 0 || !start.IsValid()) + if (target == NULL || byte_size == 0) return 0; DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0'); - DataBufferSP data_sp(heap_buffer); - - data.SetData(data_sp); - data.SetByteOrder(target->GetArchitecture().GetByteOrder()); - data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); + DataBufferSP data_sp (heap_buffer); Error error; bool prefer_file_cache = true; - - m_instruction_list.Clear(); - - while (num_instructions_found < num_instructions) - { - if (buffer_size < data_offset + byte_size) - { - buffer_size = data_offset + byte_size; - heap_buffer->SetByteSize (buffer_size); - data.SetData(data_sp); // Resizing might have changed the backing store location, so we have to reset - // the DataBufferSP in the extractor so it changes to pointing at the right thing. - } - const size_t bytes_read = target->ReadMemory (addr, prefer_file_cache, heap_buffer->GetBytes() + data_offset, byte_size, error); - size_t num_bytes_read = 0; - if (bytes_read == 0) - break; - - num_bytes_read = DecodeInstructions (start, data, next_instruction_offset, num_instructions - num_instructions_found, true); - if (num_bytes_read == 0) - break; - num_instructions_found = m_instruction_list.GetSize(); - - // Prepare for the next round. - data_offset += bytes_read; - addr.Slide (bytes_read); - next_instruction_offset += num_bytes_read; - } - + const size_t bytes_read = target->ReadMemory (start, + prefer_file_cache, + heap_buffer->GetBytes(), + byte_size, + error); + + if (bytes_read == 0) + return 0; + DataExtractor data (data_sp, + m_arch.GetByteOrder(), + m_arch.GetAddressByteSize()); + + const bool append_instructions = true; + DecodeInstructions (start, + data, + 0, + num_instructions, + append_instructions); + return m_instruction_list.GetSize(); } diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index a504829d75c89b52e137d1a201c2eee21bd747dd..735dde4a5daff335f79caf47e8378653be3049ac 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -351,11 +351,12 @@ Module::FindFunctions (const ConstString &name, const uint32_t num_matches = symbol_indexes.size(); if (num_matches) { + const bool merge_symbol_into_function = true; SymbolContext sc(this); for (uint32_t i=0; iSymbolAtIndex(symbol_indexes[i]); - sc_list.AppendIfUnique (sc); + sc_list.AppendIfUnique (sc, merge_symbol_into_function); } } } @@ -392,11 +393,12 @@ Module::FindFunctions (const RegularExpression& regex, const uint32_t num_matches = symbol_indexes.size(); if (num_matches) { + const bool merge_symbol_into_function = true; SymbolContext sc(this); for (uint32_t i=0; iSymbolAtIndex(symbol_indexes[i]); - sc_list.AppendIfUnique (sc); + sc_list.AppendIfUnique (sc, merge_symbol_into_function); } } } diff --git a/lldb/source/Core/Opcode.cpp b/lldb/source/Core/Opcode.cpp index d33c80c76de2b1a5dbedb39380f2aa91bc6420d2..b765bf7dd1daddc394a9f100ec343d6d984c0206 100644 --- a/lldb/source/Core/Opcode.cpp +++ b/lldb/source/Core/Opcode.cpp @@ -48,7 +48,7 @@ Opcode::Dump (Stream *s, uint32_t min_byte_width) for (uint32_t i=0; i 0) - s->PutChar (' '); + bytes_written += s->PutChar (' '); bytes_written += s->Printf ("%2.2x", m_data.inst.bytes[i]); } } diff --git a/lldb/source/Expression/ClangExpressionParser.cpp b/lldb/source/Expression/ClangExpressionParser.cpp index 12a4472957e599826dc3cfdae2521a278419bdcb..59849351e1998518522d8e69b43943d976faa607 100644 --- a/lldb/source/Expression/ClangExpressionParser.cpp +++ b/lldb/source/Expression/ClangExpressionParser.cpp @@ -742,13 +742,14 @@ ClangExpressionParser::DisassembleFunction (Stream &stream, ExecutionContext &ex disassembler->DecodeInstructions (Address (NULL, func_remote_addr), extractor, 0, UINT32_MAX, false); InstructionList &instruction_list = disassembler->GetInstructionList(); - + const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize(); for (uint32_t instruction_index = 0, num_instructions = instruction_list.GetSize(); instruction_index < num_instructions; ++instruction_index) { Instruction *instruction = instruction_list.GetInstructionAtIndex(instruction_index).get(); instruction->Dump (&stream, + max_opcode_byte_size, true, true, &exe_ctx, diff --git a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp index 9c55042640f3c245fba3e99731eb9f3d4c204d0a..59e6d9a4bb48f44773895c2a43c4b7d60d3f20bf 100644 --- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp +++ b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp @@ -74,8 +74,10 @@ static int IPRegisterReader(uint64_t *value, unsigned regID, void* arg) return -1; } -DisassemblerLLVM::InstructionLLVM::InstructionLLVM (const Address &addr, EDDisassemblerRef disassembler) : - Instruction (addr), +DisassemblerLLVM::InstructionLLVM::InstructionLLVM (const Address &addr, + AddressClass addr_class, + EDDisassemblerRef disassembler) : + Instruction (addr, addr_class), m_disassembler (disassembler) { } @@ -99,6 +101,7 @@ void DisassemblerLLVM::InstructionLLVM::Dump ( Stream *s, + uint32_t max_opcode_byte_size, bool show_address, bool show_bytes, const lldb_private::ExecutionContext* exe_ctx, @@ -131,13 +134,19 @@ DisassemblerLLVM::InstructionLLVM::Dump // x86_64 and i386 are the only ones that use bytes right now so // pad out the byte dump to be able to always show 15 bytes (3 chars each) // plus a space - m_opcode.Dump (s, 15 * 3 + 1); + if (max_opcode_byte_size > 0) + m_opcode.Dump (s, max_opcode_byte_size * 3 + 1); + else + m_opcode.Dump (s, 15 * 3 + 1); } else { // Else, we have ARM which can show up to a uint32_t 0x00000000 (10 spaces) // plus two for padding... - m_opcode.Dump (s, 12); + if (max_opcode_byte_size > 0) + m_opcode.Dump (s, max_opcode_byte_size * 3 + 1); + else + m_opcode.Dump (s, 12); } } @@ -329,9 +338,9 @@ DisassemblerLLVM::InstructionLLVM::DoesBranch() const } size_t -DisassemblerLLVM::InstructionLLVM::Extract (const Disassembler &disassembler, - const lldb_private::DataExtractor &data, - uint32_t data_offset) +DisassemblerLLVM::InstructionLLVM::Decode (const Disassembler &disassembler, + const lldb_private::DataExtractor &data, + uint32_t data_offset) { if (EDCreateInsts(&m_inst, 1, m_disassembler, DataExtractorByteReader, data_offset, (void*)(&data))) { @@ -382,6 +391,7 @@ SyntaxForArchSpec (const ArchSpec &arch) case llvm::Triple::x86_64: return kEDAssemblySyntaxX86ATT; case llvm::Triple::arm: + case llvm::Triple::thumb: return kEDAssemblySyntaxARMUAL; default: break; @@ -411,17 +421,16 @@ DisassemblerLLVM::DisassemblerLLVM(const ArchSpec &arch) : if (EDGetDisassembler(&m_disassembler, arch_triple.c_str(), SyntaxForArchSpec (arch))) m_disassembler = NULL; llvm::Triple::ArchType llvm_arch = arch.GetTriple().getArch(); + // Don't have the lldb::Triple::thumb architecture here. If someone specifies + // "thumb" as the architecture, we want a thumb only disassembler. But if any + // architecture starting with "arm" if specified, we want to auto detect the + // arm/thumb code automatically using the AddressClass from section offset + // addresses. if (llvm_arch == llvm::Triple::arm) { if (EDGetDisassembler(&m_disassembler_thumb, "thumb-apple-darwin", kEDAssemblySyntaxARMUAL)) m_disassembler_thumb = NULL; } - else if (llvm_arch == llvm::Triple::thumb) - { - m_disassembler_thumb = m_disassembler; - if (EDGetDisassembler(&m_disassembler, "arm-apple-darwin-unknown", kEDAssemblySyntaxARMUAL)) - m_disassembler = NULL; - } } } @@ -456,15 +465,18 @@ DisassemblerLLVM::DecodeInstructions // If we have a thumb disassembler, then we have an ARM architecture // so we need to check what the instruction address class is to make // sure we shouldn't be disassembling as thumb... + AddressClass inst_address_class = eAddressClassInvalid; if (m_disassembler_thumb) { - if (inst_addr.GetAddressClass () == eAddressClassCodeAlternateISA) + inst_address_class = inst_addr.GetAddressClass (); + if (inst_address_class == eAddressClassCodeAlternateISA) use_thumb = true; } InstructionSP inst_sp (new InstructionLLVM (inst_addr, + inst_address_class, use_thumb ? m_disassembler_thumb : m_disassembler)); - size_t inst_byte_size = inst_sp->Extract (*this, data, data_offset); + size_t inst_byte_size = inst_sp->Decode (*this, data, data_offset); if (inst_byte_size == 0) break; diff --git a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h index 9e01bf3f2c620e021c835d115aa135fe6bc3b02c..8408d70dc879c3b1db1015d1bb2002815baa5488 100644 --- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h +++ b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h @@ -23,6 +23,7 @@ public: { public: InstructionLLVM (const lldb_private::Address &addr, + lldb_private::AddressClass addr_class, EDDisassemblerRef disassembler); virtual @@ -30,6 +31,7 @@ public: virtual void Dump (lldb_private::Stream *s, + uint32_t max_opcode_byte_size, bool show_address, bool show_bytes, const lldb_private::ExecutionContext* exe_ctx, @@ -39,9 +41,9 @@ public: DoesBranch () const; virtual size_t - Extract (const Disassembler &disassembler, - const lldb_private::DataExtractor &data, - uint32_t data_offset); + Decode (const Disassembler &disassembler, + const lldb_private::DataExtractor &data, + uint32_t data_offset); protected: EDDisassemblerRef m_disassembler; diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp index f595e531a7280512a55afe3a21f5f894be4255c6..a5a36bb9d4e248e2ef1658e41fd96ce2ca4b589f 100644 --- a/lldb/source/Symbol/SymbolContext.cpp +++ b/lldb/source/Symbol/SymbolContext.cpp @@ -334,11 +334,11 @@ bool lldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs) { return lhs.function != rhs.function - && lhs.symbol != rhs.symbol - && lhs.module_sp.get() != rhs.module_sp.get() - && lhs.comp_unit != rhs.comp_unit - && lhs.target_sp.get() != rhs.target_sp.get() - && LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0; + || lhs.symbol != rhs.symbol + || lhs.module_sp.get() != rhs.module_sp.get() + || lhs.comp_unit != rhs.comp_unit + || lhs.target_sp.get() != rhs.target_sp.get() + || LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0; } bool @@ -749,14 +749,43 @@ SymbolContextList::Append(const SymbolContext& sc) } bool -SymbolContextList::AppendIfUnique (const SymbolContext& sc) +SymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_into_function) { - collection::const_iterator pos, end = m_symbol_contexts.end(); + collection::iterator pos, end = m_symbol_contexts.end(); for (pos = m_symbol_contexts.begin(); pos != end; ++pos) { if (*pos == sc) return false; } + if (merge_symbol_into_function + && sc.symbol != NULL + && sc.comp_unit == NULL + && sc.function == NULL + && sc.block == NULL + && sc.line_entry.IsValid() == false) + { + const AddressRange *symbol_range = sc.symbol->GetAddressRangePtr(); + if (symbol_range) + { + for (pos = m_symbol_contexts.begin(); pos != end; ++pos) + { + if (pos->function) + { + if (pos->function->GetAddressRange().GetBaseAddress() == symbol_range->GetBaseAddress()) + { + // Do we already have a function with this symbol? + if (pos->symbol == sc.symbol) + return false; + if (pos->symbol == NULL) + { + pos->symbol = sc.symbol; + return false; + } + } + } + } + } + } m_symbol_contexts.push_back(sc); return true; } diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 3dc11049f6cbc8914d805cd62c9c9e1c19b5874d..0b734c5344658831927cef6fe113e32968d36f65 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -587,18 +587,16 @@ Target::ReadMemory (const Address& addr, bool prefer_file_cache, void *dst, size bool process_is_valid = m_process_sp && m_process_sp->IsAlive(); size_t bytes_read = 0; - Address resolved_addr(addr); - if (!resolved_addr.IsSectionOffset()) + Address resolved_addr; + if (!addr.IsSectionOffset()) { if (process_is_valid) - { m_section_load_list.ResolveLoadAddress (addr.GetOffset(), resolved_addr); - } else - { m_images.ResolveFileAddress(addr.GetOffset(), resolved_addr); - } } + if (!resolved_addr.IsValid()) + resolved_addr = addr; if (prefer_file_cache) { diff --git a/lldb/source/Target/ThreadPlanTracer.cpp b/lldb/source/Target/ThreadPlanTracer.cpp index 578a160251ed1530b3687a45d83a6b1946704563..fe95b9a5a9a57a04d890b74e833ea9f68c5089e8 100644 --- a/lldb/source/Target/ThreadPlanTracer.cpp +++ b/lldb/source/Target/ThreadPlanTracer.cpp @@ -209,11 +209,13 @@ ThreadPlanAssemblyTracer::Log () m_disassembler->DecodeInstructions (Address (NULL, pc), extractor, 0, 1, false); InstructionList &instruction_list = m_disassembler->GetInstructionList(); - + const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize(); + if (instruction_list.GetSize()) { Instruction *instruction = instruction_list.GetInstructionAtIndex(0).get(); instruction->Dump (&desc, + max_opcode_byte_size, false, false, NULL, diff --git a/lldb/test/settings/TestSettings.py b/lldb/test/settings/TestSettings.py index 129a209dac0677b6faa20aa075f881d83b5fb457..8e70df1f7058525b3a94d83063d39a5c0727baea 100644 --- a/lldb/test/settings/TestSettings.py +++ b/lldb/test/settings/TestSettings.py @@ -240,9 +240,6 @@ class SettingsCommandTestCase(TestBase): "auto-confirm (boolean) = ", "target.default-arch (string):", "target.expr-prefix (string) = ", - "target.execution-level (enum) = ", - "target.execution-mode (enum) = ", - "target.execution-os-type (enum) = ", "target.process.run-args (array):", "target.process.env-vars (dictionary):", "target.process.inherit-env (boolean) = ",