[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