diff options
author | Greg Clayton <gclayton@apple.com> | 2011-09-26 07:11:27 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2011-09-26 07:11:27 +0000 |
commit | 8f7180b11e024406e50ed53e27c95af461e6ec4d (patch) | |
tree | 58923ba4e035f927163db21665e0d69d20699317 /lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp | |
parent | 1748b37acd1826d9f02f75fbace1be49a596eae1 (diff) | |
download | bcm5719-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.cpp | 172 |
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 { |