diff options
author | Sean Callanan <scallanan@apple.com> | 2012-03-02 23:22:53 +0000 |
---|---|---|
committer | Sean Callanan <scallanan@apple.com> | 2012-03-02 23:22:53 +0000 |
commit | 7725a4630d8b48a5039ca2f4218aac2aae299e3a (patch) | |
tree | de57138777a62cc87e334ebf5d622572931e1f58 /lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp | |
parent | b8b21e9b5640fa6509eb885649df8fb9b9d08611 (diff) | |
download | bcm5719-llvm-7725a4630d8b48a5039ca2f4218aac2aae299e3a.tar.gz bcm5719-llvm-7725a4630d8b48a5039ca2f4218aac2aae299e3a.zip |
Added a function to the disassembler that checks
(from the mnemonic) whether an instruction is a
branch. This function's result is exposed through
DoesBranch().
llvm-svn: 151953
Diffstat (limited to 'lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp')
-rw-r--r-- | lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp | 94 |
1 files changed, 92 insertions, 2 deletions
diff --git a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp index d8799560252..2667ff0d456 100644 --- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp +++ b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp @@ -37,7 +37,8 @@ public: m_disasm(disasm), m_is_valid(false), m_no_comments(true), - m_comment_stream() + m_comment_stream(), + m_does_branch(eLazyBoolCalculate) { } @@ -147,7 +148,7 @@ public: virtual bool DoesBranch () const { - return false; + return m_does_branch == eLazyBoolYes; } virtual size_t @@ -251,6 +252,90 @@ protected: } } + bool StringRepresentsBranch (const char *data, size_t size) + { + const char *cursor = data; + + bool inWhitespace = true; + + while (inWhitespace && cursor < data + size) + { + switch (*cursor) + { + default: + inWhitespace = false; + break; + case ' ': + break; + case '\t': + break; + } + + if (inWhitespace) + ++cursor; + } + + if (cursor >= data + size) + return false; + + llvm::Triple::ArchType arch = m_disasm.GetArchitecture().GetMachine(); + + switch (arch) + { + default: + return false; + case llvm::Triple::x86: + case llvm::Triple::x86_64: + switch (cursor[0]) + { + default: + return false; + case 'j': + return true; + case 'c': + if (cursor[1] == 'a' && + cursor[2] == 'l' && + cursor[3] == 'l') + return true; + else + return false; + } + case llvm::Triple::arm: + case llvm::Triple::thumb: + switch (cursor[0]) + { + default: + return false; + case 'b': + { + switch (cursor[1]) + { + default: + return false; + case 'l': + case 'x': + case ' ': + case '\t': + return true; + } + return false; + } + case 'c': + { + switch (cursor[1]) + { + default: + return false; + case 'b': + return true; + } + } + } + } + + return false; + } + template <bool Reparse> bool Parse (const lldb_private::Address &address, lldb_private::AddressClass addr_class, const DataExtractor &extractor, @@ -279,6 +364,10 @@ protected: out_string.data(), out_string.size()); + if (m_does_branch == eLazyBoolCalculate) + m_does_branch = (StringRepresentsBranch (out_string.data(), out_string.size()) ? + eLazyBoolYes : eLazyBoolNo); + m_comment_stream.Flush(); m_no_comments = false; @@ -331,6 +420,7 @@ protected: bool m_no_comments; StreamString m_comment_stream; + LazyBool m_does_branch; static bool s_regex_compiled; static ::regex_t s_regex; |