This patch enables setting of breakpoints and disassembly for microMIPS applications running on bare-iron targets like IASim.
MIPS uses bit #0 (ISA bit) of an address for ISA mode (1 for microMIPS/MIPS16 and 0 for MIPS). The resulting address is called as compressed address when ISA bit is set. This allows processor to switch between microMIPS and MIPS without any need for special mode-control register. This bit is then cleared by the processor while fetching the instruction from memory. However, apart from .debug_line, none of the ELF/DWARF sections set the ISA bit.
In this patch:
- The symbol table is recorded in the form of compressed address for microMIPS symbols, so that corresponding debug_line can be decoded properly.
- Memory read/write of compressed address has been handled
This kind of address snipping is going to be needed in many different places and this should be done in:
lldb::addr_t
Target::GetOpcodeLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
You will note there is already similar functionality for ARM:
lldb::addr_t Target::GetOpcodeLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const { addr_t opcode_addr = load_addr; switch (m_arch.GetMachine()) { case llvm::Triple::arm: case llvm::Triple::thumb: switch (addr_class) { case eAddressClassData: case eAddressClassDebug: return LLDB_INVALID_ADDRESS; case eAddressClassInvalid: case eAddressClassUnknown: case eAddressClassCode: case eAddressClassCodeAlternateISA: case eAddressClassRuntime: opcode_addr &= ~(1ull); break; } break; default: break; } return opcode_addr; }Then you would typically access this via "Address::GetCallableLoadAddress (Target *target, bool is_indirect) const".
We should probably add a new method to Address:
Address Address::GetCallableAddress(Target *target, bool is_indirect) const { SectionSP section_sp (GetSection()); if (section_sp) { ModuleSP module_sp = section_sp->GetModule(); if (module_sp) { lldb::addr_t callable_file_addr = target->GetCallableLoadAddress (GetFileAddress(), GetAddressClass()); Address callable_addr; if (module_sp->ResolveFileAddress (callable_file_addr, callable_addr)) return callable_addr; } } return *this; }Then you should use this here: