jaydeep updated this revision to Diff 34292.
jaydeep added a comment.

In this patch:

- Removed MIPS comment from generic code
- Used Target::GetOpcodeLoadAddress to fixup the PC

Regarding change in FormatEntity.cpp:

We still need to do this. The bit #0 of ‘addr’ has already been striped and 
thus it does not represent its true address space (microMIPS or MIPS). We need 
to call GetCallableLoadAddress here because we want to set the bit #0 of this 
address if it belongs to eAddressClassCodeAlternateISA.

This change displays the microMIPS disassembly (and other addresses) in compact 
address space:

  0x8020067d <+0>:  addiusp -16
  0x8020067f <+2>:  sw     $fp, 12($sp)
  0x80200681 <+4>:  move   $fp, $sp

- thread #1: tid = 0x0001, 0x802006c5 micro.elf`foo(a=0, b=0) + 16 at 
micro.c:19, stop reason = breakpoint 2.1 frame #0: 0x802006c5 
micro.elf`foo(a=0, b=0) + 16 at micro.c:19

Without this change the microMIPS disassembly would be displayed in uncompact 
(MIPS) address space:

  0x8020067c <+0>:  addiusp -16
  0x8020067e <+2>:  sw     $fp, 12($sp)
  0x80200680 <+4>:  move   $fp, $sp

- thread #1: tid = 0x0001, 0x802006c4 micro.elf`foo(a=0, b=0) + 16 at 
micro.c:19, stop reason = breakpoint 2.1 frame #0: 0x802006c4 
micro.elf`foo(a=0, b=0) + 16 at micro.c:19


Repository:
  rL LLVM

http://reviews.llvm.org/D12079

Files:
  source/Core/FormatEntity.cpp
  source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
  source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  source/Target/RegisterContext.cpp
  source/Target/Target.cpp

Index: source/Target/Target.cpp
===================================================================
--- source/Target/Target.cpp
+++ source/Target/Target.cpp
@@ -2065,6 +2065,27 @@
     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)
@@ -2110,6 +2131,10 @@
     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)
Index: source/Target/RegisterContext.cpp
===================================================================
--- source/Target/RegisterContext.cpp
+++ 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 @@
 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
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1394,6 +1394,7 @@
 {
     LineTable* line_table;
     std::unique_ptr<LineSequence> sequence_ap;
+    ArchSpec arch;
 };
 
 //----------------------------------------------------------------------
@@ -1422,8 +1423,20 @@
             info->sequence_ap.reset(line_table->CreateLineSequenceContainer());
             assert(info->sequence_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.
+        */
+        lldb::addr_t file_addr = state.address;
+        if (info->arch.GetMachine() == llvm::Triple::mips || info->arch.GetMachine() == llvm::Triple::mipsel
+           || info->arch.GetMachine() == llvm::Triple::mips64 || info->arch.GetMachine() == llvm::Triple::mips64el)
+            file_addr = state.address & (~1ull);
+
         line_table->AppendLineEntryToSequence (info->sequence_ap.get(),
-                                               state.address,
+                                               file_addr,
                                                state.line,
                                                state.column,
                                                state.file,
@@ -1463,6 +1476,7 @@
                 {
                     ParseDWARFLineTableCallbackInfo info;
                     info.line_table = line_table_ap.get();
+                    GetObjectFile()->GetArchitecture(info.arch);
                     lldb::offset_t offset = cu_line_offset;
                     DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
                     if (m_debug_map_symfile)
Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
===================================================================
--- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -1814,6 +1814,10 @@
     }
 }
 
+#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,
@@ -2037,6 +2041,31 @@
                     }
                 }
             }
+
+            /*
+             * 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.
+            */
+            if ((arch.GetMachine() == llvm::Triple::mips || arch.GetMachine() == llvm::Triple::mipsel
+                || arch.GetMachine() == llvm::Triple::mips64 || arch.GetMachine() == llvm::Triple::mips64el))
+            {
+                if (IS_MICROMIPS(symbol.st_other))
+                    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
Index: source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
===================================================================
--- source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
+++ source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
@@ -684,10 +684,6 @@
             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, cpu, features_str.c_str(), flavor, *this));
@@ -709,6 +705,25 @@
             m_alternate_disasm_ap.reset();
         }
     }
+    else if (arch.GetTriple().getArch() == llvm::Triple::mips
+            || arch.GetTriple().getArch() == llvm::Triple::mipsel
+            || arch.GetTriple().getArch() == llvm::Triple::mips64
+            || arch.GetTriple().getArch() == 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, cpu, features_str.c_str(), flavor, *this));
+        if (!m_alternate_disasm_ap->IsValid())
+        {
+            m_disasm_ap.reset();
+            m_alternate_disasm_ap.reset();
+        }
+    }
 }
 
 DisassemblerLLVMC::~DisassemblerLLVMC()
Index: source/Core/FormatEntity.cpp
===================================================================
--- source/Core/FormatEntity.cpp
+++ source/Core/FormatEntity.cpp
@@ -418,10 +418,15 @@
 {
     Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
     addr_t vaddr = LLDB_INVALID_ADDRESS;
+
+    // If the address belongs to eAddressClassCodeAlternateISA then
+    // dump its callable form.
+    Address callable_addr (addr.GetCallableLoadAddress(target));
+
     if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
-        vaddr = addr.GetLoadAddress (target);
+        vaddr = callable_addr.GetLoadAddress (target);
     if (vaddr == LLDB_INVALID_ADDRESS)
-        vaddr = addr.GetFileAddress ();
+        vaddr = callable_addr.GetFileAddress ();
 
     if (vaddr != LLDB_INVALID_ADDRESS)
     {
@@ -437,7 +442,7 @@
             ExecutionContextScope *exe_scope = NULL;
             if (exe_ctx)
                 exe_scope = exe_ctx->GetBestExecutionContextScope();
-            addr.Dump (&s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, 0);
+            callable_addr.Dump (&s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, 0);
         }
         else
         {
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to