diff options
31 files changed, 944 insertions, 414 deletions
diff --git a/lldb/include/lldb/API/SBInstruction.h b/lldb/include/lldb/API/SBInstruction.h index 880cbe17202..79ffd8e27e2 100644 --- a/lldb/include/lldb/API/SBInstruction.h +++ b/lldb/include/lldb/API/SBInstruction.h @@ -53,7 +53,7 @@ public: GetDescription (lldb::SBStream &description); bool - EmulateWithFrame (lldb::SBFrame &frame, bool auto_advance_pc); + EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options); bool DumpEmulation (const char * triple); // triple is to specify the architecture, e.g. 'armv6' or 'arm-apple-darwin' diff --git a/lldb/include/lldb/Core/Disassembler.h b/lldb/include/lldb/Core/Disassembler.h index 8c5a0c1a686..2a0433cad8e 100644 --- a/lldb/include/lldb/Core/Disassembler.h +++ b/lldb/include/lldb/Core/Disassembler.h @@ -86,7 +86,7 @@ public: bool Emulate (const ArchSpec &arch, - bool auto_advance_pc, + uint32_t evaluate_options, void *baton, EmulateInstruction::ReadMemory read_mem_callback, EmulateInstruction::WriteMemory write_mem_calback, diff --git a/lldb/include/lldb/Core/EmulateInstruction.h b/lldb/include/lldb/Core/EmulateInstruction.h index 590fa18fa8e..a0ecdc91ce6 100644 --- a/lldb/include/lldb/Core/EmulateInstruction.h +++ b/lldb/include/lldb/Core/EmulateInstruction.h @@ -86,7 +86,9 @@ class EmulateInstruction : public: static EmulateInstruction* - FindPlugin (const ArchSpec &arch, const char *plugin_name); + FindPlugin (const ArchSpec &arch, + InstructionType supported_inst_type, + const char *plugin_name); enum ContextType { @@ -366,45 +368,43 @@ public: static void PrintContext (const char *context_type, const Context &context); - typedef size_t (*ReadMemory) (void *baton, + typedef size_t (*ReadMemory) (EmulateInstruction *instruction, + void *baton, const Context &context, lldb::addr_t addr, void *dst, size_t length); - typedef size_t (*WriteMemory) (void *baton, + typedef size_t (*WriteMemory) (EmulateInstruction *instruction, + void *baton, const Context &context, lldb::addr_t addr, const void *dst, size_t length); - typedef bool (*ReadRegister) (void *baton, + typedef bool (*ReadRegister) (EmulateInstruction *instruction, + void *baton, uint32_t reg_kind, uint32_t reg_num, uint64_t ®_value); - typedef bool (*WriteRegister) (void *baton, + typedef bool (*WriteRegister) (EmulateInstruction *instruction, + void *baton, const Context &context, uint32_t reg_kind, uint32_t reg_num, uint64_t reg_value); - EmulateInstruction (lldb::ByteOrder byte_order, - uint32_t addr_byte_size, - const ArchSpec &arch, - void *baton, - ReadMemory read_mem_callback, - WriteMemory write_mem_callback, - ReadRegister read_reg_callback, - WriteRegister write_reg_callback); - - EmulateInstruction (lldb::ByteOrder byte_order, - uint32_t addr_byte_size, - const ArchSpec &arch); + EmulateInstruction (const ArchSpec &arch); virtual ~EmulateInstruction() { } + //---------------------------------------------------------------------- + // Mandatory overrides + //---------------------------------------------------------------------- + virtual bool + SupportsEmulatingIntructionsOfType (InstructionType inst_type) = 0; virtual bool SetTargetTriple (const ArchSpec &arch) = 0; @@ -413,21 +413,20 @@ public: ReadInstruction () = 0; virtual bool - SetInstruction (const Opcode &insn_opcode, const Address &inst_addr) = 0; - - virtual bool - EvaluateInstruction () = 0; + EvaluateInstruction (uint32_t evaluate_options) = 0; virtual bool TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) = 0; + + virtual const char * + GetRegisterName (uint32_t reg_kind, uint32_t reg_num) = 0; + //---------------------------------------------------------------------- + // Optional overrides + //---------------------------------------------------------------------- + virtual bool + SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target); - bool - GetAdvancePC () { return m_advance_pc; } - - void - SetAdvancePC (bool value) { m_advance_pc = value; } - - static void + static const char * TranslateRegister (uint32_t reg_kind, uint32_t reg_num, std::string ®_name); uint64_t @@ -458,13 +457,13 @@ public: uint32_t GetAddressByteSize () const { - return m_addr_byte_size; + return m_arch.GetAddressByteSize(); } lldb::ByteOrder GetByteOrder () const { - return m_byte_order; + return m_arch.GetByteOrder(); } const Opcode & @@ -472,59 +471,73 @@ public: { return m_opcode; } + + const ArchSpec & + GetArchitecture () const + { + return m_arch; + } static size_t - ReadMemoryFrame (void *baton, + ReadMemoryFrame (EmulateInstruction *instruction, + void *baton, const Context &context, lldb::addr_t addr, void *dst, size_t length); static size_t - WriteMemoryFrame (void *baton, + WriteMemoryFrame (EmulateInstruction *instruction, + void *baton, const Context &context, lldb::addr_t addr, const void *dst, size_t length); static bool - ReadRegisterFrame (void *baton, + ReadRegisterFrame (EmulateInstruction *instruction, + void *baton, uint32_t reg_kind, uint32_t reg_num, uint64_t ®_value); static bool - WriteRegisterFrame (void *baton, + WriteRegisterFrame (EmulateInstruction *instruction, + void *baton, const Context &context, uint32_t reg_kind, uint32_t reg_num, uint64_t reg_value); static size_t - ReadMemoryDefault (void *baton, + ReadMemoryDefault (EmulateInstruction *instruction, + void *baton, const Context &context, lldb::addr_t addr, void *dst, size_t length); static size_t - WriteMemoryDefault (void *baton, + WriteMemoryDefault (EmulateInstruction *instruction, + void *baton, const Context &context, lldb::addr_t addr, const void *dst, size_t length); static bool - ReadRegisterDefault (void *baton, + ReadRegisterDefault (EmulateInstruction *instruction, + void *baton, uint32_t reg_kind, uint32_t reg_num, uint64_t ®_value); static bool - WriteRegisterDefault (void *baton, + WriteRegisterDefault (EmulateInstruction *instruction, + void *baton, const Context &context, uint32_t reg_kind, uint32_t reg_num, @@ -553,8 +566,6 @@ public: protected: - lldb::ByteOrder m_byte_order; - uint32_t m_addr_byte_size; ArchSpec m_arch; void * m_baton; ReadMemory m_read_mem_callback; @@ -563,7 +574,6 @@ protected: WriteRegister m_write_reg_callback; lldb::addr_t m_opcode_pc; Opcode m_opcode; - bool m_advance_pc; //------------------------------------------------------------------ // For EmulateInstruction only //------------------------------------------------------------------ diff --git a/lldb/include/lldb/Target/ArchDefaultUnwindPlan.h b/lldb/include/lldb/Target/ArchDefaultUnwindPlan.h index 932e4ef56ac..ad848fa8efe 100644 --- a/lldb/include/lldb/Target/ArchDefaultUnwindPlan.h +++ b/lldb/include/lldb/Target/ArchDefaultUnwindPlan.h @@ -24,7 +24,8 @@ public: ~ArchDefaultUnwindPlan(); virtual lldb::UnwindPlanSP - GetArchDefaultUnwindPlan (Thread& thread, Address current_pc) = 0; + GetArchDefaultUnwindPlan (Thread& thread, + const Address ¤t_pc) = 0; static lldb::ArchDefaultUnwindPlanSP FindPlugin (const ArchSpec &arch); diff --git a/lldb/include/lldb/Target/UnwindAssembly.h b/lldb/include/lldb/Target/UnwindAssembly.h index 296f6376951..2630932bd51 100644 --- a/lldb/include/lldb/Target/UnwindAssembly.h +++ b/lldb/include/lldb/Target/UnwindAssembly.h @@ -11,6 +11,7 @@ #define utility_UnwindAssembly_h_ #include "lldb/lldb-private.h" +#include "lldb/Core/ArchSpec.h" #include "lldb/Core/PluginInterface.h" namespace lldb_private { @@ -43,8 +44,11 @@ public: Address& first_non_prologue_insn) = 0; protected: - UnwindAssembly(); + UnwindAssembly (const ArchSpec &arch); + ArchSpec m_arch; + private: + UnwindAssembly(); // Outlaw default constructor DISALLOW_COPY_AND_ASSIGN (UnwindAssembly); }; diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 7f3b30a374c..a3388b8873a 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -457,6 +457,13 @@ namespace lldb { } SectionType; + typedef enum EmulateInstructionOptions + { + eEmulateInstructionOptionNone = (0u), + eEmulateInstructionOptionAutoAdvancePC = (1u << 0), + eEmulateInstructionOptionIgnoreConditions = (1u << 1) + } EmulateInstructionOptions; + } // namespace lldb diff --git a/lldb/include/lldb/lldb-private-enumerations.h b/lldb/include/lldb/lldb-private-enumerations.h index ba22e71ec4e..fddc02daefd 100644 --- a/lldb/include/lldb/lldb-private-enumerations.h +++ b/lldb/include/lldb/lldb-private-enumerations.h @@ -204,6 +204,19 @@ typedef enum NameMatchType } NameMatchType; +//------------------------------------------------------------------ +/// Instruction types +//------------------------------------------------------------------ +typedef enum InstructionType +{ + eInstructionTypeAny, // Support for any instructions at all (at least one) + eInstructionTypePrologueEpilogue, // All prologue and epilogue instructons that push and pop register values and modify sp/fp + eInstructionTypePCModifying, // Any instruction that modifies the program counter/instruction pointer + eInstructionTypeAll // All instructions of any kind + +} InstructionType; + + } // namespace lldb diff --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h index c22371cbb51..0111c92bf15 100644 --- a/lldb/include/lldb/lldb-private-interfaces.h +++ b/lldb/include/lldb/lldb-private-interfaces.h @@ -22,7 +22,7 @@ namespace lldb_private typedef ObjectContainer* (*ObjectContainerCreateInstance) (Module* module, lldb::DataBufferSP& dataSP, const FileSpec *file, lldb::addr_t offset, lldb::addr_t length); typedef ObjectFile* (*ObjectFileCreateInstance) (Module* module, lldb::DataBufferSP& dataSP, const FileSpec* file, lldb::addr_t offset, lldb::addr_t length); typedef LogChannel* (*LogChannelCreateInstance) (); - typedef EmulateInstruction * (*EmulateInstructionCreateInstance) (const ArchSpec &arch); + typedef EmulateInstruction * (*EmulateInstructionCreateInstance) (const ArchSpec &arch, InstructionType inst_type); typedef LanguageRuntime *(*LanguageRuntimeCreateInstance) (Process *process, lldb::LanguageType language); typedef Platform* (*PlatformCreateInstance) (); typedef Process* (*ProcessCreateInstance) (Target &target, Listener &listener); diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 8e6569efc98..432f034fc8f 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -404,6 +404,7 @@ 26DE20611161902700A093E2 /* SBBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DE20601161902600A093E2 /* SBBlock.cpp */; }; 26DE20631161904200A093E2 /* SBLineEntry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DE20621161904200A093E2 /* SBLineEntry.cpp */; }; 26DE20651161904E00A093E2 /* SBSymbol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DE20641161904E00A093E2 /* SBSymbol.cpp */; }; + 26ECA04313665FED008D1F18 /* ARM_DWARF_Registers.c in Sources */ = {isa = PBXBuildFile; fileRef = 26ECA04213665FED008D1F18 /* ARM_DWARF_Registers.c */; }; 26F5C27710F3D9E4009D5894 /* Driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F5C27310F3D9E4009D5894 /* Driver.cpp */; }; 26F5C27810F3D9E4009D5894 /* IOChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F5C27510F3D9E4009D5894 /* IOChannel.cpp */; }; 26F5C32510F3DF23009D5894 /* libpython.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C32410F3DF23009D5894 /* libpython.dylib */; }; @@ -1043,6 +1044,7 @@ 26E3EEF811A994E800FBADB6 /* RegisterContextMacOSXFrameBackchain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextMacOSXFrameBackchain.h; path = Utility/RegisterContextMacOSXFrameBackchain.h; sourceTree = "<group>"; }; 26E6902E129C6BD500DDECD9 /* ClangExternalASTSourceCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangExternalASTSourceCallbacks.h; path = include/lldb/Symbol/ClangExternalASTSourceCallbacks.h; sourceTree = "<group>"; }; 26E69030129C6BEF00DDECD9 /* ClangExternalASTSourceCallbacks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangExternalASTSourceCallbacks.cpp; path = source/Symbol/ClangExternalASTSourceCallbacks.cpp; sourceTree = "<group>"; }; + 26ECA04213665FED008D1F18 /* ARM_DWARF_Registers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ARM_DWARF_Registers.c; path = source/Utility/ARM_DWARF_Registers.c; sourceTree = "<group>"; }; 26F5C26A10F3D9A4009D5894 /* lldb */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = lldb; sourceTree = BUILT_PRODUCTS_DIR; }; 26F5C27210F3D9E4009D5894 /* lldb-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "lldb-Info.plist"; path = "tools/driver/lldb-Info.plist"; sourceTree = "<group>"; }; 26F5C27310F3D9E4009D5894 /* Driver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Driver.cpp; path = tools/driver/Driver.cpp; sourceTree = "<group>"; }; @@ -1761,6 +1763,7 @@ 4C2FAE2E135E3A70001EDE44 /* SharedCluster.h */, 261B5A5311C3F2AD00AABD0A /* SharingPtr.h */, 26F996A7119B79C300412154 /* ARM_DWARF_Registers.h */, + 26ECA04213665FED008D1F18 /* ARM_DWARF_Registers.c */, 26F996A8119B79C300412154 /* ARM_GCC_Registers.h */, 2660D9F611922A1300958FBD /* StringExtractor.cpp */, 2660D9F711922A1300958FBD /* StringExtractor.h */, @@ -3231,6 +3234,7 @@ 2692BA231366150100F9E14D /* ArchVolatileRegs-x86.cpp in Sources */, 263E949F13661AEA00E7D1CE /* UnwindAssembly-x86.cpp in Sources */, 264D8D5013661BD7003A368F /* UnwindAssembly.cpp in Sources */, + 26ECA04313665FED008D1F18 /* ARM_DWARF_Registers.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme b/lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme index 3380f797b0a..76220409aee 100644 --- a/lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme +++ b/lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme @@ -74,8 +74,6 @@ <LaunchAction selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - displayScaleIsEnabled = "NO" - displayScale = "1.00" launchStyle = "0" useCustomWorkingDirectory = "YES" customWorkingDirectory = "/Volumes/work/gclayton/Documents/src/lldb/build/Debug" @@ -131,8 +129,6 @@ </AdditionalOptions> </LaunchAction> <ProfileAction - displayScaleIsEnabled = "NO" - displayScale = "1.00" shouldUseLaunchSchemeArgsEnv = "YES" savedToolIdentifier = "" useCustomWorkingDirectory = "NO" diff --git a/lldb/source/API/SBInstruction.cpp b/lldb/source/API/SBInstruction.cpp index 920ce3c60a6..0a5594a5a97 100644 --- a/lldb/source/API/SBInstruction.cpp +++ b/lldb/source/API/SBInstruction.cpp @@ -116,7 +116,7 @@ SBInstruction::Print (FILE *out) } bool -SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, bool auto_advance_pc) +SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options) { if (m_opaque_sp && frame.get()) { @@ -126,7 +126,7 @@ SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, bool auto_advance_pc) lldb_private::ArchSpec arch = target->GetArchitecture(); return m_opaque_sp->Emulate (arch, - auto_advance_pc, + evaluate_options, (void *) frame.get(), &lldb_private::EmulateInstruction::ReadMemoryFrame, &lldb_private::EmulateInstruction::WriteMemoryFrame, diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp index c765e6cb939..2c86b89c727 100644 --- a/lldb/source/Core/Disassembler.cpp +++ b/lldb/source/Core/Disassembler.cpp @@ -503,11 +503,11 @@ Instruction::GetAddressClass () bool Instruction::DumpEmulation (const ArchSpec &arch) { - std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, NULL)); + std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); if (insn_emulator_ap.get()) { - insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress()); - return insn_emulator_ap->EvaluateInstruction (); + insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); + return insn_emulator_ap->EvaluateInstruction (0); } return false; @@ -766,7 +766,7 @@ Instruction::TestEmulation (Stream *out_stream, const char *file_name) arch.SetTriple (llvm::Triple (value_sp->GetStringValue())); bool success = false; - std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, NULL)); + std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); if (insn_emulator_ap.get()) success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary); @@ -780,21 +780,20 @@ Instruction::TestEmulation (Stream *out_stream, const char *file_name) bool Instruction::Emulate (const ArchSpec &arch, - bool auto_advance_pc, + uint32_t evaluate_options, void *baton, EmulateInstruction::ReadMemory read_mem_callback, EmulateInstruction::WriteMemory write_mem_callback, EmulateInstruction::ReadRegister read_reg_callback, EmulateInstruction::WriteRegister write_reg_callback) { - std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, NULL)); + std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypeAny, NULL)); if (insn_emulator_ap.get()) { insn_emulator_ap->SetBaton (baton); insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback); - insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress()); - insn_emulator_ap->SetAdvancePC (auto_advance_pc); - return insn_emulator_ap->EvaluateInstruction (); + insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress(), NULL); + return insn_emulator_ap->EvaluateInstruction (evaluate_options); } return false; diff --git a/lldb/source/Core/EmulateInstruction.cpp b/lldb/source/Core/EmulateInstruction.cpp index 5a7006bd1f7..d730a532179 100644 --- a/lldb/source/Core/EmulateInstruction.cpp +++ b/lldb/source/Core/EmulateInstruction.cpp @@ -9,6 +9,7 @@ #include "lldb/Core/EmulateInstruction.h" +#include "lldb/Core/Address.h" #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/DataExtractor.h" #include "lldb/Core/Error.h" @@ -17,6 +18,7 @@ #include "lldb/Host/Endian.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "Plugins/Instruction/ARM/EmulateInstructionARM.h" @@ -25,7 +27,7 @@ using namespace lldb; using namespace lldb_private; EmulateInstruction* -EmulateInstruction::FindPlugin (const ArchSpec &arch, const char *plugin_name) +EmulateInstruction::FindPlugin (const ArchSpec &arch, InstructionType supported_inst_type, const char *plugin_name) { EmulateInstructionCreateInstance create_callback = NULL; if (plugin_name) @@ -33,7 +35,7 @@ EmulateInstruction::FindPlugin (const ArchSpec &arch, const char *plugin_name) create_callback = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (plugin_name); if (create_callback) { - EmulateInstruction *emulate_insn_ptr = create_callback(arch); + EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type); if (emulate_insn_ptr) return emulate_insn_ptr; } @@ -42,7 +44,7 @@ EmulateInstruction::FindPlugin (const ArchSpec &arch, const char *plugin_name) { for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != NULL; ++idx) { - EmulateInstruction *emulate_insn_ptr = create_callback(arch); + EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type); if (emulate_insn_ptr) return emulate_insn_ptr; } @@ -50,47 +52,14 @@ EmulateInstruction::FindPlugin (const ArchSpec &arch, const char *plugin_name) return NULL; } -EmulateInstruction::EmulateInstruction -( - lldb::ByteOrder byte_order, - uint32_t addr_byte_size, - const ArchSpec &arch, - void *baton, - ReadMemory read_mem_callback, - WriteMemory write_mem_callback, - ReadRegister read_reg_callback, - WriteRegister write_reg_callback -) : - m_byte_order (endian::InlHostByteOrder()), - m_addr_byte_size (addr_byte_size), - m_arch (arch), - m_baton (baton), - m_read_mem_callback (read_mem_callback), - m_write_mem_callback (write_mem_callback), - m_read_reg_callback (read_reg_callback), - m_write_reg_callback (write_reg_callback), - m_opcode_pc (LLDB_INVALID_ADDRESS), - m_opcode (), - m_advance_pc (false) -{ -} - -EmulateInstruction::EmulateInstruction -( - lldb::ByteOrder byte_order, - uint32_t addr_byte_size, - const ArchSpec &arch -) : - m_byte_order (endian::InlHostByteOrder()), - m_addr_byte_size (addr_byte_size), +EmulateInstruction::EmulateInstruction (const ArchSpec &arch) : m_arch (arch), m_baton (NULL), m_read_mem_callback (&ReadMemoryDefault), m_write_mem_callback (&WriteMemoryDefault), m_read_reg_callback (&ReadRegisterDefault), m_write_reg_callback (&WriteRegisterDefault), - m_opcode_pc (LLDB_INVALID_ADDRESS), - m_advance_pc (false) + m_opcode_pc (LLDB_INVALID_ADDRESS) { ::memset (&m_opcode, 0, sizeof (m_opcode)); } @@ -99,7 +68,7 @@ uint64_t EmulateInstruction::ReadRegisterUnsigned (uint32_t reg_kind, uint32_t reg_num, uint64_t fail_value, bool *success_ptr) { uint64_t uval64 = 0; - bool success = m_read_reg_callback (m_baton, reg_kind, reg_num, uval64); + bool success = m_read_reg_callback (this, m_baton, reg_kind, reg_num, uval64); if (success_ptr) *success_ptr = success; if (!success) @@ -110,7 +79,7 @@ EmulateInstruction::ReadRegisterUnsigned (uint32_t reg_kind, uint32_t reg_num, u bool EmulateInstruction::WriteRegisterUnsigned (const Context &context, uint32_t reg_kind, uint32_t reg_num, uint64_t reg_value) { - return m_write_reg_callback (m_baton, context, reg_kind, reg_num, reg_value); + return m_write_reg_callback (this, m_baton, context, reg_kind, reg_num, reg_value); } uint64_t @@ -121,11 +90,11 @@ EmulateInstruction::ReadMemoryUnsigned (const Context &context, lldb::addr_t add if (byte_size <= 8) { uint8_t buf[sizeof(uint64_t)]; - size_t bytes_read = m_read_mem_callback (m_baton, context, addr, buf, byte_size); + size_t bytes_read = m_read_mem_callback (this, m_baton, context, addr, buf, byte_size); if (bytes_read == byte_size) { uint32_t offset = 0; - DataExtractor data (buf, byte_size, m_byte_order, m_addr_byte_size); + DataExtractor data (buf, byte_size, GetByteOrder(), GetAddressByteSize()); uval64 = data.GetMaxU64 (&offset, byte_size); success = true; } @@ -149,7 +118,7 @@ EmulateInstruction::WriteMemoryUnsigned (const Context &context, StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder()); strm.PutMaxHex64 (uval, uval_byte_size); - size_t bytes_written = m_write_mem_callback (m_baton, context, addr, strm.GetData(), uval_byte_size); + size_t bytes_written = m_write_mem_callback (this, m_baton, context, addr, strm.GetData(), uval_byte_size); if (bytes_written == uval_byte_size) return true; return false; @@ -208,7 +177,8 @@ EmulateInstruction::SetWriteRegCallback (WriteRegister write_reg_callback) // size_t -EmulateInstruction::ReadMemoryFrame (void *baton, +EmulateInstruction::ReadMemoryFrame (EmulateInstruction *instruction, + void *baton, const Context &context, lldb::addr_t addr, void *dst, @@ -233,7 +203,8 @@ EmulateInstruction::ReadMemoryFrame (void *baton, } size_t -EmulateInstruction::WriteMemoryFrame (void *baton, +EmulateInstruction::WriteMemoryFrame (EmulateInstruction *instruction, + void *baton, const Context &context, lldb::addr_t addr, const void *dst, @@ -262,7 +233,8 @@ EmulateInstruction::WriteMemoryFrame (void *baton, } bool -EmulateInstruction::ReadRegisterFrame (void *baton, +EmulateInstruction::ReadRegisterFrame (EmulateInstruction *instruction, + void *baton, uint32_t reg_kind, uint32_t reg_num, uint64_t ®_value) @@ -289,7 +261,8 @@ EmulateInstruction::ReadRegisterFrame (void *baton, } bool -EmulateInstruction::WriteRegisterFrame (void *baton, +EmulateInstruction::WriteRegisterFrame (EmulateInstruction *instruction, + void *baton, const Context &context, uint32_t reg_kind, uint32_t reg_num, @@ -310,7 +283,8 @@ EmulateInstruction::WriteRegisterFrame (void *baton, } size_t -EmulateInstruction::ReadMemoryDefault (void *baton, +EmulateInstruction::ReadMemoryDefault (EmulateInstruction *instruction, + void *baton, const Context &context, lldb::addr_t addr, void *dst, @@ -324,7 +298,8 @@ EmulateInstruction::ReadMemoryDefault (void *baton, } size_t -EmulateInstruction::WriteMemoryDefault (void *baton, +EmulateInstruction::WriteMemoryDefault (EmulateInstruction *instruction, + void *baton, const Context &context, lldb::addr_t addr, const void *dst, @@ -336,7 +311,8 @@ EmulateInstruction::WriteMemoryDefault (void *baton, } bool -EmulateInstruction::ReadRegisterDefault (void *baton, +EmulateInstruction::ReadRegisterDefault (EmulateInstruction *instruction, + void *baton, uint32_t reg_kind, uint32_t reg_num, uint64_t ®_value) @@ -350,7 +326,8 @@ EmulateInstruction::ReadRegisterDefault (void *baton, } bool -EmulateInstruction::WriteRegisterDefault (void *baton, +EmulateInstruction::WriteRegisterDefault (EmulateInstruction *instruction, + void *baton, const Context &context, uint32_t reg_kind, uint32_t reg_num, @@ -601,54 +578,69 @@ EmulateInstruction::PrintContext (const char *context_type, const Context &conte } } -void -EmulateInstruction::TranslateRegister (uint32_t kind, uint32_t num, std::string &name) +bool +EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_addr, Target *target) { - if (kind == eRegisterKindDWARF) + m_opcode = opcode; + m_opcode_pc = LLDB_INVALID_ADDRESS; + if (inst_addr.IsValid()) { - if (num == 13) //dwarf_sp NOTE: This is ARM-SPECIFIC - name = "sp"; - else if (num == 14) //dwarf_lr NOTE: This is ARM-SPECIFIC - name = "lr"; - else if (num == 15) //dwarf_pc NOTE: This is ARM-SPECIFIC - name = "pc"; - else if (num == 16) //dwarf_cpsr NOTE: This is ARM-SPECIFIC - name = "cpsr"; - else - { - StreamString sstr; - - sstr.Printf ("r%d", num); - name = sstr.GetData(); - } - + if (target) + m_opcode_pc = inst_addr.GetLoadAddress (target); + if (m_opcode_pc == LLDB_INVALID_ADDRESS) + m_opcode_pc = inst_addr.GetFileAddress (); } - else if (kind == eRegisterKindGeneric) + return true; +} + + +const char * +EmulateInstruction::TranslateRegister (uint32_t kind, uint32_t num, std::string &name) +{ + if (kind == eRegisterKindGeneric) { - if (num == LLDB_REGNUM_GENERIC_SP) - name = "sp"; - else if (num == LLDB_REGNUM_GENERIC_FLAGS) - name = "cpsr"; - else if (num == LLDB_REGNUM_GENERIC_PC) - name = "pc"; - else if (num == LLDB_REGNUM_GENERIC_RA) - name = "lr"; - else + switch (num) { - StreamString sstr; - - sstr.Printf ("r%d", num); - name = sstr.GetData(); + case LLDB_REGNUM_GENERIC_PC: name = "pc"; break; + case LLDB_REGNUM_GENERIC_SP: name = "sp"; break; + case LLDB_REGNUM_GENERIC_FP: name = "fp"; break; + case LLDB_REGNUM_GENERIC_RA: name = "ra"; break; + case LLDB_REGNUM_GENERIC_FLAGS: name = "flags"; break; + default: name.clear(); break; } + if (!name.empty()) + return name.c_str(); } - else + const char *kind_cstr = NULL; + + switch (kind) { - StreamString sstr; + case eRegisterKindGCC: // the register numbers seen in eh_frame + kind_cstr = "gcc"; + break; + + case eRegisterKindDWARF: // the register numbers seen DWARF + kind_cstr = "dwarf"; + break; - sstr.Printf ("r%d", num); - name = sstr.GetData(); + case eRegisterKindGeneric: // insn ptr reg, stack ptr reg, etc not specific to any particular target + kind_cstr = "generic"; + break; + + case eRegisterKindGDB: // the register numbers gdb uses (matches stabs numbers?) + kind_cstr = "gdb"; + break; + + case eRegisterKindLLDB: // lldb's internal register numbers + kind_cstr = "lldb"; + break; } + + + StreamString sstr; + sstr.Printf ("%s(%u)", kind_cstr, num); + name.swap (sstr.GetString()); + return name.c_str(); } - diff --git a/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.cpp b/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.cpp index de8b5f8ff67..4be89faaca5 100644 --- a/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.cpp +++ b/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.cpp @@ -15,8 +15,8 @@ using namespace lldb; using namespace lldb_private; -lldb_private::ArchDefaultUnwindPlan * -ArchDefaultUnwindPlan_x86_64::CreateInstance (const lldb_private::ArchSpec &arch) +ArchDefaultUnwindPlan * +ArchDefaultUnwindPlan_x86_64::CreateInstance (const ArchSpec &arch) { if (arch.GetMachine () == llvm::Triple::x86_64) return new ArchDefaultUnwindPlan_x86_64 (); @@ -24,7 +24,7 @@ ArchDefaultUnwindPlan_x86_64::CreateInstance (const lldb_private::ArchSpec &arch } ArchDefaultUnwindPlan_x86_64::ArchDefaultUnwindPlan_x86_64() : - lldb_private::ArchDefaultUnwindPlan(), + ArchDefaultUnwindPlan(), m_unwind_plan_sp (new UnwindPlan) { UnwindPlan::Row row; @@ -96,15 +96,16 @@ ArchDefaultUnwindPlan_x86_64::GetPluginDescriptionStatic() } UnwindPlanSP -ArchDefaultUnwindPlan_x86_64::GetArchDefaultUnwindPlan (Thread& thread, Address current_pc) +ArchDefaultUnwindPlan_x86_64::GetArchDefaultUnwindPlan (Thread& thread, + const Address ¤t_pc) { return m_unwind_plan_sp; } -lldb_private::ArchDefaultUnwindPlan * -ArchDefaultUnwindPlan_i386::CreateInstance (const lldb_private::ArchSpec &arch) +ArchDefaultUnwindPlan * +ArchDefaultUnwindPlan_i386::CreateInstance (const ArchSpec &arch) { if (arch.GetMachine () == llvm::Triple::x86) return new ArchDefaultUnwindPlan_i386 (); @@ -112,7 +113,7 @@ ArchDefaultUnwindPlan_i386::CreateInstance (const lldb_private::ArchSpec &arch) } ArchDefaultUnwindPlan_i386::ArchDefaultUnwindPlan_i386() : - lldb_private::ArchDefaultUnwindPlan(), + ArchDefaultUnwindPlan(), m_unwind_plan_sp (new UnwindPlan) { UnwindPlan::Row row; @@ -185,7 +186,7 @@ ArchDefaultUnwindPlan_i386::GetPluginDescriptionStatic() } UnwindPlanSP -ArchDefaultUnwindPlan_i386::GetArchDefaultUnwindPlan (Thread& thread, Address current_pc) +ArchDefaultUnwindPlan_i386::GetArchDefaultUnwindPlan (Thread& thread, const Address ¤t_pc) { return m_unwind_plan_sp; } diff --git a/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.h b/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.h index 53b37dfc829..ce5abb1c0d8 100644 --- a/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.h +++ b/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.h @@ -15,8 +15,6 @@ #include "lldb/Target/Thread.h" #include "lldb/Symbol/UnwindPlan.h" -namespace lldb_private { - class ArchDefaultUnwindPlan_x86_64 : public lldb_private::ArchDefaultUnwindPlan { public: @@ -24,7 +22,8 @@ public: ~ArchDefaultUnwindPlan_x86_64 () { } virtual lldb::UnwindPlanSP - GetArchDefaultUnwindPlan (Thread& thread, Address current_pc); + GetArchDefaultUnwindPlan (lldb_private::Thread& thread, + const lldb_private::Address ¤t_pc); static lldb_private::ArchDefaultUnwindPlan * CreateInstance (const lldb_private::ArchSpec &arch); @@ -66,7 +65,8 @@ public: ~ArchDefaultUnwindPlan_i386 () { } virtual lldb::UnwindPlanSP - GetArchDefaultUnwindPlan (Thread& thread, Address current_pc); + GetArchDefaultUnwindPlan (lldb_private::Thread& thread, + const lldb_private::Address& current_pc); static lldb_private::ArchDefaultUnwindPlan * CreateInstance (const lldb_private::ArchSpec &arch); @@ -101,7 +101,4 @@ private: lldb::UnwindPlanSP m_unwind_plan_sp; }; - -} // namespace lldb_private - #endif // liblldb_UnwindAssembly_x86_h_ diff --git a/lldb/source/Plugins/ArchVolatileRegs/x86/ArchVolatileRegs-x86.h b/lldb/source/Plugins/ArchVolatileRegs/x86/ArchVolatileRegs-x86.h index 70e1d202672..c01bef581d7 100644 --- a/lldb/source/Plugins/ArchVolatileRegs/x86/ArchVolatileRegs-x86.h +++ b/lldb/source/Plugins/ArchVolatileRegs/x86/ArchVolatileRegs-x86.h @@ -15,8 +15,6 @@ #include "lldb/Target/ArchVolatileRegs.h" #include <set> -namespace lldb_private { - class ArchVolatileRegs_x86 : public lldb_private::ArchVolatileRegs { public: @@ -62,7 +60,4 @@ private: std::set<int> m_non_volatile_regs; }; - -} // namespace lldb_private - #endif // liblldb_ArchVolatileRegs_x86_h_ diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp index 702ca061da3..f6c52c0d8be 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -181,21 +181,24 @@ EmulateInstructionARM::GetPluginDescriptionStatic () } EmulateInstruction * -EmulateInstructionARM::CreateInstance (const ArchSpec &arch) +EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type) { - if (arch.GetTriple().getArch() == llvm::Triple::arm) - { - std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); - - if (emulate_insn_ap.get()) - return emulate_insn_ap.release(); - } - else if (arch.GetTriple().getArch() == llvm::Triple::thumb) + if (EmulateInstructionARM::SupportsEmulatingIntructionsOfTypeStatic(inst_type)) { - std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); - - if (emulate_insn_ap.get()) - return emulate_insn_ap.release(); + if (arch.GetTriple().getArch() == llvm::Triple::arm) + { + std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); + + if (emulate_insn_ap.get()) + return emulate_insn_ap.release(); + } + else if (arch.GetTriple().getArch() == llvm::Triple::thumb) + { + std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); + + if (emulate_insn_ap.get()) + return emulate_insn_ap.release(); + } } return NULL; @@ -340,7 +343,7 @@ EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding enc Register dwarf_reg; dwarf_reg.SetRegister (eRegisterKindDWARF, 0); Register sp_reg; - sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp); + sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); for (i=0; i<15; ++i) { if (BitIsSet (registers, i)) @@ -1247,7 +1250,7 @@ EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding EmulateInstruction::Context context; context.type = EmulateInstruction::eContextAdjustStackPointer; Register sp_reg; - sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp); + sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); context.SetRegisterPlusOffset (sp_reg, sp_offset); if (d == 15) @@ -1312,7 +1315,7 @@ EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding EmulateInstruction::Context context; context.type = EmulateInstruction::eContextAddition; Register sp_reg; - sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp); + sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); Register other_reg; other_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm); context.SetRegisterRegisterOperands (sp_reg, other_reg); @@ -1849,7 +1852,7 @@ EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding EmulateInstruction::Context context; context.type = EmulateInstruction::eContextPushRegisterOnStack; Register sp_reg; - sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp); + sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); context.SetRegisterPlusOffset (sp_reg, addr - sp); if (Rt != 15) { @@ -1952,7 +1955,7 @@ EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding en Register dwarf_reg; dwarf_reg.SetRegister (eRegisterKindDWARF, 0); Register sp_reg; - sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp); + sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); for (i=0; i<regs; ++i) { dwarf_reg.num = start_reg + d + i; @@ -2047,7 +2050,7 @@ EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding enc Register dwarf_reg; dwarf_reg.SetRegister (eRegisterKindDWARF, 0); Register sp_reg; - sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp); + sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); for (i=0; i<regs; ++i) { dwarf_reg.num = start_reg + d + i; @@ -9330,7 +9333,7 @@ EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding EmulateInstruction::Context context; context.type = eContextSubtraction; Register sp_reg; - sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp); + sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); Register dwarf_reg; dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m); context.SetRegisterRegisterOperands (sp_reg, dwarf_reg); @@ -10604,7 +10607,7 @@ EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding enc // // Combine the word-aligned words in the correct order for current endianness. // D[d+r] = if BigEndian() then word1:word2 else word2:word1; uint64_t data; - if (m_byte_order == eByteOrderBig) + if (GetByteOrder() == eByteOrderBig) { data = word1; data = (data << 32) | word2; @@ -10791,7 +10794,7 @@ EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding enc data_reg.num = start_reg + d + r; - if (m_byte_order == eByteOrderBig) + if (GetByteOrder() == eByteOrderBig) { context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) @@ -10931,7 +10934,7 @@ EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) // // Combine the word-aligned words in the correct order for current endianness. // D[d] = if BigEndian() then word1:word2 else word2:word1; uint64_t data64; - if (m_byte_order == eByteOrderBig) + if (GetByteOrder() == eByteOrderBig) { data64 = word1; data64 = (data64 << 32) | word2; @@ -11059,7 +11062,7 @@ EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) if (!success) return false; - if (m_byte_order == eByteOrderBig) + if (GetByteOrder() == eByteOrderBig) { if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) return false; @@ -12064,7 +12067,7 @@ EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncod } EmulateInstructionARM::ARMOpcode* -EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode) +EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) { static ARMOpcode g_arm_opcodes[] = @@ -12289,7 +12292,8 @@ EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode) for (size_t i=0; i<k_num_arm_opcodes; ++i) { - if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value) + if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && + (g_arm_opcodes[i].variants & arm_isa) != 0) return &g_arm_opcodes[i]; } return NULL; @@ -12297,7 +12301,7 @@ EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode) EmulateInstructionARM::ARMOpcode* -EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode) +EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) { static ARMOpcode @@ -12607,7 +12611,8 @@ EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode) const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode); for (size_t i=0; i<k_num_thumb_opcodes; ++i) { - if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value) + if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && + (g_thumb_opcodes[i].variants & arm_isa) != 0) return &g_thumb_opcodes[i]; } return NULL; @@ -12636,24 +12641,30 @@ EmulateInstructionARM::SetArchitecture (const ArchSpec &arch) } bool -EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr) +EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) { - m_opcode = insn_opcode; + if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target)) + { + if (m_arch.GetTriple().getArch() == llvm::Triple::thumb) + m_opcode_mode = eModeThumb; + else + { + AddressClass addr_class = inst_addr.GetAddressClass(); - if (m_arch.GetTriple().getArch() == llvm::Triple::thumb) - m_opcode_mode = eModeThumb; - else - { - AddressClass addr_class = inst_addr.GetAddressClass(); - - if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown)) - m_opcode_mode = eModeARM; - else if (addr_class == eAddressClassCodeAlternateISA) - m_opcode_mode = eModeThumb; - else - return false; - } - return true; + if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown)) + m_opcode_mode = eModeARM; + else if (addr_class == eAddressClassCodeAlternateISA) + m_opcode_mode = eModeThumb; + else + return false; + } + if (m_opcode_mode == eModeThumb) + m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; + else + m_opcode_cpsr = CPSR_MODE_USR; + return true; + } + return false; } bool @@ -12711,6 +12722,12 @@ EmulateInstructionARM::ArchVersion () bool EmulateInstructionARM::ConditionPassed (const uint32_t opcode) { + // If we are ignoring conditions, then always return true. + // this allows us to iterate over disassembly code and still + // emulate an instruction even if we don't have all the right + // bits set in the CPSR register... + if (m_ignore_conditions) + return true; const uint32_t cond = CurrentCond (opcode); @@ -12855,7 +12872,7 @@ EmulateInstructionARM::CurrentModeIsPrivileged () return false; if (mode == 16) - return false; + return false; return true; } @@ -13188,123 +13205,72 @@ EmulateInstructionARM::WriteFlags (Context &context, } bool -EmulateInstructionARM::EvaluateInstruction () +EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) { // Advance the ITSTATE bits to their values for the next instruction. if (m_opcode_mode == eModeThumb && m_it_session.InITBlock()) m_it_session.ITAdvance(); - - ARMOpcode *opcode_data; + ARMOpcode *opcode_data = NULL; if (m_opcode_mode == eModeThumb) - opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32()); + opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); else if (m_opcode_mode == eModeARM) - opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32()); - else - return false; + opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); - if (!opcode_data) + if (opcode_data == NULL) return false; - // Verify that we're the right arch for this opcode - switch (m_arm_isa) + const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; + m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions; + + bool success = false; + if (m_opcode_cpsr == 0 || m_ignore_conditions == false) { - case ARMv4: - if (opcode_data->variants != ARMvAll) - return false; - break; - - case ARMv4T: - if ((opcode_data->variants!= ARMvAll) - && (opcode_data->variants != ARMV4T_ABOVE)) - return false; - break; - - case ARMv5T: - case ARMv5TE: - if ((opcode_data->variants != ARMvAll) - && (opcode_data->variants != ARMV4T_ABOVE) - && (opcode_data->variants != ARMV5_ABOVE)) - return false; - break; - - case ARMv5TEJ: - if ((opcode_data->variants != ARMvAll) - && (opcode_data->variants != ARMV4T_ABOVE) - && (opcode_data->variants != ARMV5_ABOVE) - && (opcode_data->variants != ARMV5J_ABOVE)) - return false; - break; - - case ARMv6: - case ARMv6K: - if ((opcode_data->variants != ARMvAll) - && (opcode_data->variants != ARMV4T_ABOVE) - && (opcode_data->variants != ARMV5_ABOVE) - && (opcode_data->variants != ARMV5J_ABOVE) - && (opcode_data->variants != ARMV6_ABOVE)) - return false; - break; - - case ARMv6T2: - case ARMv7: - case ARMv8: - if ((opcode_data->variants != ARMvAll) - && (opcode_data->variants != ARMV4T_ABOVE) - && (opcode_data->variants != ARMV5_ABOVE) - && (opcode_data->variants != ARMV5J_ABOVE) - && (opcode_data->variants != ARMV6_ABOVE) - && (opcode_data->variants != ARMV6T2_ABOVE)) - return false; - break; - - default: -// if (opcode_data->variants != ARMvAll) -// return false; - break; + m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF, + dwarf_cpsr, + 0, + &success); } + + // Only return false if we are unable to read the CPSR if we care about conditions + if (success == false && m_ignore_conditions == false) + return false; - // Just for now, for testing purposes. - if (m_baton == NULL) - fprintf (stdout, "\nEvaluateInstruction, opcode (0x%x), found = '%s'\n", m_opcode.GetOpcode32(), - opcode_data->name); - - bool success; - if (m_baton) + uint32_t orig_pc_value = 0; + if (auto_advance_pc) { - uint32_t cpsr_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success); - if (success) - m_opcode_cpsr = cpsr_value; + orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); + if (!success) + return false; } - uint32_t orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); - if (!success) - return false; - - success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); // Call the Emulate... function. - if (!success) - return false; - - uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); + // Call the Emulate... function. + success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); if (!success) return false; - if (m_advance_pc && (after_pc_value == orig_pc_value)) + if (auto_advance_pc) { - if (opcode_data->size == eSize32) - after_pc_value += 4; - else if (opcode_data->size == eSize16) - after_pc_value += 2; - - EmulateInstruction::Context context; - context.type = eContextAdvancePC; - context.SetNoArgs(); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value)) + uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); + if (!success) return false; + if (auto_advance_pc && (after_pc_value == orig_pc_value)) + { + if (opcode_data->size == eSize32) + after_pc_value += 4; + else if (opcode_data->size == eSize16) + after_pc_value += 2; + + EmulateInstruction::Context context; + context.type = eContextAdvancePC; + context.SetNoArgs(); + if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value)) + return false; + + } } - return true; } @@ -13331,10 +13297,6 @@ EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, Option } test_opcode = value_sp->GetUInt64Value (); - // If the instruction emulation does not directly update the PC, advance the PC to the next instruction after - // performing the emulation. - SetAdvancePC (true); - if (arch.GetTriple().getArch() == llvm::Triple::arm) { m_opcode_mode = eModeARM; @@ -13392,7 +13354,7 @@ EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, Option &EmulationStateARM::ReadPseudoRegister, &EmulationStateARM::WritePseudoRegister); - bool success = EvaluateInstruction (); + bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC); if (!success) { out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n"); @@ -13406,3 +13368,26 @@ EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, Option return success; } + +const char * +EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) +{ + if (reg_kind == eRegisterKindGeneric) + { + switch (reg_num) + { + case LLDB_REGNUM_GENERIC_PC: return "pc"; + case LLDB_REGNUM_GENERIC_SP: return "sp"; + case LLDB_REGNUM_GENERIC_FP: return "fp"; + case LLDB_REGNUM_GENERIC_RA: return "lr"; + case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; + default: return NULL; + } + } + else if (reg_kind == eRegisterKindDWARF) + { + return GetARMDWARFRegisterName (reg_num); + } + return NULL; +} + diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h index faaae730680..bb7b7c23b3b 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h @@ -75,8 +75,28 @@ public: GetPluginDescriptionStatic (); static lldb_private::EmulateInstruction * - CreateInstance (const lldb_private::ArchSpec &arch); + CreateInstance (const lldb_private::ArchSpec &arch, + InstructionType inst_type); + static bool + SupportsEmulatingIntructionsOfTypeStatic (InstructionType inst_type) + { + switch (inst_type) + { + case eInstructionTypeAny: + case eInstructionTypePrologueEpilogue: + case eInstructionTypePCModifying: + return true; + + case eInstructionTypeAll: + return false; + + default: + break; + } + return false; + } + virtual const char * GetPluginName() { @@ -106,38 +126,43 @@ public: }; EmulateInstructionARM (const ArchSpec &arch) : - EmulateInstruction (lldb::eByteOrderLittle, - 4, - arch), + EmulateInstruction (arch), m_arm_isa (0), m_opcode_mode (eModeInvalid), m_opcode_cpsr (0), - m_it_session () + m_it_session (), + m_ignore_conditions (false) { + SetArchitecture (arch); } - EmulateInstructionARM (const ArchSpec &arch, - void *baton, - ReadMemory read_mem_callback, - WriteMemory write_mem_callback, - ReadRegister read_reg_callback, - WriteRegister write_reg_callback) : - EmulateInstruction (lldb::eByteOrderLittle, // Byte order for ARM - 4, // Address size in byte - arch, - baton, - read_mem_callback, - write_mem_callback, - read_reg_callback, - write_reg_callback), - m_arm_isa (0), - m_opcode_mode (eModeInvalid), - m_opcode_cpsr (0), - m_it_session () +// EmulateInstructionARM (const ArchSpec &arch, +// bool ignore_conditions, +// void *baton, +// ReadMemory read_mem_callback, +// WriteMemory write_mem_callback, +// ReadRegister read_reg_callback, +// WriteRegister write_reg_callback) : +// EmulateInstruction (arch, +// ignore_conditions, +// baton, +// read_mem_callback, +// write_mem_callback, +// read_reg_callback, +// write_reg_callback), +// m_arm_isa (0), +// m_opcode_mode (eModeInvalid), +// m_opcode_cpsr (0), +// m_it_session () +// { +// } + + virtual bool + SupportsEmulatingIntructionsOfType (InstructionType inst_type) { + return SupportsEmulatingIntructionsOfTypeStatic (inst_type); } - - + virtual bool SetArchitecture (const ArchSpec &arch); @@ -145,14 +170,17 @@ public: ReadInstruction (); virtual bool - SetInstruction (const Opcode &insn_opcode, const Address &inst_addr); + SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target); virtual bool - EvaluateInstruction (); + EvaluateInstruction (uint32_t evaluate_options); virtual bool TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data); + virtual const char * + GetRegisterName (uint32_t reg_kind, uint32_t reg_num); + uint32_t ArchVersion(); @@ -340,10 +368,10 @@ protected: static ARMOpcode* - GetARMOpcodeForInstruction (const uint32_t opcode); + GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t isa_mask); static ARMOpcode* - GetThumbOpcodeForInstruction (const uint32_t opcode); + GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t isa_mask); // A8.6.123 PUSH bool @@ -948,6 +976,7 @@ protected: uint32_t m_opcode_cpsr; uint32_t m_new_inst_cpsr; // This can get updated by the opcode. ITSession m_it_session; + bool m_ignore_conditions; }; } // namespace lldb_private diff --git a/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp index 7fb65a495be..72fc484e0d9 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp +++ b/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp @@ -187,11 +187,12 @@ EmulationStateARM::ReadFromPseudoAddress (lldb::addr_t p_address, uint32_t size, } size_t -EmulationStateARM::ReadPseudoMemory (void *baton, - const EmulateInstruction::Context &context, - lldb::addr_t addr, - void *dst, - size_t length) +EmulationStateARM::ReadPseudoMemory (EmulateInstruction *instruction, + void *baton, + const EmulateInstruction::Context &context, + lldb::addr_t addr, + void *dst, + size_t length) { if (!baton) return 0; @@ -230,11 +231,12 @@ EmulationStateARM::ReadPseudoMemory (void *baton, } size_t -EmulationStateARM::WritePseudoMemory (void *baton, - const EmulateInstruction::Context &context, - lldb::addr_t addr, - const void *dst, - size_t length) +EmulationStateARM::WritePseudoMemory (EmulateInstruction *instruction, + void *baton, + const EmulateInstruction::Context &context, + lldb::addr_t addr, + const void *dst, + size_t length) { if (!baton) return 0; @@ -250,10 +252,11 @@ EmulationStateARM::WritePseudoMemory (void *baton, } bool -EmulationStateARM::ReadPseudoRegister (void *baton, - uint32_t reg_kind, - uint32_t reg_num, - uint64_t ®_value) +EmulationStateARM::ReadPseudoRegister (EmulateInstruction *instruction, + void *baton, + uint32_t reg_kind, + uint32_t reg_num, + uint64_t ®_value) { if (!baton) return false; @@ -284,11 +287,12 @@ EmulationStateARM::ReadPseudoRegister (void *baton, } bool -EmulationStateARM::WritePseudoRegister (void *baton, - const EmulateInstruction::Context &context, - uint32_t reg_kind, - uint32_t reg_num, - uint64_t reg_value) +EmulationStateARM::WritePseudoRegister (EmulateInstruction *instruction, + void *baton, + const EmulateInstruction::Context &context, + uint32_t reg_kind, + uint32_t reg_num, + uint64_t reg_value) { if (!baton) return false; diff --git a/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h b/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h index 025ff9e3d94..1dcc680f973 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h +++ b/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h @@ -16,8 +16,6 @@ #include "lldb/Core/Opcode.h" #include "lldb/Interpreter/NamedOptionValue.h" -namespace lldb_private { - class EmulationStateARM { public: @@ -45,37 +43,41 @@ public: ClearPseudoMemory (); bool - LoadPseudoRegistersFromFrame (StackFrame &frame); + LoadPseudoRegistersFromFrame (lldb_private::StackFrame &frame); bool - LoadStateFromDictionary (OptionValueDictionary *test_data); + LoadStateFromDictionary (lldb_private::OptionValueDictionary *test_data); bool CompareState (EmulationStateARM &other_state); static size_t - ReadPseudoMemory (void *baton, - const EmulateInstruction::Context &context, + ReadPseudoMemory (lldb_private::EmulateInstruction *instruction, + void *baton, + const lldb_private::EmulateInstruction::Context &context, lldb::addr_t addr, void *dst, size_t length); static size_t - WritePseudoMemory (void *baton, - const EmulateInstruction::Context &context, + WritePseudoMemory (lldb_private::EmulateInstruction *instruction, + void *baton, + const lldb_private::EmulateInstruction::Context &context, lldb::addr_t addr, const void *dst, size_t length); static bool - ReadPseudoRegister (void *baton, + ReadPseudoRegister (lldb_private::EmulateInstruction *instruction, + void *baton, uint32_t reg_kind, uint32_t reg_num, uint64_t ®_value); static bool - WritePseudoRegister (void *baton, - const EmulateInstruction::Context &context, + WritePseudoRegister (lldb_private::EmulateInstruction *instruction, + void *baton, + const lldb_private::EmulateInstruction::Context &context, uint32_t reg_kind, uint32_t reg_num, uint64_t reg_value); @@ -97,7 +99,5 @@ private: DISALLOW_COPY_AND_ASSIGN (EmulationStateARM); }; - -} // namespace lldb_private #endif // lldb_EmulationStateARM_h_ diff --git a/lldb/source/Plugins/Process/Utility/ARMDefines.h b/lldb/source/Plugins/Process/Utility/ARMDefines.h index 0ef8c61449a..3cc9d4674c3 100644 --- a/lldb/source/Plugins/Process/Utility/ARMDefines.h +++ b/lldb/source/Plugins/Process/Utility/ARMDefines.h @@ -79,6 +79,15 @@ static inline const char *ARMCondCodeToString(uint32_t CC) #define CPSR_Z_POS 30 #define CPSR_N_POS 31 +// CPSR mode definitions +#define CPSR_MODE_USR 0x10u +#define CPSR_MODE_FIQ 0x11u +#define CPSR_MODE_IRQ 0x12u +#define CPSR_MODE_SVC 0x13u +#define CPSR_MODE_ABT 0x17u +#define CPSR_MODE_UND 0x1bu +#define CPSR_MODE_SYS 0x1fu + // Masks for CPSR #define MASK_CPSR_MODE_MASK (0x0000001fu) #define MASK_CPSR_T (1u << CPSR_T_POS) diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index 351b6eb2bc9..3e9cef34c19 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -143,16 +143,21 @@ ThreadGDBRemote::GetUnwinder () { const ArchSpec target_arch (GetProcess().GetTarget().GetArchitecture ()); const llvm::Triple::ArchType machine = target_arch.GetMachine(); - if (machine == llvm::Triple::x86_64 || machine == llvm::Triple::x86) + switch (machine) { - m_unwinder_ap.reset (new UnwindLLDB (*this)); - } + case llvm::Triple::x86_64: + case llvm::Triple::x86: + case llvm::Triple::arm: + case llvm::Triple::thumb: + m_unwinder_ap.reset (new UnwindLLDB (*this)); + break; + + default: #if defined(__APPLE__) - else - { - m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this)); - } + m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this)); #endif + break; + } } return m_unwinder_ap.get(); } diff --git a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp index 1379cd4ce12..d9855b7c788 100644 --- a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp +++ b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp @@ -12,16 +12,16 @@ #include "llvm-c/EnhancedDisassembly.h" #include "lldb/Core/Address.h" -#include "lldb/Core/Error.h" #include "lldb/Core/ArchSpec.h" +#include "lldb/Core/DataBufferHeap.h" +#include "lldb/Core/Disassembler.h" +#include "lldb/Core/Error.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Core/StreamFile.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" -#include "lldb/Target/RegisterContext.h" #include "lldb/Target/Thread.h" #include "lldb/Target/Target.h" -#include "lldb/Target/UnwindAssembly.h" using namespace lldb; using namespace lldb_private; @@ -33,19 +33,108 @@ using namespace lldb_private; //----------------------------------------------------------------------------------------------- bool -UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, Thread& thread, UnwindPlan& unwind_plan) +UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& range, + Thread& thread, + UnwindPlan& unwind_plan) { +#if 0 + UnwindPlan::Row row; + UnwindPlan::Row::RegisterLocation regloc; + + m_unwind_plan_sp->SetRegisterKind (eRegisterKindGeneric); + row.SetCFARegister (LLDB_REGNUM_GENERIC_FP); + row.SetCFAOffset (2 * 8); + row.SetOffset (0); + + regloc.SetAtCFAPlusOffset (2 * -8); + row.SetRegisterInfo (LLDB_REGNUM_GENERIC_FP, regloc); + regloc.SetAtCFAPlusOffset (1 * -8); + row.SetRegisterInfo (LLDB_REGNUM_GENERIC_PC, regloc); + regloc.SetIsCFAPlusOffset (0); + row.SetRegisterInfo (LLDB_REGNUM_GENERIC_SP, regloc); + + m_unwind_plan_sp->AppendRow (row); + m_unwind_plan_sp->SetSourceName ("x86_64 architectural default"); +#endif + + if (range.GetByteSize() > 0 && + range.GetBaseAddress().IsValid() && + m_inst_emulator_ap.get()) + { +#if 0 + Target &target = thread.GetProcess().GetTarget(); + const ArchSpec &target_arch = target.GetArchitecture(); + bool prefer_file_cache = true; + Error error; + DataBufferHeap data_buffer (range.GetByteSize(), 0); + if (target.ReadMemory (range.GetBaseAddress(), + prefer_file_cache, + data_buffer.GetBytes(), + data_buffer.GetByteSize(), + error) == data_buffer.GetByteSize()) + { + DataExtractor data (data_buffer.GetBytes(), + data_buffer.GetByteSize(), + target_arch.GetByteOrder(), + target_arch.GetAddressByteSize()); + } +#endif + StreamFile strm (stdout, false); + + ExecutionContext exe_ctx; + thread.CalculateExecutionContext(exe_ctx); + DisassemblerSP disasm_sp (Disassembler::DisassembleRange (m_arch, + NULL, + exe_ctx, + range)); + if (disasm_sp) + { + + m_range_ptr = ⦥ + m_thread_ptr = &thread; + m_unwind_plan_ptr = &unwind_plan; + + const uint32_t addr_byte_size = m_arch.GetAddressByteSize(); + const bool show_address = true; + const bool show_bytes = true; + const bool raw = false; + // Initialize the stack pointer with a known value. In the 32 bit case + // it will be 0x80000000, and in the 64 bit case 0x8000000000000000. + // We use the address byte size to be safe for any future addresss sizes + SetRegisterValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, (1ull << ((addr_byte_size * 8) - 1))); + + const InstructionList &inst_list = disasm_sp->GetInstructionList (); + const size_t num_instructions = inst_list.GetSize(); + for (size_t idx=0; idx<num_instructions; ++idx) + { + Instruction *inst = inst_list.GetInstructionAtIndex (idx).get(); + if (inst) + { + inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize (), show_address, show_bytes, &exe_ctx, raw); + strm.EOL(); + + m_inst_emulator_ap->SetInstruction (inst->GetOpcode(), inst->GetAddress(), exe_ctx.target); + m_inst_emulator_ap->EvaluateInstruction (eEmulateInstructionOptionIgnoreConditions); + } + } + } + } return false; } bool -UnwindAssemblyInstEmulation::GetFastUnwindPlan (AddressRange& func, Thread& thread, UnwindPlan &unwind_plan) +UnwindAssemblyInstEmulation::GetFastUnwindPlan (AddressRange& func, + Thread& thread, + UnwindPlan &unwind_plan) { return false; } bool -UnwindAssemblyInstEmulation::FirstNonPrologueInsn (AddressRange& func, Target& target, Thread* thread, Address& first_non_prologue_insn) +UnwindAssemblyInstEmulation::FirstNonPrologueInsn (AddressRange& func, + Target& target, + Thread* thread, + Address& first_non_prologue_insn) { return false; } @@ -53,6 +142,10 @@ UnwindAssemblyInstEmulation::FirstNonPrologueInsn (AddressRange& func, Target& t UnwindAssembly * UnwindAssemblyInstEmulation::CreateInstance (const ArchSpec &arch) { + std::auto_ptr<lldb_private::EmulateInstruction> inst_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypePrologueEpilogue, NULL)); + // Make sure that all prologue instructions are handled + if (inst_emulator_ap.get()) + return new UnwindAssemblyInstEmulation (arch, inst_emulator_ap.release()); return NULL; } @@ -106,3 +199,120 @@ UnwindAssemblyInstEmulation::GetPluginDescriptionStatic() { return "Instruction emulation based unwind information."; } + + + +size_t +UnwindAssemblyInstEmulation::ReadMemory (EmulateInstruction *instruction, + void *baton, + const EmulateInstruction::Context &context, + lldb::addr_t addr, + void *dst, + size_t dst_len) +{ + //UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton; + printf ("UnwindAssemblyInstEmulation::ReadMemory (context.type = %i, context.info_type = %i, addr = 0x%16.16llx, dst = %p, dst_len = %zu)\n", + context.type, + context.info_type, + addr, + dst, + dst_len); + return dst_len; +} + +size_t +UnwindAssemblyInstEmulation::WriteMemory (EmulateInstruction *instruction, + void *baton, + const EmulateInstruction::Context &context, + lldb::addr_t addr, + const void *dst, + size_t dst_len) +{ + // UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton; + + DataExtractor data (dst, + dst_len, + instruction->GetArchitecture ().GetByteOrder(), + instruction->GetArchitecture ().GetAddressByteSize()); + StreamFile strm(stdout, false); + + strm.Printf ("UnwindAssemblyInstEmulation::WriteMemory (context.type = %i, context.info_type = %i, ", + context.type, + context.info_type); + data.Dump(&strm, 0, eFormatBytes, 1, dst_len, UINT32_MAX, addr, 0, 0); + strm.EOL(); + return dst_len; +} + +bool +UnwindAssemblyInstEmulation::ReadRegister (EmulateInstruction *instruction, + void *baton, + uint32_t reg_kind, + uint32_t reg_num, + uint64_t ®_value) +{ + UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton; + const char *reg_name = instruction->GetRegisterName (reg_kind, reg_num); + + reg_value = inst_emulator->GetRegisterValue (reg_kind, reg_num); + + printf ("UnwindAssemblyInstEmulation::ReadRegister (name = \"%s\") => value = 0x%16.16llx\n", reg_name, reg_value); + + return true; +} + +bool +UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction, + void *baton, + const EmulateInstruction::Context &context, + uint32_t reg_kind, + uint32_t reg_num, + uint64_t reg_value) +{ + UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton; + const char *reg_name = instruction->GetRegisterName (reg_kind, reg_num); + + printf ("UnwindAssemblyInstEmulation::WriteRegister (name = \"%s\", value = 0x%16.16llx, context.type = %i, context.info_type = %i)\n", + reg_name, + reg_value, + context.type, + context.info_type); + + inst_emulator->SetRegisterValue (reg_kind, reg_num, reg_value); + + switch (context.type) + { + case EmulateInstruction::eContextInvalid: + case EmulateInstruction::eContextReadOpcode: + case EmulateInstruction::eContextImmediate: + case EmulateInstruction::eContextAdjustBaseRegister: + case EmulateInstruction::eContextRegisterPlusOffset: + case EmulateInstruction::eContextAdjustPC: + case EmulateInstruction::eContextRegisterStore: + case EmulateInstruction::eContextRegisterLoad: + case EmulateInstruction::eContextRelativeBranchImmediate: + case EmulateInstruction::eContextAbsoluteBranchRegister: + case EmulateInstruction::eContextSupervisorCall: + case EmulateInstruction::eContextTableBranchReadMemory: + case EmulateInstruction::eContextWriteRegisterRandomBits: + case EmulateInstruction::eContextWriteMemoryRandomBits: + case EmulateInstruction::eContextMultiplication: + case EmulateInstruction::eContextAddition: + case EmulateInstruction::eContextSubtraction: + case EmulateInstruction::eContextAdvancePC: + case EmulateInstruction::eContextReturnFromException: + break; + + case EmulateInstruction::eContextPushRegisterOnStack: + break; + + case EmulateInstruction::eContextPopRegisterOffStack: + break; + + case EmulateInstruction::eContextAdjustStackPointer: + break; + } + return true; +} + + diff --git a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h index f6137389c95..c18cbabdfa7 100644 --- a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h +++ b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h @@ -11,8 +11,8 @@ #define liblldb_UnwindAssemblyInstEmulation_h_ #include "lldb/lldb-private.h" +#include "lldb/Core/EmulateInstruction.h" #include "lldb/Target/UnwindAssembly.h" -#include "lldb/Target/Thread.h" class UnwindAssemblyInstEmulation : public lldb_private::UnwindAssembly { @@ -43,7 +43,6 @@ public: static lldb_private::UnwindAssembly * CreateInstance (const lldb_private::ArchSpec &arch); - //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ @@ -69,14 +68,83 @@ public: GetPluginVersion(); private: + + static size_t + ReadMemory (lldb_private::EmulateInstruction *instruction, + void *baton, + const lldb_private::EmulateInstruction::Context &context, + lldb::addr_t addr, + void *dst, + size_t length); + + static size_t + WriteMemory (lldb_private::EmulateInstruction *instruction, + void *baton, + const lldb_private::EmulateInstruction::Context &context, + lldb::addr_t addr, + const void *dst, + size_t length); + + static bool + ReadRegister (lldb_private::EmulateInstruction *instruction, + void *baton, + uint32_t reg_kind, + uint32_t reg_num, + uint64_t ®_value); + + static bool + WriteRegister (lldb_private::EmulateInstruction *instruction, + void *baton, + const lldb_private::EmulateInstruction::Context &context, + uint32_t reg_kind, + uint32_t reg_num, + uint64_t reg_value); + // Call CreateInstance to get an instance of this class - UnwindAssemblyInstEmulation(int cpu) : - lldb_private::UnwindAssembly(), m_cpu(cpu) + UnwindAssemblyInstEmulation (const lldb_private::ArchSpec &arch, + lldb_private::EmulateInstruction *inst_emulator) : + UnwindAssembly (arch), + m_inst_emulator_ap (inst_emulator), + m_range_ptr (NULL), + m_thread_ptr (NULL), + m_unwind_plan_ptr (NULL) + { + if (m_inst_emulator_ap.get()) + { + m_inst_emulator_ap->SetBaton (this); + m_inst_emulator_ap->SetCallbacks (ReadMemory, WriteMemory, ReadRegister, WriteRegister); + } + } + + static uint64_t + MakeRegisterKindValuePair (uint32_t reg_kind, uint32_t reg_num) + { + return (uint64_t)reg_kind << 32 | reg_num; + } + + void + SetRegisterValue (uint32_t reg_kind, uint32_t reg_num, uint64_t reg_value) + { + m_register_values[MakeRegisterKindValuePair (reg_kind, reg_num)] = reg_value; + } + + uint64_t + GetRegisterValue (uint32_t reg_kind, uint32_t reg_num) { + const uint64_t reg_id = MakeRegisterKindValuePair (reg_kind, reg_num); + RegisterValueMap::const_iterator pos = m_register_values.find(reg_id); + if (pos != m_register_values.end()) + return pos->second; + return (uint64_t)reg_kind << 24 | (uint64_t)reg_num; } - int m_cpu; + std::auto_ptr<lldb_private::EmulateInstruction> m_inst_emulator_ap; + lldb_private::AddressRange* m_range_ptr; + lldb_private::Thread* m_thread_ptr; + lldb_private::UnwindPlan* m_unwind_plan_ptr; + typedef std::map<uint64_t, uint64_t> RegisterValueMap; + RegisterValueMap m_register_values; }; #endif // liblldb_UnwindAssemblyInstEmulation_h_ diff --git a/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp b/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp index 28bb3364243..8382e3ea26f 100644 --- a/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp +++ b/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp @@ -818,6 +818,17 @@ AssemblyParse_x86::find_first_non_prologue_insn (Address &address) // UnwindAssemblyParser_x86 method definitions //----------------------------------------------------------------------------------------------- +UnwindAssembly_x86::UnwindAssembly_x86 (const ArchSpec &arch, int cpu) : + lldb_private::UnwindAssembly(arch), + m_cpu(cpu) +{ +} + + +UnwindAssembly_x86::~UnwindAssembly_x86 () +{ +} + bool UnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, Thread& thread, UnwindPlan& unwind_plan) { @@ -844,9 +855,9 @@ UnwindAssembly_x86::CreateInstance (const ArchSpec &arch) { const llvm::Triple::ArchType cpu = arch.GetMachine (); if (cpu == llvm::Triple::x86) - return new UnwindAssembly_x86 (k_i386); + return new UnwindAssembly_x86 (arch, k_i386); else if (cpu == llvm::Triple::x86_64) - return new UnwindAssembly_x86 (k_x86_64); + return new UnwindAssembly_x86 (arch, k_x86_64); return NULL; } diff --git a/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h b/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h index 4c29dcf7b28..f5d039141b2 100644 --- a/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h +++ b/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h @@ -12,25 +12,29 @@ #include "lldb/lldb-private.h" #include "lldb/Target/UnwindAssembly.h" -#include "lldb/Target/Thread.h" -namespace lldb_private { - class UnwindAssembly_x86 : public lldb_private::UnwindAssembly { public: - ~UnwindAssembly_x86 () { } + ~UnwindAssembly_x86 (); virtual bool - GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, lldb_private::Thread& thread, UnwindPlan& unwind_plan); + GetNonCallSiteUnwindPlanFromAssembly (lldb_private::AddressRange& func, + lldb_private::Thread& thread, + lldb_private::UnwindPlan& unwind_plan); virtual bool - GetFastUnwindPlan (AddressRange& func, lldb_private::Thread& thread, UnwindPlan &unwind_plan); + GetFastUnwindPlan (lldb_private::AddressRange& func, + lldb_private::Thread& thread, + lldb_private::UnwindPlan &unwind_plan); // thread may be NULL in which case we only use the Target (e.g. if this is called pre-process-launch). virtual bool - FirstNonPrologueInsn (AddressRange& func, lldb_private::Target& target, lldb_private::Thread* thread, Address& first_non_prologue_insn); + FirstNonPrologueInsn (lldb_private::AddressRange& func, + lldb_private::Target& target, + lldb_private::Thread* thread, + lldb_private::Address& first_non_prologue_insn); static lldb_private::UnwindAssembly * CreateInstance (const lldb_private::ArchSpec &arch); @@ -61,13 +65,10 @@ public: GetPluginVersion(); private: - UnwindAssembly_x86(int cpu) : - lldb_private::UnwindAssembly(), m_cpu(cpu) { } // Call CreateInstance instead. + UnwindAssembly_x86 (const lldb_private::ArchSpec &arch, int cpu); int m_cpu; }; -} // namespace lldb_private - #endif // liblldb_UnwindAssembly_x86_h_ diff --git a/lldb/source/Target/ExecutionContext.cpp b/lldb/source/Target/ExecutionContext.cpp index 15b4dc8f9be..581ba6a9952 100644 --- a/lldb/source/Target/ExecutionContext.cpp +++ b/lldb/source/Target/ExecutionContext.cpp @@ -6,12 +6,6 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// - -// -//===----------------------------------------------------------------------===// - #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/ExecutionContextScope.h" diff --git a/lldb/source/Target/UnwindAssembly.cpp b/lldb/source/Target/UnwindAssembly.cpp index ba3ba6f7eb1..af662b97c74 100644 --- a/lldb/source/Target/UnwindAssembly.cpp +++ b/lldb/source/Target/UnwindAssembly.cpp @@ -31,7 +31,8 @@ UnwindAssembly::FindPlugin (const ArchSpec &arch) return NULL; } -UnwindAssembly::UnwindAssembly () +UnwindAssembly::UnwindAssembly (const ArchSpec &arch) : + m_arch (arch) { } diff --git a/lldb/source/Utility/ARM_DWARF_Registers.c b/lldb/source/Utility/ARM_DWARF_Registers.c new file mode 100644 index 00000000000..2008e19ba20 --- /dev/null +++ b/lldb/source/Utility/ARM_DWARF_Registers.c @@ -0,0 +1,183 @@ +//===-- ARM_DWARF_Registers.c -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ARM_DWARF_Registers.h" + +const char * +GetARMDWARFRegisterName (unsigned reg_num) +{ + switch (reg_num) + { + case dwarf_r0: return "r0"; + case dwarf_r1: return "r1"; + case dwarf_r2: return "r2"; + case dwarf_r3: return "r3"; + case dwarf_r4: return "r4"; + case dwarf_r5: return "r5"; + case dwarf_r6: return "r6"; + case dwarf_r7: return "r7"; + case dwarf_r8: return "r8"; + case dwarf_r9: return "r9"; + case dwarf_r10: return "r10"; + case dwarf_r11: return "r11"; + case dwarf_r12: return "r12"; + case dwarf_sp: return "sp"; + case dwarf_lr: return "lr"; + case dwarf_pc: return "pc"; + case dwarf_cpsr:return "cpsr"; + + case dwarf_s0: return "s0"; + case dwarf_s1: return "s1"; + case dwarf_s2: return "s2"; + case dwarf_s3: return "s3"; + case dwarf_s4: return "s4"; + case dwarf_s5: return "s5"; + case dwarf_s6: return "s6"; + case dwarf_s7: return "s7"; + case dwarf_s8: return "s8"; + case dwarf_s9: return "s9"; + case dwarf_s10: return "s10"; + case dwarf_s11: return "s11"; + case dwarf_s12: return "s12"; + case dwarf_s13: return "s13"; + case dwarf_s14: return "s14"; + case dwarf_s15: return "s15"; + case dwarf_s16: return "s16"; + case dwarf_s17: return "s17"; + case dwarf_s18: return "s18"; + case dwarf_s19: return "s19"; + case dwarf_s20: return "s20"; + case dwarf_s21: return "s21"; + case dwarf_s22: return "s22"; + case dwarf_s23: return "s23"; + case dwarf_s24: return "s24"; + case dwarf_s25: return "s25"; + case dwarf_s26: return "s26"; + case dwarf_s27: return "s27"; + case dwarf_s28: return "s28"; + case dwarf_s29: return "s29"; + case dwarf_s30: return "s30"; + case dwarf_s31: return "s31"; + + // FPA Registers 0-7 + case dwarf_f0: return "f0"; + case dwarf_f1: return "f1"; + case dwarf_f2: return "f2"; + case dwarf_f3: return "f3"; + case dwarf_f4: return "f4"; + case dwarf_f5: return "f5"; + case dwarf_f6: return "f6"; + case dwarf_f7: return "f7"; + + // Intel wireless MMX general purpose registers 0–7 + // XScale accumulator register 0–7 (they do overlap with wCGR0 - wCGR7) + case dwarf_wCGR0: return "wCGR0/ACC0"; + case dwarf_wCGR1: return "wCGR1/ACC1"; + case dwarf_wCGR2: return "wCGR2/ACC2"; + case dwarf_wCGR3: return "wCGR3/ACC3"; + case dwarf_wCGR4: return "wCGR4/ACC4"; + case dwarf_wCGR5: return "wCGR5/ACC5"; + case dwarf_wCGR6: return "wCGR6/ACC6"; + case dwarf_wCGR7: return "wCGR7/ACC7"; + + // Intel wireless MMX data registers 0–15 + case dwarf_wR0: return "wR0"; + case dwarf_wR1: return "wR1"; + case dwarf_wR2: return "wR2"; + case dwarf_wR3: return "wR3"; + case dwarf_wR4: return "wR4"; + case dwarf_wR5: return "wR5"; + case dwarf_wR6: return "wR6"; + case dwarf_wR7: return "wR7"; + case dwarf_wR8: return "wR8"; + case dwarf_wR9: return "wR9"; + case dwarf_wR10: return "wR10"; + case dwarf_wR11: return "wR11"; + case dwarf_wR12: return "wR12"; + case dwarf_wR13: return "wR13"; + case dwarf_wR14: return "wR14"; + case dwarf_wR15: return "wR15"; + + case dwarf_spsr: return "spsr"; + case dwarf_spsr_fiq: return "spsr_fiq"; + case dwarf_spsr_irq: return "spsr_irq"; + case dwarf_spsr_abt: return "spsr_abt"; + case dwarf_spsr_und: return "spsr_und"; + case dwarf_spsr_svc: return "spsr_svc"; + + case dwarf_r8_usr: return "r8_usr"; + case dwarf_r9_usr: return "r9_usr"; + case dwarf_r10_usr: return "r10_usr"; + case dwarf_r11_usr: return "r11_usr"; + case dwarf_r12_usr: return "r12_usr"; + case dwarf_r13_usr: return "r13_usr"; + case dwarf_r14_usr: return "r14_usr"; + case dwarf_r8_fiq: return "r8_fiq"; + case dwarf_r9_fiq: return "r9_fiq"; + case dwarf_r10_fiq: return "r10_fiq"; + case dwarf_r11_fiq: return "r11_fiq"; + case dwarf_r12_fiq: return "r12_fiq"; + case dwarf_r13_fiq: return "r13_fiq"; + case dwarf_r14_fiq: return "r14_fiq"; + case dwarf_r13_irq: return "r13_irq"; + case dwarf_r14_irq: return "r14_irq"; + case dwarf_r13_abt: return "r13_abt"; + case dwarf_r14_abt: return "r14_abt"; + case dwarf_r13_und: return "r13_und"; + case dwarf_r14_und: return "r14_und"; + case dwarf_r13_svc: return "r13_svc"; + case dwarf_r14_svc: return "r14_svc"; + + // Intel wireless MMX control register in co-processor 0–7 + case dwarf_wC0: return "wC0"; + case dwarf_wC1: return "wC1"; + case dwarf_wC2: return "wC2"; + case dwarf_wC3: return "wC3"; + case dwarf_wC4: return "wC4"; + case dwarf_wC5: return "wC5"; + case dwarf_wC6: return "wC6"; + case dwarf_wC7: return "wC7"; + + // VFP-v3/Neon + case dwarf_d0: return "d0"; + case dwarf_d1: return "d1"; + case dwarf_d2: return "d2"; + case dwarf_d3: return "d3"; + case dwarf_d4: return "d4"; + case dwarf_d5: return "d5"; + case dwarf_d6: return "d6"; + case dwarf_d7: return "d7"; + case dwarf_d8: return "d8"; + case dwarf_d9: return "d9"; + case dwarf_d10: return "d10"; + case dwarf_d11: return "d11"; + case dwarf_d12: return "d12"; + case dwarf_d13: return "d13"; + case dwarf_d14: return "d14"; + case dwarf_d15: return "d15"; + case dwarf_d16: return "d16"; + case dwarf_d17: return "d17"; + case dwarf_d18: return "d18"; + case dwarf_d19: return "d19"; + case dwarf_d20: return "d20"; + case dwarf_d21: return "d21"; + case dwarf_d22: return "d22"; + case dwarf_d23: return "d23"; + case dwarf_d24: return "d24"; + case dwarf_d25: return "d25"; + case dwarf_d26: return "d26"; + case dwarf_d27: return "d27"; + case dwarf_d28: return "d28"; + case dwarf_d29: return "d29"; + case dwarf_d30: return "d30"; + case dwarf_d31: return "d31"; + } + return 0; +} + diff --git a/lldb/source/Utility/ARM_DWARF_Registers.h b/lldb/source/Utility/ARM_DWARF_Registers.h index c94579d1648..9c1cb910c32 100644 --- a/lldb/source/Utility/ARM_DWARF_Registers.h +++ b/lldb/source/Utility/ARM_DWARF_Registers.h @@ -186,5 +186,16 @@ enum dwarf_d31 }; +#if defined(__cplusplus) +extern "C" { +#endif + +const char * +GetARMDWARFRegisterName (unsigned reg_num); + +#if defined(__cplusplus) +} +#endif + #endif // utility_ARM_DWARF_Registers_h_ diff --git a/lldb/source/lldb.cpp b/lldb/source/lldb.cpp index 914031c438f..0c730eed47a 100644 --- a/lldb/source/lldb.cpp +++ b/lldb/source/lldb.cpp @@ -83,8 +83,8 @@ lldb_private::Initialize () ObjectFileELF::Initialize(); SymbolFileDWARF::Initialize(); SymbolFileSymtab::Initialize(); - UnwindAssembly_x86::Initialize(); UnwindAssemblyInstEmulation::Initialize(); + UnwindAssembly_x86::Initialize(); ArchDefaultUnwindPlan_x86_64::Initialize(); ArchDefaultUnwindPlan_i386::Initialize(); ArchVolatileRegs_x86::Initialize(); |