[Lldb-commits] [lldb] r196808 - Handle endianness in the Opcode class

Ed Maste emaste at freebsd.org
Mon Dec 9 11:45:33 PST 2013


Author: emaste
Date: Mon Dec  9 13:45:33 2013
New Revision: 196808

URL: http://llvm.org/viewvc/llvm-project?rev=196808&view=rev
Log:
Handle endianness in the Opcode class

Previously, an opcode set via SetOpcode32 (for example) was later
extracted via GetData() as a byte sequence in host order rather than
target order.

Review: http://llvm-reviews.chandlerc.com/D1838

Modified:
    lldb/trunk/include/lldb/Core/Opcode.h
    lldb/trunk/source/Core/Disassembler.cpp
    lldb/trunk/source/Core/Opcode.cpp
    lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
    lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp

Modified: lldb/trunk/include/lldb/Core/Opcode.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Opcode.h?rev=196808&r1=196807&r2=196808&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Opcode.h (original)
+++ lldb/trunk/include/lldb/Core/Opcode.h Mon Dec  9 13:45:33 2013
@@ -15,7 +15,9 @@
 
 // C++ Includes
 // Other libraries and framework includes
+#include "llvm/Support/MathExtras.h"
 // Project includes
+#include "lldb/Host/Endian.h"
 #include "lldb/lldb-public.h"
 
 namespace lldb
@@ -39,31 +41,31 @@ namespace lldb_private {
             eTypeBytes
         };
 
-        Opcode () : m_type (eTypeInvalid)
+        Opcode () : m_byte_order (lldb::eByteOrderInvalid), m_type (eTypeInvalid)
         {
         }
 
-        Opcode (uint8_t inst) : m_type (eType8)
+        Opcode (uint8_t inst, lldb::ByteOrder order) : m_byte_order (order), m_type (eType8)
         {
             m_data.inst8 = inst;
         }
 
-        Opcode (uint16_t inst) : m_type (eType16)
+        Opcode (uint16_t inst, lldb::ByteOrder order) : m_byte_order (order), m_type (eType16)
         {
             m_data.inst16 = inst;
         }
 
-        Opcode (uint32_t inst) : m_type (eType32)
+        Opcode (uint32_t inst, lldb::ByteOrder order) : m_byte_order (order), m_type (eType32)
         {
             m_data.inst32 = inst;
         }
 
-        Opcode (uint64_t inst) : m_type (eType64)
+        Opcode (uint64_t inst, lldb::ByteOrder order) : m_byte_order (order), m_type (eType64)
         {
             m_data.inst64 = inst;
         }
 
-        Opcode (uint8_t *bytes, size_t length)
+        Opcode (uint8_t *bytes, size_t length) : m_byte_order (lldb::eByteOrderInvalid)
         {
             SetOpcodeBytes (bytes, length);
         }
@@ -71,6 +73,7 @@ namespace lldb_private {
         void
         Clear()
         {
+            m_byte_order = lldb::eByteOrderInvalid;
             m_type = Opcode::eTypeInvalid;
         }
         Opcode::Type
@@ -102,7 +105,7 @@ namespace lldb_private {
             {
             case Opcode::eTypeInvalid:  break;
             case Opcode::eType8:        return m_data.inst8;
-            case Opcode::eType16:       return m_data.inst16;
+            case Opcode::eType16:       return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
             case Opcode::eType16_2:     break;
             case Opcode::eType32:       break;
             case Opcode::eType64:       break;
@@ -118,9 +121,9 @@ namespace lldb_private {
             {
             case Opcode::eTypeInvalid:  break;
             case Opcode::eType8:        return m_data.inst8;
-            case Opcode::eType16:       return m_data.inst16;
+            case Opcode::eType16:       return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
             case Opcode::eType16_2:     // passthrough
-            case Opcode::eType32:       return m_data.inst32;
+            case Opcode::eType32:       return GetEndianSwap() ? llvm::ByteSwap_32(m_data.inst32) : m_data.inst32;
             case Opcode::eType64:       break;
             case Opcode::eTypeBytes:    break;
             }
@@ -134,48 +137,53 @@ namespace lldb_private {
             {
             case Opcode::eTypeInvalid:  break;
             case Opcode::eType8:        return m_data.inst8;
-            case Opcode::eType16:       return m_data.inst16;
+            case Opcode::eType16:       return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
             case Opcode::eType16_2:     // passthrough
-            case Opcode::eType32:       return m_data.inst32;
-            case Opcode::eType64:       return m_data.inst64;
+            case Opcode::eType32:       return GetEndianSwap() ? llvm::ByteSwap_32(m_data.inst32) : m_data.inst32;
+            case Opcode::eType64:       return GetEndianSwap() ? llvm::ByteSwap_64(m_data.inst64) : m_data.inst64;
             case Opcode::eTypeBytes:    break;
             }
             return invalid_opcode;
         }
 
         void
-        SetOpcode8 (uint8_t inst)
+        SetOpcode8 (uint8_t inst, lldb::ByteOrder order)
         {
             m_type = eType8;
             m_data.inst8 = inst;
+            m_byte_order = order;
         }
 
         void
-        SetOpcode16 (uint16_t inst)
+        SetOpcode16 (uint16_t inst, lldb::ByteOrder order)
         {
             m_type = eType16;
             m_data.inst16 = inst;
+            m_byte_order = order;
         }
 
         void
-        SetOpcode16_2 (uint32_t inst)
+        SetOpcode16_2 (uint32_t inst, lldb::ByteOrder order)
         {
             m_type = eType16_2;
             m_data.inst32 = inst;
+            m_byte_order = order;
         }
 
         void
-        SetOpcode32 (uint32_t inst)
+        SetOpcode32 (uint32_t inst, lldb::ByteOrder order)
         {
             m_type = eType32;
             m_data.inst32 = inst;
+            m_byte_order = order;
         }
 
         void
-        SetOpcode64 (uint64_t inst)
+        SetOpcode64 (uint64_t inst, lldb::ByteOrder order)
         {
             m_type = eType64;
             m_data.inst64 = inst;
+            m_byte_order = order;
         }
 
         void
@@ -187,6 +195,7 @@ namespace lldb_private {
                 m_data.inst.length = length;
                 assert (length < sizeof (m_data.inst.bytes));
                 memcpy (m_data.inst.bytes, bytes, length);
+                m_byte_order = lldb::eByteOrderInvalid;
             }
             else
             {
@@ -249,6 +258,15 @@ namespace lldb_private {
         lldb::ByteOrder
         GetDataByteOrder () const;
 
+        bool
+        GetEndianSwap() const
+        {
+            return (m_byte_order == lldb::eByteOrderBig && lldb::endian::InlHostByteOrder() == lldb::eByteOrderLittle) ||
+                   (m_byte_order == lldb::eByteOrderLittle && lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig);
+        }
+
+        lldb::ByteOrder m_byte_order;
+
         Opcode::Type m_type;
         union
         {

Modified: lldb/trunk/source/Core/Disassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Disassembler.cpp?rev=196808&r1=196807&r2=196808&view=diff
==============================================================================
--- lldb/trunk/source/Core/Disassembler.cpp (original)
+++ lldb/trunk/source/Core/Disassembler.cpp Mon Dec  9 13:45:33 2013
@@ -1236,25 +1236,25 @@ PseudoInstruction::SetOpcode (size_t opc
         case 8:
         {
             uint8_t value8 = *((uint8_t *) opcode_data);
-            m_opcode.SetOpcode8 (value8);
+            m_opcode.SetOpcode8 (value8, eByteOrderInvalid);
             break;
          }   
         case 16:
         {
             uint16_t value16 = *((uint16_t *) opcode_data);
-            m_opcode.SetOpcode16 (value16);
+            m_opcode.SetOpcode16 (value16, eByteOrderInvalid);
             break;
          }   
         case 32:
         {
             uint32_t value32 = *((uint32_t *) opcode_data);
-            m_opcode.SetOpcode32 (value32);
+            m_opcode.SetOpcode32 (value32, eByteOrderInvalid);
             break;
          }   
         case 64:
         {
             uint64_t value64 = *((uint64_t *) opcode_data);
-            m_opcode.SetOpcode64 (value64);
+            m_opcode.SetOpcode64 (value64, eByteOrderInvalid);
             break;
          }   
         default:

Modified: lldb/trunk/source/Core/Opcode.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Opcode.cpp?rev=196808&r1=196807&r2=196808&view=diff
==============================================================================
--- lldb/trunk/source/Core/Opcode.cpp (original)
+++ lldb/trunk/source/Core/Opcode.cpp Mon Dec  9 13:45:33 2013
@@ -71,6 +71,10 @@ Opcode::Dump (Stream *s, uint32_t min_by
 lldb::ByteOrder
 Opcode::GetDataByteOrder () const
 {
+    if (m_byte_order != eByteOrderInvalid)
+    {
+        return m_byte_order;
+    }
     switch (m_type)
     {
         case Opcode::eTypeInvalid: break;
@@ -89,39 +93,66 @@ uint32_t
 Opcode::GetData (DataExtractor &data) const
 {
     uint32_t byte_size = GetByteSize ();
+    uint8_t swap_buf[8];
+    const void *buf = NULL;
 
-    DataBufferSP buffer_sp;
     if (byte_size > 0)
     {
-        switch (m_type)
+        if (!GetEndianSwap())
         {
-            case Opcode::eTypeInvalid:
-                break;
-
-            case Opcode::eType8:    buffer_sp.reset (new DataBufferHeap (&m_data.inst8,  byte_size)); break;
-            case Opcode::eType16:   buffer_sp.reset (new DataBufferHeap (&m_data.inst16, byte_size)); break;
-            case Opcode::eType16_2:
-                {
-                    // 32 bit thumb instruction, we need to sizzle this a bit
-                    uint8_t buf[4];
-                    buf[0] = m_data.inst.bytes[2];
-                    buf[1] = m_data.inst.bytes[3];
-                    buf[2] = m_data.inst.bytes[0];
-                    buf[3] = m_data.inst.bytes[1];
-                    buffer_sp.reset (new DataBufferHeap (buf, byte_size));
-                }
-                break;
-            case Opcode::eType32:
-                buffer_sp.reset (new DataBufferHeap (&m_data.inst32, byte_size));
-                break;
-            case Opcode::eType64:   buffer_sp.reset (new DataBufferHeap (&m_data.inst64, byte_size)); break;
-            case Opcode::eTypeBytes:buffer_sp.reset (new DataBufferHeap (GetOpcodeBytes(), byte_size)); break;
-                break;
+            if (m_type == Opcode::eType16_2)
+            {
+                // 32 bit thumb instruction, we need to sizzle this a bit
+                swap_buf[0] = m_data.inst.bytes[2];
+                swap_buf[1] = m_data.inst.bytes[3];
+                swap_buf[2] = m_data.inst.bytes[0];
+                swap_buf[3] = m_data.inst.bytes[1];
+                buf = swap_buf;
+            }
+            else
+            {
+                buf = GetOpcodeDataBytes();
+            }
+        }
+        else
+        {
+            switch (m_type)
+            {
+                case Opcode::eTypeInvalid:
+                    break;
+                case Opcode::eType8:
+                    buf = GetOpcodeDataBytes();
+                    break;
+                case Opcode::eType16:
+                    *(uint16_t *)swap_buf = llvm::ByteSwap_16(m_data.inst16);
+                    buf = swap_buf;
+                    break;
+                case Opcode::eType16_2:
+                    swap_buf[0] = m_data.inst.bytes[1];
+                    swap_buf[1] = m_data.inst.bytes[0];
+                    swap_buf[2] = m_data.inst.bytes[3];
+                    swap_buf[3] = m_data.inst.bytes[2];
+                    buf = swap_buf;
+                    break;
+                case Opcode::eType32:
+                    *(uint32_t *)swap_buf = llvm::ByteSwap_32(m_data.inst32);
+                    buf = swap_buf;
+                    break;
+                case Opcode::eType64:
+                    *(uint32_t *)swap_buf = llvm::ByteSwap_64(m_data.inst64);
+                    buf = swap_buf;
+                    break;
+                case Opcode::eTypeBytes:
+                    buf = GetOpcodeDataBytes();
+                    break;
+            }
         }
     }
-
-    if (buffer_sp)
+    if (buf)
     {
+        DataBufferSP buffer_sp;
+
+        buffer_sp.reset (new DataBufferHeap (buf, byte_size));
         data.SetByteOrder(GetDataByteOrder());
         data.SetData (buffer_sp);
         return byte_size;

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=196808&r1=196807&r2=196808&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp (original)
+++ lldb/trunk/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp Mon Dec  9 13:45:33 2013
@@ -128,6 +128,7 @@ public:
         bool got_op = false;
         DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
         const ArchSpec &arch = llvm_disasm.GetArchitecture();
+        const lldb::ByteOrder byte_order = data.GetByteOrder();
         
         const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize();
         const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize();
@@ -136,26 +137,26 @@ public:
             // Fixed size instructions, just read that amount of data.
             if (!data.ValidOffsetForDataOfSize(data_offset, min_op_byte_size))
                 return false;
-            
+
             switch (min_op_byte_size)
             {
                 case 1:
-                    m_opcode.SetOpcode8  (data.GetU8  (&data_offset));
+                    m_opcode.SetOpcode8  (data.GetU8  (&data_offset), byte_order);
                     got_op = true;
                     break;
 
                 case 2:
-                    m_opcode.SetOpcode16 (data.GetU16 (&data_offset));
+                    m_opcode.SetOpcode16 (data.GetU16 (&data_offset), byte_order);
                     got_op = true;
                     break;
 
                 case 4:
-                    m_opcode.SetOpcode32 (data.GetU32 (&data_offset));
+                    m_opcode.SetOpcode32 (data.GetU32 (&data_offset), byte_order);
                     got_op = true;
                     break;
 
                 case 8:
-                    m_opcode.SetOpcode64 (data.GetU64 (&data_offset));
+                    m_opcode.SetOpcode64 (data.GetU64 (&data_offset), byte_order);
                     got_op = true;
                     break;
 
@@ -178,20 +179,20 @@ public:
                     uint32_t thumb_opcode = data.GetU16(&data_offset);
                     if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
                     {
-                        m_opcode.SetOpcode16 (thumb_opcode);
+                        m_opcode.SetOpcode16 (thumb_opcode, byte_order);
                         m_is_valid = true;
                     }
                     else
                     {
                         thumb_opcode <<= 16;
                         thumb_opcode |= data.GetU16(&data_offset);
-                        m_opcode.SetOpcode16_2 (thumb_opcode);
+                        m_opcode.SetOpcode16_2 (thumb_opcode, byte_order);
                         m_is_valid = true;
                     }
                 }
                 else
                 {
-                    m_opcode.SetOpcode32 (data.GetU32(&data_offset));
+                    m_opcode.SetOpcode32 (data.GetU32(&data_offset), byte_order);
                     m_is_valid = true;
                 }
             }
@@ -304,12 +305,13 @@ public:
                 inst_size = m_opcode.GetByteSize();
                 StreamString mnemonic_strm;
                 lldb::offset_t offset = 0;
+                lldb::ByteOrder byte_order = data.GetByteOrder();
                 switch (inst_size)
                 {
                     case 1:
                         {
                             const uint8_t uval8 = data.GetU8 (&offset);
-                            m_opcode.SetOpcode8 (uval8);
+                            m_opcode.SetOpcode8 (uval8, byte_order);
                             m_opcode_name.assign (".byte");
                             mnemonic_strm.Printf("0x%2.2x", uval8);
                         }
@@ -317,7 +319,7 @@ public:
                     case 2:
                         {
                             const uint16_t uval16 = data.GetU16(&offset);
-                            m_opcode.SetOpcode16(uval16);
+                            m_opcode.SetOpcode16(uval16, byte_order);
                             m_opcode_name.assign (".short");
                             mnemonic_strm.Printf("0x%4.4x", uval16);
                         }
@@ -325,7 +327,7 @@ public:
                     case 4:
                         {
                             const uint32_t uval32 = data.GetU32(&offset);
-                            m_opcode.SetOpcode32(uval32);
+                            m_opcode.SetOpcode32(uval32, byte_order);
                             m_opcode_name.assign (".long");
                             mnemonic_strm.Printf("0x%8.8x", uval32);
                         }
@@ -333,7 +335,7 @@ public:
                     case 8:
                         {
                             const uint64_t uval64 = data.GetU64(&offset);
-                            m_opcode.SetOpcode64(uval64);
+                            m_opcode.SetOpcode64(uval64, byte_order);
                             m_opcode_name.assign (".quad");
                             mnemonic_strm.Printf("0x%16.16" PRIx64, uval64);
                         }

Modified: lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp?rev=196808&r1=196807&r2=196808&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp Mon Dec  9 13:45:33 2013
@@ -12889,18 +12889,18 @@ EmulateInstructionARM::ReadInstruction (
                 {
                     if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
                     {
-                        m_opcode.SetOpcode16 (thumb_opcode);
+                        m_opcode.SetOpcode16 (thumb_opcode, GetByteOrder());
                     }
                     else
                     {
-                        m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success));
+                        m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success), GetByteOrder());
                     }
                 }
             }
             else
             {
                 m_opcode_mode = eModeARM;
-                m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success));
+                m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder());
             }
         }
     }
@@ -13510,15 +13510,15 @@ EmulateInstructionARM::TestEmulation (St
     if (arch.GetTriple().getArch() == llvm::Triple::arm)
     {
         m_opcode_mode = eModeARM;
-        m_opcode.SetOpcode32 (test_opcode);
+        m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
     }
     else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
     {
         m_opcode_mode = eModeThumb;
         if (test_opcode < 0x10000)
-            m_opcode.SetOpcode16 (test_opcode);
+            m_opcode.SetOpcode16 (test_opcode, GetByteOrder());
         else
-            m_opcode.SetOpcode32 (test_opcode);
+            m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
 
     }
     else





More information about the lldb-commits mailing list