diff options
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 { |