[Lldb-commits] [lldb] r248248 - [LLDB][MIPS] microMIPS breakpoints, disassembly and compressed addresses
Jaydeep Patil via lldb-commits
lldb-commits at lists.llvm.org
Mon Sep 21 23:36:57 PDT 2015
Author: jaydeep
Date: Tue Sep 22 01:36:56 2015
New Revision: 248248
URL: http://llvm.org/viewvc/llvm-project?rev=248248&view=rev
Log:
[LLDB][MIPS] microMIPS breakpoints, disassembly and compressed addresses
SUMMARY:
This patch detects microMIPS symbols, sets breakpoints using un-compressed address and
display disassembly in mixed mode for microMIPS applications (running on bare-iron targets).
Reviewers: clayborg
Subscribers: nitesh.jain, mohit.bhakkad, sagar, bhushan and lldb-commits
Differential Revision: http://reviews.llvm.org/D12079
Modified:
lldb/trunk/source/Core/Address.cpp
lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
lldb/trunk/source/Target/RegisterContext.cpp
lldb/trunk/source/Target/Target.cpp
Modified: lldb/trunk/source/Core/Address.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Address.cpp?rev=248248&r1=248247&r2=248248&view=diff
==============================================================================
--- lldb/trunk/source/Core/Address.cpp (original)
+++ lldb/trunk/source/Core/Address.cpp Tue Sep 22 01:36:56 2015
@@ -463,6 +463,20 @@ Address::Dump (Stream *s, ExecutionConte
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)
Modified: lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp?rev=248248&r1=248247&r2=248248&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp (original)
+++ lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp Tue Sep 22 01:36:56 2015
@@ -736,10 +736,6 @@ DisassemblerLLVMC::DisassemblerLLVMC (co
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,14 +746,35 @@ DisassemblerLLVMC::DisassemblerLLVMC (co
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));
if (!m_alternate_disasm_ap->IsValid())
{
m_disasm_ap.reset();
+ 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();
}
}
Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=248248&r1=248247&r2=248248&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Tue Sep 22 01:36:56 2015
@@ -1894,6 +1894,10 @@ FindArmAarch64MappingSymbol(const char*
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 *sym
}
}
}
+
+ /*
+ * 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
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=248248&r1=248247&r2=248248&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Tue Sep 22 01:36:56 2015
@@ -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
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::ParseCompileUnitLineTab
{
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)
Modified: lldb/trunk/source/Target/RegisterContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/RegisterContext.cpp?rev=248248&r1=248247&r2=248248&view=diff
==============================================================================
--- lldb/trunk/source/Target/RegisterContext.cpp (original)
+++ lldb/trunk/source/Target/RegisterContext.cpp Tue Sep 22 01:36:56 2015
@@ -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
Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=248248&r1=248247&r2=248248&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Tue Sep 22 01:36:56 2015
@@ -2155,6 +2155,27 @@ Target::GetCallableLoadAddress (lldb::ad
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
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)
More information about the lldb-commits
mailing list