diff options
27 files changed, 774 insertions, 79 deletions
diff --git a/lldb/include/lldb/API/SBAddress.h b/lldb/include/lldb/API/SBAddress.h index a7be8e2ddd3..f5cd7c6c1a5 100644 --- a/lldb/include/lldb/API/SBAddress.h +++ b/lldb/include/lldb/API/SBAddress.h @@ -97,6 +97,7 @@ public: protected: + friend class SBBlock; friend class SBBreakpointLocation; friend class SBFrame; friend class SBFunction; diff --git a/lldb/include/lldb/API/SBBlock.h b/lldb/include/lldb/API/SBBlock.h index 8284aa5097a..ec1e0b5ba8a 100644 --- a/lldb/include/lldb/API/SBBlock.h +++ b/lldb/include/lldb/API/SBBlock.h @@ -56,6 +56,31 @@ public: lldb::SBBlock GetFirstChild (); + uint32_t + GetNumRanges (); + + lldb::SBAddress + GetRangeStartAddress (uint32_t idx); + + lldb::SBAddress + GetRangeEndAddress (uint32_t idx); + + uint32_t + GetRangeIndexForBlockAddress (lldb::SBAddress block_addr); + + //------------------------------------------------------------------ + /// Get the inlined block that contains this block. + /// + /// @return + /// If this block is inlined, it will return this block, else + /// parent blocks will be searched to see if any contain this + /// block and are themselves inlined. An invalid SBBlock will + /// be returned if this block nor any parent blocks are inlined + /// function blocks. + //------------------------------------------------------------------ + lldb::SBBlock + GetContainingInlinedBlock (); + bool GetDescription (lldb::SBStream &description); @@ -66,8 +91,8 @@ private: #ifndef SWIG - const lldb_private::Block * - get () const; + lldb_private::Block * + get (); void reset (lldb_private::Block *lldb_object_ptr); diff --git a/lldb/include/lldb/API/SBCompileUnit.h b/lldb/include/lldb/API/SBCompileUnit.h index 1312458b1cf..bf56436ed51 100644 --- a/lldb/include/lldb/API/SBCompileUnit.h +++ b/lldb/include/lldb/API/SBCompileUnit.h @@ -81,9 +81,9 @@ private: const lldb_private::CompileUnit & operator*() const; - const lldb_private::CompileUnit * - get () const; - + lldb_private::CompileUnit * + get (); + void reset (lldb_private::CompileUnit *lldb_object_ptr); diff --git a/lldb/include/lldb/API/SBData.h b/lldb/include/lldb/API/SBData.h index 47d779fb01c..cd611ac2601 100644 --- a/lldb/include/lldb/API/SBData.h +++ b/lldb/include/lldb/API/SBData.h @@ -125,8 +125,9 @@ protected: SetOpaque (const lldb::DataExtractorSP &data_sp); private: - friend class SBValue; + friend class SBInstruction; friend class SBSection; + friend class SBValue; lldb::DataExtractorSP m_opaque_sp; }; diff --git a/lldb/include/lldb/API/SBInstruction.h b/lldb/include/lldb/API/SBInstruction.h index 79ffd8e27e2..2893ea667a3 100644 --- a/lldb/include/lldb/API/SBInstruction.h +++ b/lldb/include/lldb/API/SBInstruction.h @@ -11,6 +11,7 @@ #define LLDB_SBInstruction_h_ #include "lldb/API/SBDefines.h" +#include "lldb/API/SBData.h" #include <stdio.h> @@ -39,6 +40,18 @@ public: SBAddress GetAddress(); + + const char * + GetOpcodeName (lldb::SBTarget target); + + const char * + GetMnemonics (lldb::SBTarget target); + + const char * + GetComment (lldb::SBTarget target); + + lldb::SBData + GetData (lldb::SBTarget target); size_t GetByteSize (); diff --git a/lldb/include/lldb/API/SBLineEntry.h b/lldb/include/lldb/API/SBLineEntry.h index 9ef65f6eca6..35b31c6981d 100644 --- a/lldb/include/lldb/API/SBLineEntry.h +++ b/lldb/include/lldb/API/SBLineEntry.h @@ -49,6 +49,15 @@ public: uint32_t GetColumn () const; + void + SetFileSpec (lldb::SBFileSpec filespec); + + void + SetLine (uint32_t line); + + void + SetColumn (uint32_t column); + #ifndef SWIG bool operator == (const lldb::SBLineEntry &rhs) const; @@ -77,8 +86,11 @@ private: const lldb_private::LineEntry * operator->() const; + lldb_private::LineEntry & + ref(); + const lldb_private::LineEntry & - operator*() const; + ref() const; #endif diff --git a/lldb/include/lldb/API/SBSymbolContext.h b/lldb/include/lldb/API/SBSymbolContext.h index e04e91b49e1..b93db5dc648 100644 --- a/lldb/include/lldb/API/SBSymbolContext.h +++ b/lldb/include/lldb/API/SBSymbolContext.h @@ -37,12 +37,24 @@ public: operator = (const lldb::SBSymbolContext &rhs); #endif - SBModule GetModule (); - SBCompileUnit GetCompileUnit (); - SBFunction GetFunction (); - SBBlock GetBlock (); - SBLineEntry GetLineEntry (); - SBSymbol GetSymbol (); + lldb::SBModule GetModule (); + lldb::SBCompileUnit GetCompileUnit (); + lldb::SBFunction GetFunction (); + lldb::SBBlock GetBlock (); + lldb::SBLineEntry GetLineEntry (); + lldb::SBSymbol GetSymbol (); + + void SetModule (lldb::SBModule module); + void SetCompileUnit (lldb::SBCompileUnit compile_unit); + void SetFunction (lldb::SBFunction function); + void SetBlock (lldb::SBBlock block); + void SetLineEntry (lldb::SBLineEntry line_entry); + void SetSymbol (lldb::SBSymbol symbol); + + SBSymbolContext + GetParentInlinedFrameInfo (const SBAddress &curr_frame_pc, + bool is_concrete_frame, + SBAddress &parent_frame_addr) const; bool GetDescription (lldb::SBStream &description); diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h index b12185c83d5..49760d03ad1 100644 --- a/lldb/include/lldb/API/SBTarget.h +++ b/lldb/include/lldb/API/SBTarget.h @@ -476,6 +476,7 @@ protected: friend class SBAddress; friend class SBDebugger; friend class SBFunction; + friend class SBInstruction; friend class SBProcess; friend class SBSymbol; friend class SBModule; diff --git a/lldb/include/lldb/Core/Disassembler.h b/lldb/include/lldb/Core/Disassembler.h index f77f73f717d..fb031d0e7dc 100644 --- a/lldb/include/lldb/Core/Disassembler.h +++ b/lldb/include/lldb/Core/Disassembler.h @@ -40,6 +40,38 @@ public: { return m_address; } + + const char * + GetOpcodeName (ExecutionContextScope *exe_scope) + { + if (m_opcode_name.empty()) + CalculateOpcodeName(exe_scope); + return m_opcode_name.c_str(); + } + const char * + GetMnemonics (ExecutionContextScope *exe_scope) + { + if (m_mnemocics.empty()) + CalculateMnemonics(exe_scope); + return m_mnemocics.c_str(); + } + + const char * + GetComment (ExecutionContextScope *exe_scope) + { + if (m_comment.empty()) + CalculateComment(exe_scope); + return m_comment.c_str(); + } + + virtual void + CalculateOpcodeName (ExecutionContextScope *exe_scope) = 0; + + virtual void + CalculateMnemonics (ExecutionContextScope *exe_scope) = 0; + + virtual void + CalculateComment (ExecutionContextScope *exe_scope) = 0; AddressClass GetAddressClass (); @@ -109,6 +141,10 @@ protected: // help us to disassemble appropriately. AddressClass m_address_class; Opcode m_opcode; // The opcode for this instruction + std::string m_opcode_name; + std::string m_mnemocics; + std::string m_comment; + }; @@ -161,7 +197,25 @@ public: virtual bool DoesBranch () const; + + virtual void + CalculateOpcodeName(ExecutionContextScope *exe_scope) + { + // TODO: fill this in and put opcode name into Instruction::m_opcode_name + } + virtual void + CalculateMnemonics(ExecutionContextScope *exe_scope) + { + // TODO: fill this in and put opcode name into Instruction::m_mnemonics + } + + virtual void + CalculateComment(ExecutionContextScope *exe_scope) + { + // TODO: fill this in and put opcode name into Instruction::m_comment + } + virtual size_t Decode (const lldb_private::Disassembler &disassembler, const lldb_private::DataExtractor &data, diff --git a/lldb/include/lldb/Core/Opcode.h b/lldb/include/lldb/Core/Opcode.h index dd91c33f5ef..69762a276ae 100644 --- a/lldb/include/lldb/Core/Opcode.h +++ b/lldb/include/lldb/Core/Opcode.h @@ -18,6 +18,11 @@ // Project includes #include "lldb/lldb-public.h" +namespace lldb +{ + class SBInstruction; +} + namespace lldb_private { class Opcode @@ -203,6 +208,26 @@ namespace lldb_private { protected: + friend class lldb::SBInstruction; + + const void * + GetOpcodeDataBytes () const + { + switch (m_type) + { + case Opcode::eTypeInvalid: break; + case Opcode::eType8: return &m_data.inst8; + case Opcode::eType16: return &m_data.inst16; + case Opcode::eType32: return &m_data.inst32; + case Opcode::eType64: return &m_data.inst64; + case Opcode::eTypeBytes: return m_data.inst.bytes; + } + return NULL; + } + + lldb::ByteOrder + GetDataByteOrder () const; + Opcode::Type m_type; union { diff --git a/lldb/include/lldb/Symbol/Block.h b/lldb/include/lldb/Symbol/Block.h index 204d09ff641..c5f7911ec62 100644 --- a/lldb/include/lldb/Symbol/Block.h +++ b/lldb/include/lldb/Symbol/Block.h @@ -434,11 +434,17 @@ public: Block * FindBlockByID (lldb::user_id_t block_id); + uint32_t + GetNumRanges () const + { + return m_ranges.size(); + } + bool GetRangeContainingOffset (const lldb::addr_t offset, VMRange &range); bool - GetRangeContainingAddress (const Address& addr, AddressRange &range); + GetRangeContainingAddress (const Address& addr, AddressRange &range, uint32_t *range_idx_ptr = NULL); //------------------------------------------------------------------ // Since blocks might have multiple discontiguous addresss ranges, diff --git a/lldb/include/lldb/Symbol/SymbolContext.h b/lldb/include/lldb/Symbol/SymbolContext.h index 8f6eb23352d..0175b9150cc 100644 --- a/lldb/include/lldb/Symbol/SymbolContext.h +++ b/lldb/include/lldb/Symbol/SymbolContext.h @@ -266,6 +266,12 @@ public: // const char *line_number, // const char *symbol); + bool + GetParentInlinedFrameInfo (const Address &curr_frame_pc, + bool is_concrete_frame, + SymbolContext &next_frame_sc, + Address &inlined_frame_addr) const; + //------------------------------------------------------------------ // Member variables //------------------------------------------------------------------ diff --git a/lldb/scripts/Python/interface/SBBlock.i b/lldb/scripts/Python/interface/SBBlock.i index ec11fc1f00c..83895edcc06 100644 --- a/lldb/scripts/Python/interface/SBBlock.i +++ b/lldb/scripts/Python/interface/SBBlock.i @@ -63,6 +63,10 @@ public: lldb::SBBlock GetParent (); + %feature("docstring", "Get the inlined block that is or contains this block.") GetContainingInlinedBlock; + lldb::SBBlock + GetContainingInlinedBlock (); + %feature("docstring", "Get the sibling block for this block.") GetSibling; lldb::SBBlock GetSibling (); @@ -70,6 +74,18 @@ public: %feature("docstring", "Get the first child block.") GetFirstChild; lldb::SBBlock GetFirstChild (); + + uint32_t + GetNumRanges (); + + lldb::SBAddress + GetRangeStartAddress (uint32_t idx); + + lldb::SBAddress + GetRangeEndAddress (uint32_t idx); + + uint32_t + GetRangeIndexForBlockAddress (lldb::SBAddress block_addr); bool GetDescription (lldb::SBStream &description); diff --git a/lldb/scripts/Python/interface/SBInstruction.i b/lldb/scripts/Python/interface/SBInstruction.i index 1a9fc205258..cf82ad9e4d6 100644 --- a/lldb/scripts/Python/interface/SBInstruction.i +++ b/lldb/scripts/Python/interface/SBInstruction.i @@ -30,6 +30,18 @@ public: SBAddress GetAddress(); + const char * + GetOpcodeName (lldb::SBTarget target); + + const char * + GetMnemonics (lldb::SBTarget target); + + const char * + GetComment (lldb::SBTarget target); + + lldb::SBData + GetData (lldb::SBTarget target); + size_t GetByteSize (); diff --git a/lldb/scripts/Python/interface/SBLineEntry.i b/lldb/scripts/Python/interface/SBLineEntry.i index 4e2968d0b39..e1631e91d48 100644 --- a/lldb/scripts/Python/interface/SBLineEntry.i +++ b/lldb/scripts/Python/interface/SBLineEntry.i @@ -67,6 +67,16 @@ public: bool GetDescription (lldb::SBStream &description); + + void + SetFileSpec (lldb::SBFileSpec filespec); + + void + SetLine (uint32_t line); + + void + SetColumn (uint32_t column); + }; } // namespace lldb diff --git a/lldb/scripts/Python/interface/SBSymbolContext.i b/lldb/scripts/Python/interface/SBSymbolContext.i index c8ef8eb60ab..00d80da9892 100644 --- a/lldb/scripts/Python/interface/SBSymbolContext.i +++ b/lldb/scripts/Python/interface/SBSymbolContext.i @@ -58,12 +58,25 @@ public: bool IsValid () const; - SBModule GetModule (); - SBCompileUnit GetCompileUnit (); - SBFunction GetFunction (); - SBBlock GetBlock (); - SBLineEntry GetLineEntry (); - SBSymbol GetSymbol (); + lldb::SBModule GetModule (); + lldb::SBCompileUnit GetCompileUnit (); + lldb::SBFunction GetFunction (); + lldb::SBBlock GetBlock (); + lldb::SBLineEntry GetLineEntry (); + lldb::SBSymbol GetSymbol (); + + void SetModule (lldb::SBModule module); + void SetCompileUnit (lldb::SBCompileUnit compile_unit); + void SetFunction (lldb::SBFunction function); + void SetBlock (lldb::SBBlock block); + void SetLineEntry (lldb::SBLineEntry line_entry); + void SetSymbol (lldb::SBSymbol symbol); + + lldb::SBSymbolContext + GetParentInlinedFrameInfo (const lldb::SBAddress &curr_frame_pc, + bool is_concrete_frame, + lldb::SBAddress &parent_frame_addr) const; + bool GetDescription (lldb::SBStream &description); diff --git a/lldb/source/API/SBBlock.cpp b/lldb/source/API/SBBlock.cpp index 860f9b9f74f..bc7392c11f9 100644 --- a/lldb/source/API/SBBlock.cpp +++ b/lldb/source/API/SBBlock.cpp @@ -8,8 +8,10 @@ //===----------------------------------------------------------------------===// #include "lldb/API/SBBlock.h" +#include "lldb/API/SBAddress.h" #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBStream.h" +#include "lldb/Core/AddressRange.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/SymbolContext.h" @@ -127,6 +129,15 @@ SBBlock::GetParent () return sb_block; } +lldb::SBBlock +SBBlock::GetContainingInlinedBlock () +{ + SBBlock sb_block; + if (m_opaque_ptr) + sb_block.m_opaque_ptr = m_opaque_ptr->GetContainingInlinedBlock (); + return sb_block; +} + SBBlock SBBlock::GetSibling () { @@ -145,8 +156,8 @@ SBBlock::GetFirstChild () return sb_block; } -const lldb_private::Block * -SBBlock::get () const +lldb_private::Block * +SBBlock::get () { return m_opaque_ptr; } @@ -181,3 +192,59 @@ SBBlock::GetDescription (SBStream &description) return true; } + +uint32_t +SBBlock::GetNumRanges () +{ + if (m_opaque_ptr) + return m_opaque_ptr->GetNumRanges(); + return 0; +} + +lldb::SBAddress +SBBlock::GetRangeStartAddress (uint32_t idx) +{ + lldb::SBAddress sb_addr; + if (m_opaque_ptr) + { + AddressRange range; + if (m_opaque_ptr->GetRangeAtIndex(idx, range)) + { + sb_addr.ref() = range.GetBaseAddress(); + } + } + return sb_addr; +} + +lldb::SBAddress +SBBlock::GetRangeEndAddress (uint32_t idx) +{ + lldb::SBAddress sb_addr; + if (m_opaque_ptr) + { + AddressRange range; + if (m_opaque_ptr->GetRangeAtIndex(idx, range)) + { + sb_addr.ref() = range.GetBaseAddress(); + sb_addr.ref().Slide(range.GetByteSize()); + } + } + return sb_addr; +} + +uint32_t +SBBlock::GetRangeIndexForBlockAddress (lldb::SBAddress block_addr) +{ + if (m_opaque_ptr && block_addr.IsValid()) + { + uint32_t range_idx = UINT32_MAX; + AddressRange range; + if (m_opaque_ptr->GetRangeContainingAddress (block_addr.ref(), range, &range_idx)) + { + return range_idx; + } + } + + return UINT32_MAX; +} + diff --git a/lldb/source/API/SBCompileUnit.cpp b/lldb/source/API/SBCompileUnit.cpp index 58723e5a394..15903627016 100644 --- a/lldb/source/API/SBCompileUnit.cpp +++ b/lldb/source/API/SBCompileUnit.cpp @@ -173,8 +173,8 @@ SBCompileUnit::operator*() const return *m_opaque_ptr; } -const lldb_private::CompileUnit * -SBCompileUnit::get () const +lldb_private::CompileUnit * +SBCompileUnit::get () { return m_opaque_ptr; } diff --git a/lldb/source/API/SBInstruction.cpp b/lldb/source/API/SBInstruction.cpp index 0be59af2f98..d708aa035d9 100644 --- a/lldb/source/API/SBInstruction.cpp +++ b/lldb/source/API/SBInstruction.cpp @@ -16,6 +16,7 @@ #include "lldb/API/SBTarget.h" #include "lldb/Core/ArchSpec.h" +#include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/Disassembler.h" #include "lldb/Core/EmulateInstruction.h" #include "lldb/Core/StreamFile.h" @@ -67,6 +68,60 @@ SBInstruction::GetAddress() return sb_addr; } +const char * +SBInstruction::GetOpcodeName(SBTarget target) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker; + ExecutionContext exe_ctx; + if (target.IsValid()) + { + api_locker.Reset (target->GetAPIMutex().GetMutex()); + target->CalculateExecutionContext (exe_ctx); + exe_ctx.SetProcessSP(target->GetProcessSP()); + } + return m_opaque_sp->GetOpcodeName(exe_ctx.GetBestExecutionContextScope()); + } + return NULL; +} + +const char * +SBInstruction::GetMnemonics(SBTarget target) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker; + ExecutionContext exe_ctx; + if (target.IsValid()) + { + api_locker.Reset (target->GetAPIMutex().GetMutex()); + target->CalculateExecutionContext (exe_ctx); + exe_ctx.SetProcessSP(target->GetProcessSP()); + } + return m_opaque_sp->GetMnemonics(exe_ctx.GetBestExecutionContextScope()); + } + return NULL; +} + +const char * +SBInstruction::GetComment(SBTarget target) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker; + ExecutionContext exe_ctx; + if (target.IsValid()) + { + api_locker.Reset (target->GetAPIMutex().GetMutex()); + target->CalculateExecutionContext (exe_ctx); + exe_ctx.SetProcessSP(target->GetProcessSP()); + } + return m_opaque_sp->GetComment(exe_ctx.GetBestExecutionContextScope()); + } + return NULL; +} + size_t SBInstruction::GetByteSize () { @@ -75,6 +130,32 @@ SBInstruction::GetByteSize () return 0; } +SBData +SBInstruction::GetData (SBTarget target) +{ + lldb::SBData sb_data; + if (m_opaque_sp) + { + const Opcode &opcode = m_opaque_sp->GetOpcode(); + const void *opcode_data = opcode.GetOpcodeBytes(); + const uint32_t opcode_data_size = opcode.GetByteSize(); + if (opcode_data && opcode_data_size > 0) + { + ByteOrder data_byte_order = opcode.GetDataByteOrder(); + if (data_byte_order == eByteOrderInvalid) + data_byte_order = target->GetArchitecture().GetByteOrder(); + DataBufferSP data_buffer_sp (new DataBufferHeap (opcode_data, opcode_data_size)); + DataExtractorSP data_extractor_sp (new DataExtractor (data_buffer_sp, + data_byte_order, + target.IsValid() ? target->GetArchitecture().GetAddressByteSize() : sizeof(void*))); + sb_data.SetOpaque (data_extractor_sp); + } + } + return sb_data; +} + + + bool SBInstruction::DoesBranch () { diff --git a/lldb/source/API/SBLineEntry.cpp b/lldb/source/API/SBLineEntry.cpp index 3567a3839c5..6915f58b24d 100644 --- a/lldb/source/API/SBLineEntry.cpp +++ b/lldb/source/API/SBLineEntry.cpp @@ -28,33 +28,33 @@ SBLineEntry::SBLineEntry (const SBLineEntry &rhs) : m_opaque_ap () { if (rhs.IsValid()) - m_opaque_ap.reset (new lldb_private::LineEntry (*rhs)); + ref() = rhs.ref(); } - - SBLineEntry::SBLineEntry (const lldb_private::LineEntry *lldb_object_ptr) : m_opaque_ap () { if (lldb_object_ptr) - m_opaque_ap.reset (new lldb_private::LineEntry(*lldb_object_ptr)); + ref() = *lldb_object_ptr; } const SBLineEntry & SBLineEntry::operator = (const SBLineEntry &rhs) { - if (this != &rhs && rhs.IsValid()) - m_opaque_ap.reset (new lldb_private::LineEntry(*rhs)); + if (this != &rhs) + { + if (rhs.IsValid()) + ref() = rhs.ref(); + else + m_opaque_ap.reset(); + } return *this; } void SBLineEntry::SetLineEntry (const lldb_private::LineEntry &lldb_object_ref) { - if (m_opaque_ap.get()) - (*m_opaque_ap.get()) = lldb_object_ref; - else - m_opaque_ap.reset (new lldb_private::LineEntry (lldb_object_ref)); + ref() = lldb_object_ref; } @@ -156,6 +156,28 @@ SBLineEntry::GetColumn () const return 0; } +void +SBLineEntry::SetFileSpec (lldb::SBFileSpec filespec) +{ + if (filespec.IsValid()) + ref().file = filespec.ref(); + else + ref().file.Clear(); +} +void +SBLineEntry::SetLine (uint32_t line) +{ + ref().line = line; +} + +void +SBLineEntry::SetColumn (uint32_t column) +{ + ref().line = column; +} + + + bool SBLineEntry::operator == (const SBLineEntry &rhs) const { @@ -186,8 +208,16 @@ SBLineEntry::operator->() const return m_opaque_ap.get(); } +lldb_private::LineEntry & +SBLineEntry::ref() +{ + if (m_opaque_ap.get() == NULL) + m_opaque_ap.reset (new lldb_private::LineEntry ()); + return *m_opaque_ap; +} + const lldb_private::LineEntry & -SBLineEntry::operator*() const +SBLineEntry::ref() const { return *m_opaque_ap; } diff --git a/lldb/source/API/SBSymbolContext.cpp b/lldb/source/API/SBSymbolContext.cpp index 76c607f7078..c2b70fb5166 100644 --- a/lldb/source/API/SBSymbolContext.cpp +++ b/lldb/source/API/SBSymbolContext.cpp @@ -10,6 +10,7 @@ #include "lldb/API/SBSymbolContext.h" #include "lldb/API/SBStream.h" #include "lldb/Core/Log.h" +#include "lldb/Core/Module.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/SymbolContext.h" @@ -173,6 +174,46 @@ SBSymbolContext::GetSymbol () return sb_symbol; } +void +SBSymbolContext::SetModule (lldb::SBModule module) +{ + ref().module_sp = module.get_sp(); +} + +void +SBSymbolContext::SetCompileUnit (lldb::SBCompileUnit compile_unit) +{ + ref().comp_unit = compile_unit.get(); +} + +void +SBSymbolContext::SetFunction (lldb::SBFunction function) +{ + ref().function = function.get(); +} + +void +SBSymbolContext::SetBlock (lldb::SBBlock block) +{ + ref().block = block.get(); +} + +void +SBSymbolContext::SetLineEntry (lldb::SBLineEntry line_entry) +{ + if (line_entry.IsValid()) + ref().line_entry = line_entry.ref(); + else + ref().line_entry.Clear(); +} + +void +SBSymbolContext::SetSymbol (lldb::SBSymbol symbol) +{ + ref().symbol = symbol.get(); +} + + lldb_private::SymbolContext* SBSymbolContext::operator->() const { @@ -223,3 +264,18 @@ SBSymbolContext::GetDescription (SBStream &description) return true; } + +SBSymbolContext +SBSymbolContext::GetParentInlinedFrameInfo (const SBAddress &curr_frame_pc, + bool is_concrete_frame, + SBAddress &parent_frame_addr) const +{ + SBSymbolContext sb_sc; + if (m_opaque_ap.get() && curr_frame_pc.IsValid()) + { + if (m_opaque_ap->GetParentInlinedFrameInfo (curr_frame_pc.ref(), is_concrete_frame, sb_sc.ref(), parent_frame_addr.ref())) + return sb_sc; + } + return SBSymbolContext(); +} + diff --git a/lldb/source/Core/Opcode.cpp b/lldb/source/Core/Opcode.cpp index b765bf7dd1d..489a61a353a 100644 --- a/lldb/source/Core/Opcode.cpp +++ b/lldb/source/Core/Opcode.cpp @@ -14,6 +14,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/Stream.h" +#include "lldb/Host/Endian.h" using namespace lldb; using namespace lldb_private; @@ -62,3 +63,19 @@ Opcode::Dump (Stream *s, uint32_t min_byte_width) return bytes_written; } +lldb::ByteOrder +Opcode::GetDataByteOrder () const +{ + switch (m_type) + { + case Opcode::eTypeInvalid: break; + case Opcode::eType8: + case Opcode::eType16: + case Opcode::eType32: + case Opcode::eType64: return lldb::endian::InlHostByteOrder(); + case Opcode::eTypeBytes: + break; + } + return eByteOrderInvalid; +} + diff --git a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp index a8c423f44e6..610271deb98 100644 --- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp +++ b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp @@ -99,13 +99,15 @@ PadString(Stream *s, const std::string &str, size_t width) s->Printf("%s ", str.c_str()); } static void -AddSymbolicInfo(const ExecutionContext *exe_ctx, ExecutionContextScope *exe_scope, - StreamString &comment, uint64_t operand_value, const Address &inst_addr) +AddSymbolicInfo (ExecutionContextScope *exe_scope, + StreamString &comment, + uint64_t operand_value, + const Address &inst_addr) { Address so_addr; Target *target = NULL; - if (exe_ctx) - target = exe_ctx->GetTargetPtr(); + if (exe_scope) + target = exe_scope->CalculateTarget(); if (target && !target->GetSectionLoadList().IsEmpty()) { if (target->GetSectionLoadList().ResolveLoadAddress(operand_value, so_addr)) @@ -225,12 +227,16 @@ InstructionLLVM::Dump if (numTokens != -1 && !raw) { addr_t base_addr = LLDB_INVALID_ADDRESS; - + uint32_t addr_nibble_size = 8; Target *target = NULL; if (exe_ctx) target = exe_ctx->GetTargetPtr(); - if (target && !target->GetSectionLoadList().IsEmpty()) - base_addr = GetAddress().GetLoadAddress (target); + if (target) + { + if (!target->GetSectionLoadList().IsEmpty()) + base_addr = GetAddress().GetLoadAddress (target); + addr_nibble_size = target->GetArchitecture().GetAddressByteSize() * 2; + } if (base_addr == LLDB_INVALID_ADDRESS) base_addr = GetAddress().GetFileAddress (); @@ -314,16 +320,16 @@ InstructionLLVM::Dump { if (EDInstIsBranch(m_inst)) { - operands.Printf("0x%llx ", operand_value); + operands.Printf("0x%*.*llx ", addr_nibble_size, addr_nibble_size, operand_value); show_token = false; } else { // Put the address value into the comment - comment.Printf("0x%llx ", operand_value); + comment.Printf("0x%*.*llx ", addr_nibble_size, addr_nibble_size, operand_value); } - AddSymbolicInfo(exe_ctx, exe_scope, comment, operand_value, GetAddress()); + AddSymbolicInfo(exe_scope, comment, operand_value, GetAddress()); } // EDEvaluateOperand } // EDOperandIsMemory } // EDGetOperand @@ -351,8 +357,8 @@ InstructionLLVM::Dump if (EDGetInstString(&inst_str, m_inst) == 0 && (pos = strstr(inst_str, "#")) != NULL) { uint64_t operand_value = PC + atoi(++pos); // Put the address value into the operands. - operands.Printf("0x%llx ", operand_value); - AddSymbolicInfo(exe_ctx, exe_scope, comment, operand_value, GetAddress()); + operands.Printf("0x%8.8llx ", operand_value); + AddSymbolicInfo(exe_scope, comment, operand_value, GetAddress()); } } // Yet more workaround for "bl #..." and "blx #...". @@ -369,12 +375,12 @@ InstructionLLVM::Dump } uint64_t operand_value = PC + atoi(++pos); // Put the address value into the comment. - comment.Printf("0x%llx ", operand_value); + comment.Printf("0x%8.8llx ", operand_value); // And the original token string into the operands. llvm::StringRef Str(pos - 1); RStrip(Str, '\n'); operands.PutCString(Str.str().c_str()); - AddSymbolicInfo(exe_ctx, exe_scope, comment, operand_value, GetAddress()); + AddSymbolicInfo(exe_scope, comment, operand_value, GetAddress()); } } // END of workaround. @@ -423,6 +429,144 @@ InstructionLLVM::Dump } } +void +InstructionLLVM::CalculateOpcodeName (ExecutionContextScope *exe_scope) +{ + const int num_tokens = EDNumTokens(m_inst); + if (num_tokens > 0) + { + const char *token_cstr = NULL; + int currentOpIndex = -1; + StreamString comment; + uint32_t addr_nibble_size = 8; + addr_t base_addr = LLDB_INVALID_ADDRESS; + Target *target = NULL; + if (exe_scope) + target = exe_scope->CalculateTarget(); + if (target && !target->GetSectionLoadList().IsEmpty()) + base_addr = GetAddress().GetLoadAddress (target); + if (base_addr == LLDB_INVALID_ADDRESS) + base_addr = GetAddress().GetFileAddress (); + addr_nibble_size = target->GetArchitecture().GetAddressByteSize() * 2; + + lldb::addr_t PC = base_addr + EDInstByteSize(m_inst); + + // When executing an ARM instruction, PC reads as the address of the + // current instruction plus 8. And for Thumb, it is plus 4. + if (m_arch_type == llvm::Triple::arm) + PC = base_addr + 8; + else if (m_arch_type == llvm::Triple::thumb) + PC = base_addr + 4; + + RegisterReaderArg rra(PC, m_disassembler); + + for (int token_idx = 0; token_idx < num_tokens; ++token_idx) + { + EDTokenRef token; + if (EDGetToken(&token, m_inst, token_idx)) + break; + + if (EDTokenIsOpcode(token) == 1) + { + if (EDGetTokenString(&token_cstr, token) == 0) // 0 on success + { + if (token_cstr) + m_opcode_name.assign(token_cstr); + } + } + else + { + int operandIndex = EDOperandIndexForToken(token); + + if (operandIndex >= 0) + { + if (operandIndex != currentOpIndex) + { + currentOpIndex = operandIndex; + EDOperandRef operand; + + if (!EDGetOperand(&operand, m_inst, currentOpIndex)) + { + if (EDOperandIsMemory(operand)) + { + uint64_t operand_value; + + if (!EDEvaluateOperand(&operand_value, operand, IPRegisterReader, &rra)) + { + comment.Printf("0x%*.*llx ", addr_nibble_size, addr_nibble_size, operand_value); + AddSymbolicInfo (exe_scope, comment, operand_value, GetAddress()); + } + } + } + } + } + if (m_mnemocics.empty() && EDTokenIsWhitespace (token) == 1) + continue; + if (EDGetTokenString (&token_cstr, token)) + break; + m_mnemocics.append (token_cstr); + } + } + // FIXME!!! + // Workaround for llvm::tB's operands not properly parsed by ARMAsmParser. + if (m_arch_type == llvm::Triple::thumb && m_opcode_name.compare("b") == 0) + { + const char *inst_str; + const char *pos = NULL; + comment.Clear(); + if (EDGetInstString(&inst_str, m_inst) == 0 && (pos = strstr(inst_str, "#")) != NULL) + { + uint64_t operand_value = PC + atoi(++pos); + // Put the address value into the operands. + comment.Printf("0x%*.*llx ", addr_nibble_size, addr_nibble_size, operand_value); + AddSymbolicInfo (exe_scope, comment, operand_value, GetAddress()); + } + } + // Yet more workaround for "bl #..." and "blx #...". + if ((m_arch_type == llvm::Triple::arm || m_arch_type == llvm::Triple::thumb) && + (m_opcode_name.compare("bl") == 0 || m_opcode_name.compare("blx") == 0)) + { + const char *inst_str; + const char *pos = NULL; + comment.Clear(); + if (EDGetInstString(&inst_str, m_inst) == 0 && (pos = strstr(inst_str, "#")) != NULL) + { + if (m_arch_type == llvm::Triple::thumb && m_opcode_name.compare("blx") == 0) + { + // A8.6.23 BLX (immediate) + // Target Address = Align(PC,4) + offset value + PC = AlignPC(PC); + } + uint64_t operand_value = PC + atoi(++pos); + // Put the address value into the comment. + comment.Printf("0x%*.*llx ", addr_nibble_size, addr_nibble_size, operand_value); + // And the original token string into the operands. +// llvm::StringRef Str(pos - 1); +// RStrip(Str, '\n'); +// operands.PutCString(Str.str().c_str()); + AddSymbolicInfo (exe_scope, comment, operand_value, GetAddress()); + } + } + // END of workaround. + + m_comment.swap (comment.GetString()); + } +} + +void +InstructionLLVM::CalculateMnemonics(ExecutionContextScope *exe_scope) +{ + // Do all of the work in CalculateOpcodeName() + CalculateOpcodeName (exe_scope); +} + +void +InstructionLLVM::CalculateComment(ExecutionContextScope *exe_scope) +{ + // Do all of the work in CalculateOpcodeName() + CalculateOpcodeName (exe_scope); +} + bool InstructionLLVM::DoesBranch() const { diff --git a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h index 0d2d920bb70..b9ab49005a3 100644 --- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h +++ b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h @@ -43,6 +43,15 @@ public: const lldb_private::DataExtractor &data, uint32_t data_offset); + virtual void + CalculateOpcodeName (lldb_private::ExecutionContextScope *exe_scope); + + virtual void + CalculateMnemonics (lldb_private::ExecutionContextScope *exe_scope); + + virtual void + CalculateComment (lldb_private::ExecutionContextScope *exe_scope); + protected: EDDisassemblerRef m_disassembler; EDInstRef m_inst; diff --git a/lldb/source/Symbol/Block.cpp b/lldb/source/Symbol/Block.cpp index d1e4d401498..6676279dabf 100644 --- a/lldb/source/Symbol/Block.cpp +++ b/lldb/source/Symbol/Block.cpp @@ -367,7 +367,7 @@ Block::GetRangeContainingOffset (const addr_t offset, VMRange &range) bool -Block::GetRangeContainingAddress (const Address& addr, AddressRange &range) +Block::GetRangeContainingAddress (const Address& addr, AddressRange &range, uint32_t *range_idx_ptr) { Function *function = CalculateSymbolContextFunction(); if (function) @@ -387,11 +387,15 @@ Block::GetRangeContainingAddress (const Address& addr, AddressRange &range) range.GetBaseAddress() = func_range.GetBaseAddress(); range.GetBaseAddress().SetOffset(func_offset + m_ranges[range_idx].GetBaseAddress()); range.SetByteSize(m_ranges[range_idx].GetByteSize()); + if (range_idx_ptr) + *range_idx_ptr = range_idx; return true; } } } } + if (range_idx_ptr) + *range_idx_ptr = UINT32_MAX; range.Clear(); return false; } diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp index 45a5f52c3bf..c7b2fb26613 100644 --- a/lldb/source/Symbol/SymbolContext.cpp +++ b/lldb/source/Symbol/SymbolContext.cpp @@ -487,6 +487,95 @@ SymbolContext::FindTypeByName (const ConstString &name) const return return_value; } +bool +SymbolContext::GetParentInlinedFrameInfo (const Address &curr_frame_pc, + bool is_concrete_frame, + SymbolContext &next_frame_sc, + Address &inlined_frame_addr) const +{ + next_frame_sc.Clear(); + inlined_frame_addr.Clear(); + + if (block) + { + bool concrete_has_inlines = false; + Block *curr_inlined_block = NULL; + Block *next_inlined_block = NULL; + //const addr_t curr_frame_file_addr = curr_frame_pc.GetFileAddress(); + if (is_concrete_frame) + { + curr_inlined_block = block->GetContainingInlinedBlock(); + if (curr_inlined_block) + { + concrete_has_inlines = true; + next_inlined_block = curr_inlined_block->GetInlinedParent(); + } + } + else + { + curr_inlined_block = block; + next_inlined_block = block->GetInlinedParent(); + } + + if (next_inlined_block) + { + next_inlined_block->CalculateSymbolContext (&next_frame_sc); + + AddressRange range; + bool got_range = curr_inlined_block->GetRangeContainingAddress (curr_frame_pc, range); + assert (got_range); + const InlineFunctionInfo* inline_info = next_inlined_block->GetInlinedFunctionInfo(); + if (inline_info) + { + inlined_frame_addr = range.GetBaseAddress(); + next_frame_sc.line_entry.range.GetBaseAddress() = inlined_frame_addr; + next_frame_sc.line_entry.file = inline_info->GetCallSite().GetFile(); + next_frame_sc.line_entry.line = inline_info->GetCallSite().GetLine(); + next_frame_sc.line_entry.column = inline_info->GetCallSite().GetColumn(); + return true; + } + } + else if (is_concrete_frame && !concrete_has_inlines) + { + // This is the symbol context for the frame that was found using the + // PC value and there are no inlined blocks so there are no inlined + // parent frames. + return false; + } + else + { + // We have had inlined frames before and now we are at the function + // instance that called the inlined frames. + // The SymbolContext object should contain a previous inline symbol + // context which we need to use to get the file, line and column info + const InlineFunctionInfo* inline_info = curr_inlined_block->GetInlinedFunctionInfo(); + if (inline_info) + { + Block *parent_block = curr_inlined_block->GetParent(); + if (parent_block) + { + parent_block->CalculateSymbolContext (&next_frame_sc); + + AddressRange range; + if (curr_inlined_block->GetRangeContainingAddress (curr_frame_pc, range)) + { + inlined_frame_addr = range.GetBaseAddress(); + //const addr_t range_file_file_addr = inlined_frame_addr.GetFileAddress(); + next_frame_sc.line_entry.range.GetBaseAddress() = inlined_frame_addr; + next_frame_sc.line_entry.file = inline_info->GetCallSite().GetFile(); + next_frame_sc.line_entry.line = inline_info->GetCallSite().GetLine(); + next_frame_sc.line_entry.column = inline_info->GetCallSite().GetColumn(); + return true; + } + } + } + } + } + + return false; +} + + //---------------------------------------------------------------------- // // SymbolContextSpecifier diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp index f8e1c6fa515..0d258790f3c 100644 --- a/lldb/source/Target/StackFrame.cpp +++ b/lldb/source/Target/StackFrame.cpp @@ -39,15 +39,12 @@ using namespace lldb_private; #define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1) #define RESOLVED_GLOBAL_VARIABLES (RESOLVED_VARIABLES << 1) -StackFrame::StackFrame -( - user_id_t frame_idx, - user_id_t unwind_frame_index, - Thread &thread, - addr_t cfa, - addr_t pc, - const SymbolContext *sc_ptr -) : +StackFrame::StackFrame (user_id_t frame_idx, + user_id_t unwind_frame_index, + Thread &thread, + addr_t cfa, + addr_t pc, + const SymbolContext *sc_ptr) : m_thread (thread), m_frame_index (frame_idx), m_concrete_frame_index (unwind_frame_index), @@ -69,16 +66,13 @@ StackFrame::StackFrame } } -StackFrame::StackFrame -( - user_id_t frame_idx, - user_id_t unwind_frame_index, - Thread &thread, - const RegisterContextSP ®_context_sp, - addr_t cfa, - addr_t pc, - const SymbolContext *sc_ptr -) : +StackFrame::StackFrame (user_id_t frame_idx, + user_id_t unwind_frame_index, + Thread &thread, + const RegisterContextSP ®_context_sp, + addr_t cfa, + addr_t pc, + const SymbolContext *sc_ptr) : m_thread (thread), m_frame_index (frame_idx), m_concrete_frame_index (unwind_frame_index), @@ -106,16 +100,13 @@ StackFrame::StackFrame } } -StackFrame::StackFrame -( - user_id_t frame_idx, - user_id_t unwind_frame_index, - Thread &thread, - const RegisterContextSP ®_context_sp, - addr_t cfa, - const Address& pc_addr, - const SymbolContext *sc_ptr -) : +StackFrame::StackFrame (user_id_t frame_idx, + user_id_t unwind_frame_index, + Thread &thread, + const RegisterContextSP ®_context_sp, + addr_t cfa, + const Address& pc_addr, + const SymbolContext *sc_ptr) : m_thread (thread), m_frame_index (frame_idx), m_concrete_frame_index (unwind_frame_index), |