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

Addressed review comments.
Address conversions are handled in Address class. This is a reduced version of 
the original patch where address conversions are handled for breakpoints only.


Repository:
  rL LLVM

http://reviews.llvm.org/D12079

Files:
  include/lldb/Core/Address.h
  include/lldb/Symbol/Function.h
  source/Breakpoint/BreakpointResolver.cpp
  source/Breakpoint/BreakpointResolverName.cpp
  source/Core/Address.cpp
  source/Core/AddressResolverName.cpp
  source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
  source/Symbol/Function.cpp
  source/Symbol/SymbolContext.cpp
  source/Target/RegisterContext.cpp
  source/Target/Target.cpp
  source/Target/ThreadPlanStepInRange.cpp

Index: source/Target/ThreadPlanStepInRange.cpp
===================================================================
--- source/Target/ThreadPlanStepInRange.cpp
+++ source/Target/ThreadPlanStepInRange.cpp
@@ -283,7 +283,7 @@
                 {
                     func_start_address = sc.function->GetAddressRange().GetBaseAddress();
                     if (curr_addr == func_start_address.GetLoadAddress(m_thread.CalculateTarget().get()))
-                        bytes_to_skip = sc.function->GetPrologueByteSize();
+                        bytes_to_skip = sc.function->GetPrologueByteSize(m_thread.CalculateTarget().get());
                 }
                 else if (sc.symbol)
                 {
Index: source/Target/Target.cpp
===================================================================
--- source/Target/Target.cpp
+++ source/Target/Target.cpp
@@ -2065,6 +2065,31 @@
     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 eAddressClassRuntime:
+        case eAddressClassCodeAlternateISA:
+            {
+                uint32_t arch_flags = m_arch.GetFlags ();
+                if ((arch_flags & ArchSpec::eMIPSAse_micromips) ||
+                    (arch_flags & ArchSpec::eMIPSAse_mips16))
+                    code_addr |= 1ull;
+                break;
+            }
+        }
+        break;
+
     case llvm::Triple::arm:
     case llvm::Triple::thumb:
         switch (addr_class)
@@ -2110,6 +2135,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
@@ -103,7 +103,17 @@
 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();
+        Target *target = target_sp.get();
+        Address addr (pc);
+        pc = addr.GetOpcodeLoadAddress (target);
+    }
+
+    return pc;
 }
 
 bool
Index: source/Symbol/SymbolContext.cpp
===================================================================
--- source/Symbol/SymbolContext.cpp
+++ source/Symbol/SymbolContext.cpp
@@ -23,6 +23,7 @@
 #include "lldb/Symbol/SymbolVendor.h"
 #include "lldb/Symbol/Variable.h"
 #include "lldb/Target/Target.h"
+#include "lldb/Target/ExecutionContext.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -173,7 +174,14 @@
         
         if (addr.IsValid())
         {
-            const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset();
+            Target *target = nullptr;
+            if (exe_scope)
+            {
+                ExecutionContext exe_ctx;
+                exe_scope->CalculateExecutionContext (exe_ctx);
+                target = Target::GetTargetFromContexts (&exe_ctx, this);
+            }
+            const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetCallableFileAddress(target).GetOffset();
             if (show_function_name == false)
             {
                 // Print +offset even if offset is 0
Index: source/Symbol/Function.cpp
===================================================================
--- source/Symbol/Function.cpp
+++ source/Symbol/Function.cpp
@@ -555,7 +555,7 @@
 }
 
 uint32_t
-Function::GetPrologueByteSize ()
+Function::GetPrologueByteSize (Target *target)
 {
     if (m_prologue_byte_size == 0 && m_flags.IsClear(flagsCalculatedPrologueSize))
     {
@@ -565,7 +565,14 @@
         {
             LineEntry first_line_entry;
             uint32_t first_line_entry_idx = UINT32_MAX;
-            if (line_table->FindLineEntryByAddress(GetAddressRange().GetBaseAddress(), first_line_entry, &first_line_entry_idx))
+
+            /*
+             * MIPS:
+             * The .debug_line section contains compressed addresses (bit #0 set), use callable
+             * file address to find the correct entry.
+            */
+            if (line_table->FindLineEntryByAddress(GetAddressRange().GetBaseAddress().GetCallableFileAddress(target),
+                first_line_entry, &first_line_entry_idx))
             {
                 // Make sure the first line entry isn't already the end of the prologue
                 addr_t prologue_end_file_addr = LLDB_INVALID_ADDRESS;
@@ -617,7 +624,7 @@
                         prologue_end_file_addr = first_line_entry.range.GetBaseAddress().GetFileAddress() + first_line_entry.range.GetByteSize();
                     }
                 }
-                const addr_t func_start_file_addr = m_range.GetBaseAddress().GetFileAddress();
+                const addr_t func_start_file_addr = m_range.GetBaseAddress().GetCallableFileAddress(target).GetFileAddress();
                 const addr_t func_end_file_addr = func_start_file_addr + m_range.GetByteSize();
 
                 // Verify that this prologue end file address in the function's
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,22 @@
                     }
                 }
             }
+
+            /*
+             * 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 (IS_MICROMIPS(symbol.st_other) && (arch.GetMachine() == llvm::Triple::mips
+                || arch.GetMachine() == llvm::Triple::mipsel || arch.GetMachine() == llvm::Triple::mips64
+                || arch.GetMachine() == llvm::Triple::mips64el))
+            {
+                m_address_class_map[symbol.st_value] = eAddressClassCodeAlternateISA;
+            }
         }
 
         // symbol_value_offset may contain 0 for ARM symbols or -1 for
Index: source/Core/AddressResolverName.cpp
===================================================================
--- source/Core/AddressResolverName.cpp
+++ source/Core/AddressResolverName.cpp
@@ -187,7 +187,7 @@
                     addr_t byte_size = sc.function->GetAddressRange().GetByteSize();
                     if (skip_prologue)
                     {
-                        const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
+                        const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize(sc.target_sp.get());
                         if (prologue_byte_size)
                         {
                             func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size);
Index: source/Core/Address.cpp
===================================================================
--- source/Core/Address.cpp
+++ source/Core/Address.cpp
@@ -387,6 +387,24 @@
     return false;
 }
 
+Address
+Address::GetCallableFileAddress (Target *target, bool is_indirect) const
+{
+    SectionSP section_sp (GetSection());
+    if (section_sp)
+    {
+        ModuleSP module_sp = section_sp->GetModule();
+        if (module_sp && target)
+        {
+            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;
+}
+
 bool
 Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const
 {
Index: source/Breakpoint/BreakpointResolverName.cpp
===================================================================
--- source/Breakpoint/BreakpointResolverName.cpp
+++ source/Breakpoint/BreakpointResolverName.cpp
@@ -301,10 +301,10 @@
                 }
                 else if (sc.function)
                 {
-                    break_addr = sc.function->GetAddressRange().GetBaseAddress();
+                    break_addr = sc.function->GetAddressRange().GetBaseAddress().GetCallableFileAddress(&m_breakpoint->GetTarget());
                     if (m_skip_prologue && break_addr.IsValid())
                     {
-                        const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
+                        const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize(&m_breakpoint->GetTarget());
                         if (prologue_byte_size)
                             break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
                     }
Index: source/Breakpoint/BreakpointResolver.cpp
===================================================================
--- source/Breakpoint/BreakpointResolver.cpp
+++ source/Breakpoint/BreakpointResolver.cpp
@@ -161,7 +161,7 @@
                                 Address prologue_addr(sc.function->GetAddressRange().GetBaseAddress());
                                 if (prologue_addr.IsValid() && (line_start == prologue_addr))
                                 {
-                                    const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
+                                    const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize(&m_breakpoint->GetTarget());
                                     if (prologue_byte_size)
                                     {
                                         prologue_addr.Slide(prologue_byte_size);
Index: include/lldb/Symbol/Function.h
===================================================================
--- include/lldb/Symbol/Function.h
+++ include/lldb/Symbol/Function.h
@@ -577,7 +577,7 @@
     GetClangType ();
 
     uint32_t
-    GetPrologueByteSize ();
+    GetPrologueByteSize (Target *target = nullptr);
 
     //------------------------------------------------------------------
     /// Dump a description of this object to a Stream.
Index: include/lldb/Core/Address.h
===================================================================
--- include/lldb/Core/Address.h
+++ include/lldb/Core/Address.h
@@ -308,6 +308,9 @@
     lldb::addr_t
     GetCallableLoadAddress (Target *target, bool is_indirect = false) const;
 
+    Address
+    GetCallableFileAddress (Target *target, bool is_indirect = false) const;
+
     //------------------------------------------------------------------
     /// Get the load address as an opcode load address.
     ///
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to