diff options
| author | Tatyana Krasnukha <tatyana@synopsys.com> | 2018-09-21 18:56:44 +0000 |
|---|---|---|
| committer | Tatyana Krasnukha <tatyana@synopsys.com> | 2018-09-21 18:56:44 +0000 |
| commit | 7aa9e7bc5739f468143b7b97060a9fbbfb94c6d2 (patch) | |
| tree | 3f9cd442c3e9ded0624a27a2ed0e6e8b12eb229f /lldb/source/Target/Target.cpp | |
| parent | 720fbf553d2c5b0a00d995865972aa2b8a7033b2 (diff) | |
| download | bcm5719-llvm-7aa9e7bc5739f468143b7b97060a9fbbfb94c6d2.tar.gz bcm5719-llvm-7aa9e7bc5739f468143b7b97060a9fbbfb94c6d2.zip | |
Move architecture-specific address adjustment to architecture plugins
Differential Revision: https://reviews.llvm.org/D48623
llvm-svn: 342762
Diffstat (limited to 'lldb/source/Target/Target.cpp')
| -rw-r--r-- | lldb/source/Target/Target.cpp | 245 |
1 files changed, 9 insertions, 236 deletions
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 3141e76fd2d..b7d71acad18 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -2428,249 +2428,22 @@ lldb::addr_t Target::GetPersistentSymbol(const ConstString &name) { lldb::addr_t Target::GetCallableLoadAddress(lldb::addr_t load_addr, AddressClass addr_class) const { - addr_t code_addr = load_addr; - switch (m_arch.GetSpec().GetMachine()) { - case llvm::Triple::mips: - case llvm::Triple::mipsel: - case llvm::Triple::mips64: - case llvm::Triple::mips64el: - switch (addr_class) { - case AddressClass::eData: - case AddressClass::eDebug: - return LLDB_INVALID_ADDRESS; - - case AddressClass::eUnknown: - case AddressClass::eInvalid: - case AddressClass::eCode: - case AddressClass::eCodeAlternateISA: - case AddressClass::eRuntime: - if ((code_addr & 2ull) || (addr_class == AddressClass::eCodeAlternateISA)) - code_addr |= 1ull; - break; - } - break; - - case llvm::Triple::arm: - case llvm::Triple::thumb: - switch (addr_class) { - case AddressClass::eData: - case AddressClass::eDebug: - return LLDB_INVALID_ADDRESS; - - case AddressClass::eUnknown: - case AddressClass::eInvalid: - case AddressClass::eCode: - case AddressClass::eCodeAlternateISA: - case AddressClass::eRuntime: - // Check if bit zero it no set? - if ((code_addr & 1ull) == 0) { - // Bit zero isn't set, check if the address is a multiple of 2? - if (code_addr & 2ull) { - // The address is a multiple of 2 so it must be thumb, set bit zero - code_addr |= 1ull; - } else if (addr_class == AddressClass::eCodeAlternateISA) { - // We checked the address and the address claims to be the alternate - // ISA which means thumb, so set bit zero. - code_addr |= 1ull; - } - } - break; - } - break; - - default: - break; - } - return code_addr; + auto arch_plugin = GetArchitecturePlugin(); + return arch_plugin ? + arch_plugin->GetCallableLoadAddress(load_addr, addr_class) : load_addr; } lldb::addr_t Target::GetOpcodeLoadAddress(lldb::addr_t load_addr, AddressClass addr_class) const { - addr_t opcode_addr = load_addr; - switch (m_arch.GetSpec().GetMachine()) { - case llvm::Triple::mips: - case llvm::Triple::mipsel: - case llvm::Triple::mips64: - case llvm::Triple::mips64el: - case llvm::Triple::arm: - case llvm::Triple::thumb: - switch (addr_class) { - case AddressClass::eData: - case AddressClass::eDebug: - return LLDB_INVALID_ADDRESS; - - case AddressClass::eInvalid: - case AddressClass::eUnknown: - case AddressClass::eCode: - case AddressClass::eCodeAlternateISA: - case AddressClass::eRuntime: - opcode_addr &= ~(1ull); - break; - } - break; - - default: - break; - } - return opcode_addr; + auto arch_plugin = GetArchitecturePlugin(); + return arch_plugin ? + arch_plugin->GetOpcodeLoadAddress(load_addr, addr_class) : load_addr; } lldb::addr_t Target::GetBreakableLoadAddress(lldb::addr_t addr) { - addr_t breakable_addr = addr; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - - switch (m_arch.GetSpec().GetMachine()) { - default: - break; - case llvm::Triple::mips: - case llvm::Triple::mipsel: - case llvm::Triple::mips64: - case llvm::Triple::mips64el: { - addr_t function_start = 0; - addr_t current_offset = 0; - uint32_t loop_count = 0; - Address resolved_addr; - uint32_t arch_flags = m_arch.GetSpec().GetFlags(); - bool IsMips16 = arch_flags & ArchSpec::eMIPSAse_mips16; - bool IsMicromips = arch_flags & ArchSpec::eMIPSAse_micromips; - SectionLoadList §ion_load_list = GetSectionLoadList(); - - if (section_load_list.IsEmpty()) - // No sections are loaded, so we must assume we are not running yet and - // need to operate only on file address. - m_images.ResolveFileAddress(addr, resolved_addr); - else - section_load_list.ResolveLoadAddress(addr, resolved_addr); - - // Get the function boundaries to make sure we don't scan back before the - // beginning of the current function. - ModuleSP temp_addr_module_sp(resolved_addr.GetModule()); - if (temp_addr_module_sp) { - SymbolContext sc; - uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol; - temp_addr_module_sp->ResolveSymbolContextForAddress(resolved_addr, - resolve_scope, sc); - Address sym_addr; - if (sc.function) - sym_addr = sc.function->GetAddressRange().GetBaseAddress(); - else if (sc.symbol) - sym_addr = sc.symbol->GetAddress(); - - function_start = sym_addr.GetLoadAddress(this); - if (function_start == LLDB_INVALID_ADDRESS) - function_start = sym_addr.GetFileAddress(); - - if (function_start) - current_offset = addr - function_start; - } - - // If breakpoint address is start of function then we dont have to do - // anything. - if (current_offset == 0) - return breakable_addr; - else - loop_count = current_offset / 2; - - if (loop_count > 3) { - // Scan previous 6 bytes - if (IsMips16 | IsMicromips) - loop_count = 3; - // For mips-only, instructions are always 4 bytes, so scan previous 4 - // bytes only. - else - loop_count = 2; - } - - // Create Disassembler Instance - lldb::DisassemblerSP disasm_sp( - Disassembler::FindPlugin(m_arch.GetSpec(), nullptr, nullptr)); - - ExecutionContext exe_ctx; - CalculateExecutionContext(exe_ctx); - InstructionList instruction_list; - InstructionSP prev_insn; - bool prefer_file_cache = true; // Read from file - uint32_t inst_to_choose = 0; - - for (uint32_t i = 1; i <= loop_count; i++) { - // Adjust the address to read from. - resolved_addr.Slide(-2); - AddressRange range(resolved_addr, i * 2); - uint32_t insn_size = 0; - - disasm_sp->ParseInstructions(&exe_ctx, range, nullptr, prefer_file_cache); - - uint32_t num_insns = disasm_sp->GetInstructionList().GetSize(); - if (num_insns) { - prev_insn = disasm_sp->GetInstructionList().GetInstructionAtIndex(0); - insn_size = prev_insn->GetOpcode().GetByteSize(); - if (i == 1 && insn_size == 2) { - // This looks like a valid 2-byte instruction (but it could be a part - // of upper 4 byte instruction). - instruction_list.Append(prev_insn); - inst_to_choose = 1; - } else if (i == 2) { - // Here we may get one 4-byte instruction or two 2-byte instructions. - if (num_insns == 2) { - // Looks like there are two 2-byte instructions above our - // breakpoint target address. Now the upper 2-byte instruction is - // either a valid 2-byte instruction or could be a part of it's - // upper 4-byte instruction. In both cases we don't care because in - // this case lower 2-byte instruction is definitely a valid - // instruction and whatever i=1 iteration has found out is true. - inst_to_choose = 1; - break; - } else if (insn_size == 4) { - // This instruction claims its a valid 4-byte instruction. But it - // could be a part of it's upper 4-byte instruction. Lets try - // scanning upper 2 bytes to verify this. - instruction_list.Append(prev_insn); - inst_to_choose = 2; - } - } else if (i == 3) { - if (insn_size == 4) - // FIXME: We reached here that means instruction at [target - 4] has - // already claimed to be a 4-byte instruction, and now instruction - // at [target - 6] is also claiming that it's a 4-byte instruction. - // This can not be true. In this case we can not decide the valid - // previous instruction so we let lldb set the breakpoint at the - // address given by user. - inst_to_choose = 0; - else - // This is straight-forward - inst_to_choose = 2; - break; - } - } else { - // Decode failed, bytes do not form a valid instruction. So whatever - // previous iteration has found out is true. - if (i > 1) { - inst_to_choose = i - 1; - break; - } - } - } - - // Check if we are able to find any valid instruction. - if (inst_to_choose) { - if (inst_to_choose > instruction_list.GetSize()) - inst_to_choose--; - prev_insn = instruction_list.GetInstructionAtIndex(inst_to_choose - 1); - - if (prev_insn->HasDelaySlot()) { - uint32_t shift_size = prev_insn->GetOpcode().GetByteSize(); - // Adjust the breakable address - breakable_addr = addr - shift_size; - if (log) - log->Printf("Target::%s Breakpoint at 0x%8.8" PRIx64 - " is adjusted to 0x%8.8" PRIx64 " due to delay slot\n", - __FUNCTION__, addr, breakable_addr); - } - } - break; - } - } - return breakable_addr; + auto arch_plugin = GetArchitecturePlugin(); + return arch_plugin ? + arch_plugin->GetBreakableLoadAddress(addr, *this) : addr; } SourceManager &Target::GetSourceManager() { |

