[haiku-commits] haiku: hrev45132 - in src/apps/debugger/arch/x86_64/disasm: . src/apps/debugger/arch/x86_64

  • From: anevilyak@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 6 Jan 2013 17:44:55 +0100 (CET)

hrev45132 adds 2 changesets to branch 'master'
old head: 89deb8f2736fce8293219220dc53e00c1cf868ef
new head: dcce0a030b641349a6d63126b7e7790d17704431
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=dcce0a0+%5E89deb8f

----------------------------------------------------------------------------

59fcd81: Return an error if no frames were created.

dcce0a0: Adapt x86-64 to also use udis86-based instruction analysis.

                                      [ Rene Gollent <anevilyak@xxxxxxxxx> ]

----------------------------------------------------------------------------

5 files changed, 140 insertions(+), 33 deletions(-)
src/apps/debugger/arch/Architecture.cpp          |   3 +
.../debugger/arch/x86_64/ArchitectureX8664.cpp   |  35 +-----
.../arch/x86_64/disasm/DisassemblerX8664.cpp     | 122 +++++++++++++++++++
.../arch/x86_64/disasm/DisassemblerX8664.h       |  10 ++
src/apps/debugger/arch/x86_64/disasm/Jamfile     |   3 +

############################################################################

Commit:      59fcd81013a8af64c0c6b7d7915b729b38ae3b85
URL:         http://cgit.haiku-os.org/haiku/commit/?id=59fcd81
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Sun Jan  6 16:42:58 2013 UTC

Return an error if no frames were created.

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/arch/Architecture.cpp 
b/src/apps/debugger/arch/Architecture.cpp
index c1724f7..42fd88e 100644
--- a/src/apps/debugger/arch/Architecture.cpp
+++ b/src/apps/debugger/arch/Architecture.cpp
@@ -194,6 +194,9 @@ Architecture::CreateStackTrace(Team* team,
                        break;
        }
 
+       if (stackTrace->CountFrames() == 0)
+               return B_ERROR;
+
        stackTraceDeleter.Detach();
        _stackTrace = stackTrace;
        return B_OK;

############################################################################

Revision:    hrev45132
Commit:      dcce0a030b641349a6d63126b7e7790d17704431
URL:         http://cgit.haiku-os.org/haiku/commit/?id=dcce0a0
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Sun Jan  6 16:43:41 2013 UTC

Adapt x86-64 to also use udis86-based instruction analysis.

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp 
b/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp
index 05ba2a4..3c27c87 100644
--- a/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp
+++ b/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp
@@ -470,9 +470,8 @@ status_t
 ArchitectureX8664::GetInstructionInfo(target_addr_t address,
        InstructionInfo& _info, CpuState* state)
 {
-       // read the code
+       // read the code - maximum x86{-64} instruction size = 15 bytes
        uint8 buffer[16];
-               // TODO: What's the maximum instruction size?
        ssize_t bytesRead = fTeamMemory->ReadMemory(address, buffer,
                sizeof(buffer));
        if (bytesRead < 0)
@@ -484,37 +483,7 @@ ArchitectureX8664::GetInstructionInfo(target_addr_t 
address,
        if (error != B_OK)
                return error;
 
-       // disassemble the instruction
-       BString line;
-       target_addr_t instructionAddress;
-       target_addr_t targetAddress = 0;
-       target_size_t instructionSize;
-       bool breakpointAllowed;
-       error = disassembler.GetNextInstruction(line, instructionAddress,
-               instructionSize, breakpointAllowed);
-       if (error != B_OK)
-               return error;
-
-       // FIXME: Is this correct for x86_64? I'm not entirely sure.
-       instruction_type instructionType = INSTRUCTION_TYPE_OTHER;
-       if (buffer[0] == 0xff && (buffer[1] & 0x34) == 0x10) {
-               // absolute call with r/m32
-               instructionType = INSTRUCTION_TYPE_SUBROUTINE_CALL;
-       } else if (buffer[0] == 0xe8 && instructionSize == 5) {
-               // relative call with rel32 -- don't categorize the call with 0 
as
-               // subroutine call, since it is only used to get the address of 
the GOT
-               if (buffer[1] != 0 || buffer[2] != 0 || buffer[3] != 0
-                       || buffer[4] != 0) {
-                       instructionType = INSTRUCTION_TYPE_SUBROUTINE_CALL;
-               }
-       }
-
-       if (!_info.SetTo(instructionAddress, targetAddress, instructionSize,
-                       instructionType, breakpointAllowed, line)) {
-               return B_NO_MEMORY;
-       }
-
-       return B_OK;
+       return disassembler.GetNextInstructionInfo(_info, state);
 }
 
 
diff --git a/src/apps/debugger/arch/x86_64/disasm/DisassemblerX8664.cpp 
b/src/apps/debugger/arch/x86_64/disasm/DisassemblerX8664.cpp
index 7122943..07424ce 100644
--- a/src/apps/debugger/arch/x86_64/disasm/DisassemblerX8664.cpp
+++ b/src/apps/debugger/arch/x86_64/disasm/DisassemblerX8664.cpp
@@ -14,6 +14,46 @@
 #include <OS.h>
 
 
+#include "CpuStateX8664.h"
+#include "InstructionInfo.h"
+
+
+static uint8 RegisterNumberFromUdisIndex(int32 udisIndex)
+{
+       switch (udisIndex) {
+               case UD_R_RIP: return X86_64_REGISTER_RIP;
+               case UD_R_RSP: return X86_64_REGISTER_RSP;
+               case UD_R_RBP: return X86_64_REGISTER_RBP;
+
+               case UD_R_RAX: return X86_64_REGISTER_RAX;
+               case UD_R_RBX: return X86_64_REGISTER_RBX;
+               case UD_R_RCX: return X86_64_REGISTER_RCX;
+               case UD_R_RDX: return X86_64_REGISTER_RDX;
+
+               case UD_R_RSI: return X86_64_REGISTER_RSI;
+               case UD_R_RDI: return X86_64_REGISTER_RDI;
+
+               case UD_R_R8: return X86_64_REGISTER_R8;
+               case UD_R_R9: return X86_64_REGISTER_R9;
+               case UD_R_R10: return X86_64_REGISTER_R10;
+               case UD_R_R11: return X86_64_REGISTER_R11;
+               case UD_R_R12: return X86_64_REGISTER_R12;
+               case UD_R_R13: return X86_64_REGISTER_R13;
+               case UD_R_R14: return X86_64_REGISTER_R14;
+               case UD_R_R15: return X86_64_REGISTER_R15;
+
+               case UD_R_CS: return X86_64_REGISTER_CS;
+               case UD_R_DS: return X86_64_REGISTER_DS;
+               case UD_R_ES: return X86_64_REGISTER_ES;
+               case UD_R_FS: return X86_64_REGISTER_FS;
+               case UD_R_GS: return X86_64_REGISTER_GS;
+               case UD_R_SS: return X86_64_REGISTER_SS;
+       }
+
+       return X86_64_INT_REGISTER_END;
+}
+
+
 struct DisassemblerX8664::UdisData : ud_t {
 };
 
@@ -109,3 +149,85 @@ DisassemblerX8664::GetPreviousInstruction(target_addr_t 
nextAddress,
                }
        }
 }
+
+
+status_t
+DisassemblerX8664::GetNextInstructionInfo(InstructionInfo& _info,
+       CpuState* state)
+{
+       unsigned int size = ud_disassemble(fUdisData);
+       if (size < 1)
+               return B_ENTRY_NOT_FOUND;
+
+       uint32 address = (uint32)ud_insn_off(fUdisData);
+
+       instruction_type type = INSTRUCTION_TYPE_OTHER;
+       target_addr_t targetAddress = 0;
+
+       if (fUdisData->mnemonic == UD_Icall)
+               type = INSTRUCTION_TYPE_SUBROUTINE_CALL;
+       else if (fUdisData->mnemonic == UD_Ijmp)
+               type = INSTRUCTION_TYPE_JUMP;
+       if (state != NULL)
+               targetAddress = GetInstructionTargetAddress(state);
+
+       char buffer[256];
+       snprintf(buffer, sizeof(buffer), "0x%08" B_PRIx32 ": %16.16s  %s", 
address,
+               ud_insn_hex(fUdisData), ud_insn_asm(fUdisData));
+                       // TODO: Resolve symbols!
+
+       if (!_info.SetTo(address, targetAddress, size, type, true, buffer))
+               return B_NO_MEMORY;
+
+       return B_OK;
+}
+
+
+target_addr_t
+DisassemblerX8664::GetInstructionTargetAddress(CpuState* state) const
+{
+       if (fUdisData->mnemonic != UD_Icall && fUdisData->mnemonic != UD_Ijmp)
+               return 0;
+
+       CpuStateX8664* x64State = dynamic_cast<CpuStateX8664*>(state);
+       if (x64State == NULL)
+               return 0;
+
+       target_addr_t targetAddress = 0;
+       switch (fUdisData->operand[0].type) {
+               case UD_OP_REG:
+               {
+                       targetAddress = x64State->IntRegisterValue(
+                               
RegisterNumberFromUdisIndex(fUdisData->operand[0].base));
+                       targetAddress += fUdisData->operand[0].offset;
+               }
+               break;
+               case UD_OP_MEM:
+               {
+                       targetAddress = x64State->IntRegisterValue(
+                               
RegisterNumberFromUdisIndex(fUdisData->operand[0].base));
+                       targetAddress += x64State->IntRegisterValue(
+                               
RegisterNumberFromUdisIndex(fUdisData->operand[0].index))
+                               * fUdisData->operand[0].scale;
+               }
+               break;
+               case UD_OP_JIMM:
+               {
+                       targetAddress = ud_insn_off(fUdisData)
+                               + fUdisData->operand[0].lval.sdword + 
ud_insn_len(fUdisData);
+               }
+               break;
+
+               case UD_OP_IMM:
+               case UD_OP_CONST:
+               {
+                       targetAddress = fUdisData->operand[0].lval.udword;
+               }
+               break;
+
+               default:
+               break;
+       }
+
+       return targetAddress;
+}
diff --git a/src/apps/debugger/arch/x86_64/disasm/DisassemblerX8664.h 
b/src/apps/debugger/arch/x86_64/disasm/DisassemblerX8664.h
index af045f4..9a61a95 100644
--- a/src/apps/debugger/arch/x86_64/disasm/DisassemblerX8664.h
+++ b/src/apps/debugger/arch/x86_64/disasm/DisassemblerX8664.h
@@ -11,6 +11,10 @@
 #include "Types.h"
 
 
+class CpuState;
+class InstructionInfo;
+
+
 class DisassemblerX8664 {
 public:
                                                                
DisassemblerX8664();
@@ -27,8 +31,14 @@ public:
                                                                        
target_addr_t nextAddress,
                                                                        
target_addr_t& _address,
                                                                        
target_size_t& _size);
+       virtual status_t                        GetNextInstructionInfo(
+                                                                       
InstructionInfo& _info,
+                                                                       
CpuState* state);
 
 private:
+                       target_addr_t           GetInstructionTargetAddress(
+                                                                       
CpuState* state) const;
+private:
                        struct UdisData;
 
 private:
diff --git a/src/apps/debugger/arch/x86_64/disasm/Jamfile 
b/src/apps/debugger/arch/x86_64/disasm/Jamfile
index 7abcbb2..7424d3d 100644
--- a/src/apps/debugger/arch/x86_64/disasm/Jamfile
+++ b/src/apps/debugger/arch/x86_64/disasm/Jamfile
@@ -3,9 +3,12 @@ SubDir HAIKU_TOP src apps debugger arch x86_64 disasm ;
 CCFLAGS +=  -Werror ;
 C++FLAGS += -Werror ;
 
+UsePrivateHeaders shared ;
+
 UseHeaders [ LibraryHeaders udis86 ] ;
 UseHeaders [ LibraryHeaders [ FDirName udis86 libudis86 ] ] ;
 
+SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ;
 SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ;
 SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) $(DOTDOT) types ] ;
 


Other related posts:

  • » [haiku-commits] haiku: hrev45132 - in src/apps/debugger/arch/x86_64/disasm: . src/apps/debugger/arch/x86_64 - anevilyak