Add more workarounds for "bl #..." and "blx #..." where the ARMAsmParser fails to parse/recognize
the (PC-relative) immediate operand.


git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@131913 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp b/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
index 4b5d1dc..b5020fd 100644
--- a/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
+++ b/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
@@ -328,6 +328,7 @@
             if (m_arch_type == llvm::Triple::thumb && opcode.GetString() == "b") {
                 const char *inst_str;
                 const char *pos = NULL;
+                operands.Clear(); comment.Clear();
                 if (EDGetInstString(&inst_str, m_inst) == 0 && (pos = strstr(inst_str, "#")) != NULL) {
                     uint64_t operand_value = PC + atoi(++pos);
                     operands.Printf("0x%llx ", operand_value);
@@ -345,6 +346,33 @@
                     }
                 }
             }
+            // Yet more workaround for "bl #..." and "blx #...".
+            if ((m_arch_type == llvm::Triple::arm || m_arch_type == llvm::Triple::thumb) &&
+                (opcode.GetString() == "bl" || opcode.GetString() == "blx")) {
+                const char *inst_str;
+                const char *pos = NULL;
+                operands.Clear(); 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 comment
+                    comment.Printf("0x%llx ", operand_value);
+                    llvm::StringRef string_ref(pos - 1);
+                    llvm::StringRef operand_string_ref = string_ref.split('\n').first;
+                    operands.PutCString(operand_string_ref.str().c_str());
+
+                    lldb_private::Address so_addr;
+                    if (exe_ctx && exe_ctx->target && !exe_ctx->target->GetSectionLoadList().IsEmpty()) {
+                        if (exe_ctx->target->GetSectionLoadList().ResolveLoadAddress (operand_value, so_addr))
+                            so_addr.Dump(&comment, exe_scope, Address::DumpStyleResolvedDescriptionNoModule, Address::DumpStyleSectionNameOffset);
+                    } else {
+                        Module *module = GetAddress().GetModule();
+                        if (module) {
+                            if (module->ResolveFileAddress (operand_value, so_addr))
+                                so_addr.Dump(&comment, exe_scope, Address::DumpStyleResolvedDescriptionNoModule, Address::DumpStyleSectionNameOffset);
+                        }
+                    }
+                }
+            }
             // END of workaround.
 
             // If both operands and comment are empty, we will just print out