Index: source/Commands/CommandObjectFrame.cpp =================================================================== --- source/Commands/CommandObjectFrame.cpp +++ source/Commands/CommandObjectFrame.cpp @@ -45,6 +45,8 @@ #include "lldb/Target/StackFrame.h" #include "lldb/Target/Thread.h" #include "lldb/Target/Target.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/SectionLoadList.h" using namespace lldb; using namespace lldb_private; @@ -602,6 +604,122 @@ OptionGroupValueObjectDisplay m_varobj_options; }; +class CommandObjectFrameDump : public CommandObjectParsed +{ +public: + + CommandObjectFrameDump (CommandInterpreter &interpreter) : + CommandObjectParsed ( interpreter, + "frame dump", + "Dump the current stack frame", + "frame dump", + eFlagRequiresTarget | + eFlagRequiresFrame | + eFlagTryTargetAPILock | + eFlagProcessMustBeLaunched | + eFlagProcessMustBePaused ) + { + } + + ~CommandObjectFrameDump () + { + } + +protected: + bool + DoExecute (Args& command, CommandReturnObject &result) + { + result.SetStatus (eReturnStatusSuccessFinishResult); + lldb_private::Error error; + + // get the current target + Target *target = m_exe_ctx.GetTargetPtr(); + + // get the architecture bit size + int archBits = target->GetArchitecture( ).GetAddressByteSize( ); + + lldb_private::Stream &output = result.GetOutputStream( ); + lldb_private::StackFrame *frame = m_exe_ctx.GetFramePtr( ); + lldb_private::RegisterContext *reg = frame->GetRegisterContext( ).get( ); + + // find the frame extent + uint64_t r_sp = reg->GetSP( ); + uint64_t r_fp = reg->GetFP( ); + uint64_t start = r_sp - archBits*2; // pad out a little + uint64_t end = r_fp + archBits*3; + int64_t size = (end - start); + + // check we have something to read + if ( size <= 0 ) + return result.Succeeded(); + + // allocate space for the memory read + uint8_t * data = new uint8_t[ size ]; + assert( data != nullptr ); + + // read in the stack data + Address memAddr = Address( start ); + size_t read = target->ReadMemory( memAddr, false, data, size, error ); + + // only dump as much as we have + if ( read < size ) size = read; + + // display the current frame index + uint32_t fidx = frame->GetFrameIndex( ); + m_exe_ctx.GetFrameRef().DumpUsingSettingsFormat( &output ); + + // + uint64_t value = 0; + + // print out the stack + for ( int i = 0; i < size; i++ ) + { + // start of aligned address + if ( start % archBits == 0 ) + { + if ( i > 0 ) + { + // dump symbol for this stack entry + Address so_reg_addr; + if ( target->GetSectionLoadList().ResolveLoadAddress( value, so_reg_addr) ) + { + output.PutCString (" "); + so_reg_addr.Dump(&output, m_exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription); + } + output.Printf( "\n" ); + } + + // label the sp and fp + if ( start == r_sp ) output.Printf( "sp> " ); + else if ( start == r_fp ) output.Printf( "fp> " ); + else output.Printf( " " ); + + // output the address + output.Printf( "0x%08x: ", start ); + + // clear the current value + value = 0; + } + + // push data into values high byte + value = ( value >> 8 ); + value |= ( data[i] << 24 ); // sets sign bit for ? reason + value &= 0xffffffff; // so have to mask + + // output one byte of data + output.Printf( "%02x ", data[i] ); + start += 1; + } + + // clean up and release the memory + if ( data != nullptr ) + delete[] data; + data = nullptr; + + output.Printf( "\n" ); + return result.Succeeded(); + } +}; #pragma mark CommandObjectMultiwordFrame @@ -615,9 +733,10 @@ "A set of commands for operating on the current thread's frames.", "frame []") { - LoadSubCommand ("info", CommandObjectSP (new CommandObjectFrameInfo (interpreter))); - LoadSubCommand ("select", CommandObjectSP (new CommandObjectFrameSelect (interpreter))); - LoadSubCommand ("variable", CommandObjectSP (new CommandObjectFrameVariable (interpreter))); + LoadSubCommand ("info" , CommandObjectSP (new CommandObjectFrameInfo (interpreter))); + LoadSubCommand ("select" , CommandObjectSP (new CommandObjectFrameSelect (interpreter))); + LoadSubCommand ("variable", CommandObjectSP (new CommandObjectFrameVariable(interpreter))); + LoadSubCommand ("dump ", CommandObjectSP (new CommandObjectFrameDump (interpreter))); } CommandObjectMultiwordFrame::~CommandObjectMultiwordFrame () Index: source/Commands/CommandObjectRegister.cpp =================================================================== --- source/Commands/CommandObjectRegister.cpp +++ source/Commands/CommandObjectRegister.cpp @@ -154,6 +154,10 @@ if (primitive_only && reg_info && reg_info->value_regs) continue; + // dont dump invalid (padding) registers + if (reg_info->format == eFormatInvalid && reg_info->encoding == eEncodingInvalid) + continue; + if (DumpRegister (exe_ctx, strm, reg_ctx, reg_info)) ++available_count; else