diff options
author | dim <dim@FreeBSD.org> | 2016-01-13 20:06:56 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2016-01-13 20:06:56 +0000 |
commit | 8553c19974a5ab5f815b9e64f7bfe9899924726b (patch) | |
tree | 2b6dc7dcb4a6380cb331aded15f5a81c0038e194 /source/Target/Process.cpp | |
parent | 78b9749c0a4ea980a8b934645da6ae98fcc665e8 (diff) | |
download | FreeBSD-src-8553c19974a5ab5f815b9e64f7bfe9899924726b.zip FreeBSD-src-8553c19974a5ab5f815b9e64f7bfe9899924726b.tar.gz |
Vendor import of lldb trunk r257626:
https://llvm.org/svn/llvm-project/lldb/trunk@257626
Diffstat (limited to 'source/Target/Process.cpp')
-rw-r--r-- | source/Target/Process.cpp | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp index 311c695..e4fe419 100644 --- a/source/Target/Process.cpp +++ b/source/Target/Process.cpp @@ -6515,3 +6515,65 @@ Process::ResetImageToken(size_t token) if (token < m_image_tokens.size()) m_image_tokens[token] = LLDB_INVALID_IMAGE_TOKEN; } + +Address +Process::AdvanceAddressToNextBranchInstruction (Address default_stop_addr, AddressRange range_bounds) +{ + Target &target = GetTarget(); + DisassemblerSP disassembler_sp; + InstructionList *insn_list = NULL; + + Address retval = default_stop_addr; + + if (target.GetUseFastStepping() == false) + return retval; + if (default_stop_addr.IsValid() == false) + return retval; + + ExecutionContext exe_ctx (this); + const char *plugin_name = nullptr; + const char *flavor = nullptr; + const bool prefer_file_cache = true; + disassembler_sp = Disassembler::DisassembleRange(target.GetArchitecture(), + plugin_name, + flavor, + exe_ctx, + range_bounds, + prefer_file_cache); + if (disassembler_sp.get()) + insn_list = &disassembler_sp->GetInstructionList(); + + if (insn_list == NULL) + { + return retval; + } + + size_t insn_offset = insn_list->GetIndexOfInstructionAtAddress (default_stop_addr); + if (insn_offset == UINT32_MAX) + { + return retval; + } + + uint32_t branch_index = insn_list->GetIndexOfNextBranchInstruction (insn_offset, target); + if (branch_index == UINT32_MAX) + { + return retval; + } + + if (branch_index > insn_offset) + { + Address next_branch_insn_address = insn_list->GetInstructionAtIndex (branch_index)->GetAddress(); + if (next_branch_insn_address.IsValid() && range_bounds.ContainsFileAddress (next_branch_insn_address)) + { + retval = next_branch_insn_address; + } + } + + if (disassembler_sp.get()) + { + // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions. + disassembler_sp->GetInstructionList().Clear(); + } + + return retval; +} |