diff options
author | Jim Ingham <jingham@apple.com> | 2014-03-25 00:15:47 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2014-03-25 00:15:47 +0000 |
commit | 2f2c876e4f342ce4a1d103fb4e9b2c65372df8a1 (patch) | |
tree | 7d8dfe045edcee69778439341adb4721743a2edd /lldb/source/Commands/CommandObjectDisassemble.cpp | |
parent | a0c0510845190a60ef9504a2e4efa12818bc84b2 (diff) | |
download | llvm-2f2c876e4f342ce4a1d103fb4e9b2c65372df8a1.zip llvm-2f2c876e4f342ce4a1d103fb4e9b2c65372df8a1.tar.gz llvm-2f2c876e4f342ce4a1d103fb4e9b2c65372df8a1.tar.bz2 |
Make "disassemble -a" work when the target is not running yet. It will dump all the functions matching that address, just like "disassemble -n" does before running.
<rdar://problem/16406570>
llvm-svn: 204689
Diffstat (limited to 'lldb/source/Commands/CommandObjectDisassemble.cpp')
-rw-r--r-- | lldb/source/Commands/CommandObjectDisassemble.cpp | 159 |
1 files changed, 102 insertions, 57 deletions
diff --git a/lldb/source/Commands/CommandObjectDisassemble.cpp b/lldb/source/Commands/CommandObjectDisassemble.cpp index f9c683b3..bdb98e7 100644 --- a/lldb/source/Commands/CommandObjectDisassemble.cpp +++ b/lldb/source/Commands/CommandObjectDisassemble.cpp @@ -370,6 +370,7 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result) } else { + std::vector<AddressRange> ranges; AddressRange range; StackFrame *frame = m_exe_ctx.GetFramePtr(); if (m_options.frame_line) @@ -425,6 +426,7 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result) // Disassembling at the PC always disassembles some number of instructions (not the whole function). m_options.num_instructions = DEFAULT_DISASM_NUM_INS; } + ranges.push_back(range); } else { @@ -440,50 +442,76 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result) return false; } range.SetByteSize (m_options.end_addr - m_options.start_addr); + ranges.push_back(range); } } else { if (m_options.symbol_containing_addr != LLDB_INVALID_ADDRESS - && target - && !target->GetSectionLoadList().IsEmpty()) + && target) { - bool failed = false; - Address symbol_containing_address; - if (target->GetSectionLoadList().ResolveLoadAddress (m_options.symbol_containing_addr, symbol_containing_address)) + if (!target->GetSectionLoadList().IsEmpty()) { - ModuleSP module_sp (symbol_containing_address.GetModule()); - SymbolContext sc; - bool resolve_tail_call_address = true; // PC can be one past the address range of the function. - module_sp->ResolveSymbolContextForAddress (symbol_containing_address, eSymbolContextEverything, sc, - resolve_tail_call_address); - if (sc.function || sc.symbol) + bool failed = false; + Address symbol_containing_address; + if (target->GetSectionLoadList().ResolveLoadAddress (m_options.symbol_containing_addr, symbol_containing_address)) { - sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range); + ModuleSP module_sp (symbol_containing_address.GetModule()); + SymbolContext sc; + bool resolve_tail_call_address = true; // PC can be one past the address range of the function. + module_sp->ResolveSymbolContextForAddress (symbol_containing_address, eSymbolContextEverything, sc, + resolve_tail_call_address); + if (sc.function || sc.symbol) + { + sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range); + } + else + { + failed = true; + } } else { failed = true; } + if (failed) + { + result.AppendErrorWithFormat ("Could not find function bounds for address 0x%" PRIx64 "\n", m_options.symbol_containing_addr); + result.SetStatus (eReturnStatusFailed); + return false; + } + ranges.push_back(range); } else { - failed = true; - } - if (failed) - { - result.AppendErrorWithFormat ("Could not find function bounds for address 0x%" PRIx64 "\n", m_options.symbol_containing_addr); - result.SetStatus (eReturnStatusFailed); - return false; + for (lldb::ModuleSP module_sp : target->GetImages().Modules()) + { + lldb::addr_t file_addr = m_options.symbol_containing_addr; + Address file_address; + if (module_sp->ResolveFileAddress(file_addr, file_address)) + { + SymbolContext sc; + bool resolve_tail_call_address = true; // PC can be one past the address range of the function. + module_sp->ResolveSymbolContextForAddress (file_address, eSymbolContextEverything, sc, resolve_tail_call_address); + if (sc.function || sc.symbol) + { + sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range); + ranges.push_back(range); + } + } + } + } } } } } + else + ranges.push_back(range); if (m_options.num_instructions != 0) { - if (!range.GetBaseAddress().IsValid()) + if (ranges.size() == 0) { // The default action is to disassemble the current frame function. if (frame) @@ -504,29 +532,38 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result) return false; } } - - if (Disassembler::Disassemble (m_interpreter.GetDebugger(), - m_options.arch, - plugin_name, - flavor_string, - m_exe_ctx, - range.GetBaseAddress(), - m_options.num_instructions, - m_options.show_mixed ? m_options.num_lines_context : 0, - options, - result.GetOutputStream())) - { - result.SetStatus (eReturnStatusSuccessFinishResult); - } - else + + bool print_sc_header = ranges.size() > 1; + for (AddressRange cur_range : ranges) { - result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", m_options.start_addr); - result.SetStatus (eReturnStatusFailed); + if (Disassembler::Disassemble (m_interpreter.GetDebugger(), + m_options.arch, + plugin_name, + flavor_string, + m_exe_ctx, + cur_range.GetBaseAddress(), + m_options.num_instructions, + m_options.show_mixed ? m_options.num_lines_context : 0, + options, + result.GetOutputStream())) + { + result.SetStatus (eReturnStatusSuccessFinishResult); + } + else + { + if (m_options.start_addr != LLDB_INVALID_ADDRESS) + result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", m_options.start_addr); + else if (m_options.symbol_containing_addr != LLDB_INVALID_ADDRESS) + result.AppendErrorWithFormat ("Failed to disassemble memory in function at 0x%8.8" PRIx64 ".\n", m_options.symbol_containing_addr); + result.SetStatus (eReturnStatusFailed); + } } + if (print_sc_header) + result.AppendMessage("\n"); } else { - if (!range.GetBaseAddress().IsValid()) + if (ranges.size() == 0) { // The default action is to disassemble the current frame function. if (frame) @@ -548,27 +585,35 @@ CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result) result.SetStatus (eReturnStatusFailed); return false; } + ranges.push_back(range); } - if (range.GetByteSize() == 0) - range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE); - - if (Disassembler::Disassemble (m_interpreter.GetDebugger(), - m_options.arch, - plugin_name, - flavor_string, - m_exe_ctx, - range, - m_options.num_instructions, - m_options.show_mixed ? m_options.num_lines_context : 0, - options, - result.GetOutputStream())) + + bool print_sc_header = ranges.size() > 1; + for (AddressRange cur_range : ranges) { - result.SetStatus (eReturnStatusSuccessFinishResult); - } - else - { - result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", m_options.start_addr); - result.SetStatus (eReturnStatusFailed); + if (cur_range.GetByteSize() == 0) + cur_range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE); + + if (Disassembler::Disassemble (m_interpreter.GetDebugger(), + m_options.arch, + plugin_name, + flavor_string, + m_exe_ctx, + cur_range, + m_options.num_instructions, + m_options.show_mixed ? m_options.num_lines_context : 0, + options, + result.GetOutputStream())) + { + result.SetStatus (eReturnStatusSuccessFinishResult); + } + else + { + result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", m_options.start_addr); + result.SetStatus (eReturnStatusFailed); + } + if (print_sc_header) + result.AppendMessage("\n"); } } } |