summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp')
-rw-r--r--lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp172
1 files changed, 158 insertions, 14 deletions
diff --git a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
index a8c423f44e6..610271deb98 100644
--- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
+++ b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
@@ -99,13 +99,15 @@ PadString(Stream *s, const std::string &str, size_t width)
s->Printf("%s ", str.c_str());
}
static void
-AddSymbolicInfo(const ExecutionContext *exe_ctx, ExecutionContextScope *exe_scope,
- StreamString &comment, uint64_t operand_value, const Address &inst_addr)
+AddSymbolicInfo (ExecutionContextScope *exe_scope,
+ StreamString &comment,
+ uint64_t operand_value,
+ const Address &inst_addr)
{
Address so_addr;
Target *target = NULL;
- if (exe_ctx)
- target = exe_ctx->GetTargetPtr();
+ if (exe_scope)
+ target = exe_scope->CalculateTarget();
if (target && !target->GetSectionLoadList().IsEmpty())
{
if (target->GetSectionLoadList().ResolveLoadAddress(operand_value, so_addr))
@@ -225,12 +227,16 @@ InstructionLLVM::Dump
if (numTokens != -1 && !raw)
{
addr_t base_addr = LLDB_INVALID_ADDRESS;
-
+ uint32_t addr_nibble_size = 8;
Target *target = NULL;
if (exe_ctx)
target = exe_ctx->GetTargetPtr();
- if (target && !target->GetSectionLoadList().IsEmpty())
- base_addr = GetAddress().GetLoadAddress (target);
+ if (target)
+ {
+ if (!target->GetSectionLoadList().IsEmpty())
+ base_addr = GetAddress().GetLoadAddress (target);
+ addr_nibble_size = target->GetArchitecture().GetAddressByteSize() * 2;
+ }
if (base_addr == LLDB_INVALID_ADDRESS)
base_addr = GetAddress().GetFileAddress ();
@@ -314,16 +320,16 @@ InstructionLLVM::Dump
{
if (EDInstIsBranch(m_inst))
{
- operands.Printf("0x%llx ", operand_value);
+ operands.Printf("0x%*.*llx ", addr_nibble_size, addr_nibble_size, operand_value);
show_token = false;
}
else
{
// Put the address value into the comment
- comment.Printf("0x%llx ", operand_value);
+ comment.Printf("0x%*.*llx ", addr_nibble_size, addr_nibble_size, operand_value);
}
- AddSymbolicInfo(exe_ctx, exe_scope, comment, operand_value, GetAddress());
+ AddSymbolicInfo(exe_scope, comment, operand_value, GetAddress());
} // EDEvaluateOperand
} // EDOperandIsMemory
} // EDGetOperand
@@ -351,8 +357,8 @@ InstructionLLVM::Dump
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 operands.
- operands.Printf("0x%llx ", operand_value);
- AddSymbolicInfo(exe_ctx, exe_scope, comment, operand_value, GetAddress());
+ operands.Printf("0x%8.8llx ", operand_value);
+ AddSymbolicInfo(exe_scope, comment, operand_value, GetAddress());
}
}
// Yet more workaround for "bl #..." and "blx #...".
@@ -369,12 +375,12 @@ InstructionLLVM::Dump
}
uint64_t operand_value = PC + atoi(++pos);
// Put the address value into the comment.
- comment.Printf("0x%llx ", operand_value);
+ comment.Printf("0x%8.8llx ", operand_value);
// And the original token string into the operands.
llvm::StringRef Str(pos - 1);
RStrip(Str, '\n');
operands.PutCString(Str.str().c_str());
- AddSymbolicInfo(exe_ctx, exe_scope, comment, operand_value, GetAddress());
+ AddSymbolicInfo(exe_scope, comment, operand_value, GetAddress());
}
}
// END of workaround.
@@ -423,6 +429,144 @@ InstructionLLVM::Dump
}
}
+void
+InstructionLLVM::CalculateOpcodeName (ExecutionContextScope *exe_scope)
+{
+ const int num_tokens = EDNumTokens(m_inst);
+ if (num_tokens > 0)
+ {
+ const char *token_cstr = NULL;
+ int currentOpIndex = -1;
+ StreamString comment;
+ uint32_t addr_nibble_size = 8;
+ addr_t base_addr = LLDB_INVALID_ADDRESS;
+ Target *target = NULL;
+ if (exe_scope)
+ target = exe_scope->CalculateTarget();
+ if (target && !target->GetSectionLoadList().IsEmpty())
+ base_addr = GetAddress().GetLoadAddress (target);
+ if (base_addr == LLDB_INVALID_ADDRESS)
+ base_addr = GetAddress().GetFileAddress ();
+ addr_nibble_size = target->GetArchitecture().GetAddressByteSize() * 2;
+
+ lldb::addr_t PC = base_addr + EDInstByteSize(m_inst);
+
+ // When executing an ARM instruction, PC reads as the address of the
+ // current instruction plus 8. And for Thumb, it is plus 4.
+ if (m_arch_type == llvm::Triple::arm)
+ PC = base_addr + 8;
+ else if (m_arch_type == llvm::Triple::thumb)
+ PC = base_addr + 4;
+
+ RegisterReaderArg rra(PC, m_disassembler);
+
+ for (int token_idx = 0; token_idx < num_tokens; ++token_idx)
+ {
+ EDTokenRef token;
+ if (EDGetToken(&token, m_inst, token_idx))
+ break;
+
+ if (EDTokenIsOpcode(token) == 1)
+ {
+ if (EDGetTokenString(&token_cstr, token) == 0) // 0 on success
+ {
+ if (token_cstr)
+ m_opcode_name.assign(token_cstr);
+ }
+ }
+ else
+ {
+ int operandIndex = EDOperandIndexForToken(token);
+
+ if (operandIndex >= 0)
+ {
+ if (operandIndex != currentOpIndex)
+ {
+ currentOpIndex = operandIndex;
+ EDOperandRef operand;
+
+ if (!EDGetOperand(&operand, m_inst, currentOpIndex))
+ {
+ if (EDOperandIsMemory(operand))
+ {
+ uint64_t operand_value;
+
+ if (!EDEvaluateOperand(&operand_value, operand, IPRegisterReader, &rra))
+ {
+ comment.Printf("0x%*.*llx ", addr_nibble_size, addr_nibble_size, operand_value);
+ AddSymbolicInfo (exe_scope, comment, operand_value, GetAddress());
+ }
+ }
+ }
+ }
+ }
+ if (m_mnemocics.empty() && EDTokenIsWhitespace (token) == 1)
+ continue;
+ if (EDGetTokenString (&token_cstr, token))
+ break;
+ m_mnemocics.append (token_cstr);
+ }
+ }
+ // FIXME!!!
+ // Workaround for llvm::tB's operands not properly parsed by ARMAsmParser.
+ if (m_arch_type == llvm::Triple::thumb && m_opcode_name.compare("b") == 0)
+ {
+ const char *inst_str;
+ const char *pos = NULL;
+ 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 operands.
+ comment.Printf("0x%*.*llx ", addr_nibble_size, addr_nibble_size, operand_value);
+ AddSymbolicInfo (exe_scope, comment, operand_value, GetAddress());
+ }
+ }
+ // Yet more workaround for "bl #..." and "blx #...".
+ if ((m_arch_type == llvm::Triple::arm || m_arch_type == llvm::Triple::thumb) &&
+ (m_opcode_name.compare("bl") == 0 || m_opcode_name.compare("blx") == 0))
+ {
+ const char *inst_str;
+ const char *pos = NULL;
+ comment.Clear();
+ if (EDGetInstString(&inst_str, m_inst) == 0 && (pos = strstr(inst_str, "#")) != NULL)
+ {
+ if (m_arch_type == llvm::Triple::thumb && m_opcode_name.compare("blx") == 0)
+ {
+ // A8.6.23 BLX (immediate)
+ // Target Address = Align(PC,4) + offset value
+ PC = AlignPC(PC);
+ }
+ uint64_t operand_value = PC + atoi(++pos);
+ // Put the address value into the comment.
+ comment.Printf("0x%*.*llx ", addr_nibble_size, addr_nibble_size, operand_value);
+ // And the original token string into the operands.
+// llvm::StringRef Str(pos - 1);
+// RStrip(Str, '\n');
+// operands.PutCString(Str.str().c_str());
+ AddSymbolicInfo (exe_scope, comment, operand_value, GetAddress());
+ }
+ }
+ // END of workaround.
+
+ m_comment.swap (comment.GetString());
+ }
+}
+
+void
+InstructionLLVM::CalculateMnemonics(ExecutionContextScope *exe_scope)
+{
+ // Do all of the work in CalculateOpcodeName()
+ CalculateOpcodeName (exe_scope);
+}
+
+void
+InstructionLLVM::CalculateComment(ExecutionContextScope *exe_scope)
+{
+ // Do all of the work in CalculateOpcodeName()
+ CalculateOpcodeName (exe_scope);
+}
+
bool
InstructionLLVM::DoesBranch() const
{
OpenPOWER on IntegriCloud