summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2011-09-26 07:11:27 +0000
committerGreg Clayton <gclayton@apple.com>2011-09-26 07:11:27 +0000
commit8f7180b11e024406e50ed53e27c95af461e6ec4d (patch)
tree58923ba4e035f927163db21665e0d69d20699317 /lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
parent1748b37acd1826d9f02f75fbace1be49a596eae1 (diff)
downloadbcm5719-llvm-8f7180b11e024406e50ed53e27c95af461e6ec4d.tar.gz
bcm5719-llvm-8f7180b11e024406e50ed53e27c95af461e6ec4d.zip
Added more functionality to the public API to allow for better
symbolication. Also improved the SBInstruction API to allow access to the instruction opcode name, mnemonics, comment and instruction data. Added the ability to edit SBLineEntry objects (change the file, line and column), and also allow SBSymbolContext objects to be modified (set module, comp unit, function, block, line entry or symbol). The SymbolContext and SBSymbolContext can now generate inlined call stack infomration for symbolication much easier using the SymbolContext::GetParentInlinedFrameInfo(...) and SBSymbolContext::GetParentInlinedFrameInfo(...) methods. llvm-svn: 140518
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