diff options
Diffstat (limited to 'lldb')
| -rw-r--r-- | lldb/source/Core/Address.cpp | 14 | ||||
| -rw-r--r-- | lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp | 27 | ||||
| -rw-r--r-- | lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 35 | ||||
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 25 | ||||
| -rw-r--r-- | lldb/source/Target/RegisterContext.cpp | 16 | ||||
| -rw-r--r-- | lldb/source/Target/Target.cpp | 25 |
6 files changed, 135 insertions, 7 deletions
diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp index f1c131dc6c4..ab8d2e5544b 100644 --- a/lldb/source/Core/Address.cpp +++ b/lldb/source/Core/Address.cpp @@ -463,6 +463,20 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum case DumpStyleLoadAddress: { addr_t load_addr = GetLoadAddress (target); + + /* + * MIPS: + * Display address in compressed form for MIPS16 or microMIPS + * if the address belongs to eAddressClassCodeAlternateISA. + */ + if (target) + { + const llvm::Triple::ArchType llvm_arch = target->GetArchitecture().GetMachine(); + if (llvm_arch == llvm::Triple::mips || llvm_arch == llvm::Triple::mipsel + || llvm_arch == llvm::Triple::mips64 || llvm_arch == llvm::Triple::mips64el) + load_addr = GetCallableLoadAddress (target); + } + if (load_addr == LLDB_INVALID_ADDRESS) { if (fallback_style != DumpStyleInvalid) diff --git a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp index d527bdc63d1..6626c92c4f2 100644 --- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp +++ b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp @@ -736,10 +736,6 @@ DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_s features_str += "+dsp,"; if (arch_flags & ArchSpec::eMIPSAse_dspr2) features_str += "+dspr2,"; - if (arch_flags & ArchSpec::eMIPSAse_mips16) - features_str += "+mips16,"; - if (arch_flags & ArchSpec::eMIPSAse_micromips) - features_str += "+micromips,"; } m_disasm_ap.reset (new LLVMCDisassembler(triple_str, cpu, features_str.c_str(), flavor, *this)); @@ -750,8 +746,10 @@ DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_s m_disasm_ap.reset(); } + llvm::Triple::ArchType llvm_arch = triple.getArch(); + // For arm CPUs that can execute arm or thumb instructions, also create a thumb instruction disassembler. - if (triple.getArch() == llvm::Triple::arm) + if (llvm_arch == llvm::Triple::arm) { std::string thumb_triple(thumb_arch.GetTriple().getTriple()); m_alternate_disasm_ap.reset(new LLVMCDisassembler(thumb_triple.c_str(), "", "", flavor, *this)); @@ -761,6 +759,25 @@ DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_s m_alternate_disasm_ap.reset(); } } + else if (llvm_arch == llvm::Triple::mips + || llvm_arch == llvm::Triple::mipsel + || llvm_arch == llvm::Triple::mips64 + || llvm_arch == llvm::Triple::mips64el) + { + /* Create alternate disassembler for MIPS16 and microMIPS */ + uint32_t arch_flags = arch.GetFlags (); + if (arch_flags & ArchSpec::eMIPSAse_mips16) + features_str += "+mips16,"; + else if (arch_flags & ArchSpec::eMIPSAse_micromips) + features_str += "+micromips,"; + + m_alternate_disasm_ap.reset(new LLVMCDisassembler (triple_str, cpu, features_str.c_str(), flavor, *this)); + if (!m_alternate_disasm_ap->IsValid()) + { + m_disasm_ap.reset(); + m_alternate_disasm_ap.reset(); + } + } } DisassemblerLLVMC::~DisassemblerLLVMC() diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 4c6782d59c8..cb8bd649f07 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -1894,6 +1894,10 @@ FindArmAarch64MappingSymbol(const char* symbol_name) return '\0'; } +#define STO_MIPS_ISA (3 << 6) +#define STO_MICROMIPS (2 << 6) +#define IS_MICROMIPS(ST_OTHER) (((ST_OTHER) & STO_MIPS_ISA) == STO_MICROMIPS) + // private unsigned ObjectFileELF::ParseSymbols (Symtab *symtab, @@ -2113,6 +2117,37 @@ ObjectFileELF::ParseSymbols (Symtab *symtab, } } } + + /* + * MIPS: + * The bit #0 of an address is used for ISA mode (1 for microMIPS, 0 for MIPS). + * This allows processer to switch between microMIPS and MIPS without any need + * for special mode-control register. However, apart from .debug_line, none of + * the ELF/DWARF sections set the ISA bit (for symbol or section). Use st_other + * flag to check whether the symbol is microMIPS and then set the address class + * accordingly. + */ + const llvm::Triple::ArchType llvm_arch = arch.GetMachine(); + if (llvm_arch == llvm::Triple::mips || llvm_arch == llvm::Triple::mipsel + || llvm_arch == llvm::Triple::mips64 || llvm_arch == llvm::Triple::mips64el) + { + if (IS_MICROMIPS(symbol.st_other)) + m_address_class_map[symbol.st_value] = eAddressClassCodeAlternateISA; + else if ((symbol.st_value & 1) && (symbol_type == eSymbolTypeCode)) + { + symbol.st_value = symbol.st_value & (~1ull); + m_address_class_map[symbol.st_value] = eAddressClassCodeAlternateISA; + } + else + { + if (symbol_type == eSymbolTypeCode) + m_address_class_map[symbol.st_value] = eAddressClassCode; + else if (symbol_type == eSymbolTypeData) + m_address_class_map[symbol.st_value] = eAddressClassData; + else + m_address_class_map[symbol.st_value] = eAddressClassUnknown; + } + } } // symbol_value_offset may contain 0 for ARM symbols or -1 for diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index cdb1798f4e2..43c3d7676ec 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1110,6 +1110,7 @@ struct ParseDWARFLineTableCallbackInfo { LineTable* line_table; std::unique_ptr<LineSequence> sequence_ap; + lldb::addr_t addr_mask; }; //---------------------------------------------------------------------- @@ -1139,7 +1140,7 @@ ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& sta assert(info->sequence_ap.get()); } line_table->AppendLineEntryToSequence (info->sequence_ap.get(), - state.address, + state.address & info->addr_mask, state.line, state.column, state.file, @@ -1179,6 +1180,28 @@ SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc) { ParseDWARFLineTableCallbackInfo info; info.line_table = line_table_ap.get(); + + /* + * MIPS: + * The SymbolContext may not have a valid target, thus we may not be able + * to call Address::GetOpcodeLoadAddress() which would clear the bit #0 + * for MIPS. Use ArchSpec to clear the bit #0. + */ + ArchSpec arch; + GetObjectFile()->GetArchitecture(arch); + switch (arch.GetMachine()) + { + case llvm::Triple::mips: + case llvm::Triple::mipsel: + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + info.addr_mask = ~((lldb::addr_t)1); + break; + default: + info.addr_mask = ~((lldb::addr_t)0); + break; + } + lldb::offset_t offset = cu_line_offset; DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info); if (m_debug_map_symfile) diff --git a/lldb/source/Target/RegisterContext.cpp b/lldb/source/Target/RegisterContext.cpp index 97f6f21c53c..2a4973adb7b 100644 --- a/lldb/source/Target/RegisterContext.cpp +++ b/lldb/source/Target/RegisterContext.cpp @@ -20,6 +20,7 @@ #include "lldb/Target/StackFrame.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" +#include "lldb/Target/Target.h" using namespace lldb; using namespace lldb_private; @@ -103,7 +104,20 @@ uint64_t RegisterContext::GetPC(uint64_t fail_value) { uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); - return ReadRegisterAsUnsigned (reg, fail_value); + uint64_t pc = ReadRegisterAsUnsigned (reg, fail_value); + + if (pc != fail_value) + { + TargetSP target_sp = m_thread.CalculateTarget(); + if (target_sp) + { + Target *target = target_sp.get(); + if (target) + pc = target->GetOpcodeLoadAddress (pc, eAddressClassCode); + } + } + + return pc; } bool diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 8284bdbe348..dc478bb08c1 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -2155,6 +2155,27 @@ Target::GetCallableLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) addr_t code_addr = load_addr; switch (m_arch.GetMachine()) { + case llvm::Triple::mips: + case llvm::Triple::mipsel: + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + switch (addr_class) + { + case eAddressClassData: + case eAddressClassDebug: + return LLDB_INVALID_ADDRESS; + + case eAddressClassUnknown: + case eAddressClassInvalid: + case eAddressClassCode: + case eAddressClassCodeAlternateISA: + case eAddressClassRuntime: + if ((code_addr & 2ull) || (addr_class == eAddressClassCodeAlternateISA)) + code_addr |= 1ull; + break; + } + break; + case llvm::Triple::arm: case llvm::Triple::thumb: switch (addr_class) @@ -2200,6 +2221,10 @@ Target::GetOpcodeLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) c addr_t opcode_addr = load_addr; switch (m_arch.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) |

