Add support for byte swapping to the memory inspector.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42238 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Rene Gollent
2011-06-18 22:24:00 +00:00
parent 07fb28e3df
commit 80480954e2
5 changed files with 142 additions and 20 deletions
@@ -18,6 +18,7 @@
#include <ExpressionParser.h> #include <ExpressionParser.h>
#include "Architecture.h"
#include "MemoryView.h" #include "MemoryView.h"
#include "MessageCodes.h" #include "MessageCodes.h"
#include "Team.h" #include "Team.h"
@@ -30,7 +31,8 @@ enum {
}; };
InspectorWindow::InspectorWindow(::Team* team, UserInterfaceListener* listener) InspectorWindow::InspectorWindow(::Team* team, UserInterfaceListener* listener,
BHandler* target)
: :
BWindow(BRect(100, 100, 700, 500), "Inspector", B_TITLED_WINDOW, BWindow(BRect(100, 100, 700, 500), "Inspector", B_TITLED_WINDOW,
B_ASYNCHRONOUS_CONTROLS), B_ASYNCHRONOUS_CONTROLS),
@@ -41,7 +43,8 @@ InspectorWindow::InspectorWindow(::Team* team, UserInterfaceListener* listener)
fMemoryView(NULL), fMemoryView(NULL),
fCurrentBlock(NULL), fCurrentBlock(NULL),
fCurrentAddress(0LL), fCurrentAddress(0LL),
fTeam(team) fTeam(team),
fTarget(target)
{ {
} }
@@ -52,9 +55,10 @@ InspectorWindow::~InspectorWindow()
/* static */ InspectorWindow* /* static */ InspectorWindow*
InspectorWindow::Create(::Team* team, UserInterfaceListener* listener) InspectorWindow::Create(::Team* team, UserInterfaceListener* listener,
BHandler* target)
{ {
InspectorWindow* self = new InspectorWindow(team, listener); InspectorWindow* self = new InspectorWindow(team, listener, target);
try { try {
self->_Init(); self->_Init();
@@ -94,6 +98,15 @@ InspectorWindow::_Init()
item = new BMenuItem("64-bit integer", message, '4'); item = new BMenuItem("64-bit integer", message, '4');
hexMenu->AddItem(item); hexMenu->AddItem(item);
BMenu* endianMenu = new BMenu("Endian Mode");
message = new BMessage(MSG_SET_ENDIAN_MODE);
message->AddInt32("mode", EndianModeLittleEndian);
item = new BMenuItem("Little Endian", message, 'L');
endianMenu->AddItem(item);
message = new BMessage(*message);
message->ReplaceInt32("mode", EndianModeBigEndian);
item = new BMenuItem("Big Endian", message, 'B');
endianMenu->AddItem(item);
BMenu* textMenu = new BMenu("Text Mode"); BMenu* textMenu = new BMenu("Text Mode");
message = new BMessage(MSG_SET_TEXT_MODE); message = new BMessage(MSG_SET_TEXT_MODE);
@@ -117,9 +130,12 @@ InspectorWindow::_Init()
new BMessage(MSG_NAVIGATE_NEXT_BLOCK))) new BMessage(MSG_NAVIGATE_NEXT_BLOCK)))
.End() .End()
.AddGroup(B_HORIZONTAL, 4.0f) .AddGroup(B_HORIZONTAL, 4.0f)
.Add(fHexMode = new BMenuField("outputStyle", "Hex Mode:", .Add(fHexMode = new BMenuField("hexMode", "Hex Mode:",
hexMenu)) hexMenu))
.AddGlue() .AddGlue()
.Add(fEndianMode = new BMenuField("endianMode", "Endian Mode:",
endianMenu))
.AddGlue()
.Add(fTextMode = new BMenuField("viewMode", "Text Mode:", .Add(fTextMode = new BMenuField("viewMode", "Text Mode:",
textMenu)) textMenu))
.End() .End()
@@ -128,9 +144,20 @@ InspectorWindow::_Init()
.End(); .End();
fHexMode->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); fHexMode->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
fEndianMode->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
fTextMode->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); fTextMode->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
scrollView->SetTarget(fMemoryView = MemoryView::Create()); Architecture* architecture = fTeam->GetArchitecture();
int32 hostEndian;
int32 targetEndian;
targetEndian = architecture->IsBigEndian() ? EndianModeBigEndian
: EndianModeLittleEndian;
hostEndian = architecture->IsHostEndian() ? targetEndian
: architecture->IsBigEndian() ? EndianModeLittleEndian
: EndianModeBigEndian;
scrollView->SetTarget(fMemoryView = MemoryView::Create(hostEndian,
targetEndian));
fAddressInput->SetTarget(this); fAddressInput->SetTarget(this);
fPreviousBlockButton->SetTarget(this); fPreviousBlockButton->SetTarget(this);
@@ -140,6 +167,8 @@ InspectorWindow::_Init()
hexMenu->SetLabelFromMarked(true); hexMenu->SetLabelFromMarked(true);
hexMenu->SetTargetForItems(fMemoryView); hexMenu->SetTargetForItems(fMemoryView);
endianMenu->SetLabelFromMarked(true);
endianMenu->SetTargetForItems(fMemoryView);
textMenu->SetLabelFromMarked(true); textMenu->SetLabelFromMarked(true);
textMenu->SetTargetForItems(fMemoryView); textMenu->SetTargetForItems(fMemoryView);
@@ -147,6 +176,11 @@ InspectorWindow::_Init()
hexMenu->ItemAt(1)->SetMarked(true); hexMenu->ItemAt(1)->SetMarked(true);
textMenu->ItemAt(1)->SetMarked(true); textMenu->ItemAt(1)->SetMarked(true);
if (architecture->IsBigEndian())
endianMenu->ItemAt(1)->SetMarked(true);
else
endianMenu->ItemAt(0)->SetMarked(true);
fAddressInput->TextView()->MakeFocus(true); fAddressInput->TextView()->MakeFocus(true);
} }
@@ -238,7 +272,7 @@ InspectorWindow::MessageReceived(BMessage* msg)
bool bool
InspectorWindow::QuitRequested() InspectorWindow::QuitRequested()
{ {
be_app_messenger.SendMessage(MSG_INSPECTOR_WINDOW_CLOSED); BMessenger(fTarget).SendMessage(MSG_INSPECTOR_WINDOW_CLOSED);
return true; return true;
} }
@@ -14,6 +14,7 @@
class BButton; class BButton;
class BMenuField; class BMenuField;
class BMessenger;
class BTextControl; class BTextControl;
class MemoryView; class MemoryView;
class Team; class Team;
@@ -24,11 +25,13 @@ class InspectorWindow : public BWindow,
public TeamMemoryBlock::Listener { public TeamMemoryBlock::Listener {
public: public:
InspectorWindow(::Team* team, InspectorWindow(::Team* team,
UserInterfaceListener* listener); UserInterfaceListener* listener,
BHandler* target);
virtual ~InspectorWindow(); virtual ~InspectorWindow();
static InspectorWindow* Create(::Team* team, static InspectorWindow* Create(::Team* team,
UserInterfaceListener* listener); UserInterfaceListener* listener,
BHandler* target);
// throws // throws
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
@@ -43,6 +46,7 @@ private:
UserInterfaceListener* fListener; UserInterfaceListener* fListener;
BTextControl* fAddressInput; BTextControl* fAddressInput;
BMenuField* fHexMode; BMenuField* fHexMode;
BMenuField* fEndianMode;
BMenuField* fTextMode; BMenuField* fTextMode;
MemoryView* fMemoryView; MemoryView* fMemoryView;
BButton* fPreviousBlockButton; BButton* fPreviousBlockButton;
@@ -50,6 +54,7 @@ private:
TeamMemoryBlock* fCurrentBlock; TeamMemoryBlock* fCurrentBlock;
target_addr_t fCurrentAddress; target_addr_t fCurrentAddress;
::Team* fTeam; ::Team* fTeam;
BHandler* fTarget;
}; };
#endif // INSPECTOR_WINDOW_H #endif // INSPECTOR_WINDOW_H
@@ -10,6 +10,7 @@
#include <stdio.h> #include <stdio.h>
#include <ByteOrder.h>
#include <Messenger.h> #include <Messenger.h>
#include <ScrollView.h> #include <ScrollView.h>
#include <String.h> #include <String.h>
@@ -22,7 +23,7 @@ enum {
}; };
MemoryView::MemoryView() MemoryView::MemoryView(int32 hostEndianMode, int32 targetEndianMode)
: :
BView("memoryView", B_WILL_DRAW | B_FRAME_EVENTS | B_SUBPIXEL_PRECISE), BView("memoryView", B_WILL_DRAW | B_FRAME_EVENTS | B_SUBPIXEL_PRECISE),
fTargetBlock(NULL), fTargetBlock(NULL),
@@ -31,6 +32,9 @@ MemoryView::MemoryView()
fLineHeight(0.0), fLineHeight(0.0),
fTextCharsPerLine(0), fTextCharsPerLine(0),
fHexBlocksPerLine(0), fHexBlocksPerLine(0),
fCurrentEndianMode(hostEndianMode),
fHostEndianMode(hostEndianMode),
fTargetEndianMode(targetEndianMode),
fHexMode(HexMode8BitInt), fHexMode(HexMode8BitInt),
fTextMode(TextModeASCII) fTextMode(TextModeASCII)
{ {
@@ -45,9 +49,9 @@ MemoryView::~MemoryView()
/*static */ MemoryView* /*static */ MemoryView*
MemoryView::Create() MemoryView::Create(int32 hostEndianMode, int32 targetEndianMode)
{ {
MemoryView* self = new MemoryView(); MemoryView* self = new MemoryView(hostEndianMode, targetEndianMode);
try { try {
self->_Init(); self->_Init();
@@ -264,6 +268,15 @@ MemoryView::MessageReceived(BMessage* message)
} }
break; break;
} }
case MSG_SET_ENDIAN_MODE:
{
int32 mode;
if (message->FindInt32("mode", &mode) == B_OK) {
fCurrentEndianMode = mode;
Invalidate();
}
break;
}
case MSG_SET_TEXT_MODE: case MSG_SET_TEXT_MODE:
{ {
int32 mode; int32 mode;
@@ -359,20 +372,71 @@ MemoryView::_GetNextHexBlock(char* buffer, int32 bufferSize,
} }
case HexMode16BitInt: case HexMode16BitInt:
{ {
uint16 data = *((const uint16*)address);
if (fCurrentEndianMode != fHostEndianMode) {
switch(fCurrentEndianMode)
{
case EndianModeBigEndian:
{
data = B_HOST_TO_BENDIAN_INT16(data);
}
break;
case EndianModeLittleEndian:
{
data = B_HOST_TO_LENDIAN_INT16(data);
}
break;
}
}
snprintf(buffer, bufferSize, "%04" B_PRIx16, snprintf(buffer, bufferSize, "%04" B_PRIx16,
*((const uint16*)address)); data);
break; break;
} }
case HexMode32BitInt: case HexMode32BitInt:
{ {
uint32 data = *((const uint32*)address);
if (fCurrentEndianMode != fHostEndianMode) {
switch(fCurrentEndianMode)
{
case EndianModeBigEndian:
{
data = B_HOST_TO_BENDIAN_INT32(data);
}
break;
case EndianModeLittleEndian:
{
data = B_HOST_TO_LENDIAN_INT32(data);
}
break;
}
}
snprintf(buffer, bufferSize, "%08" B_PRIx32, snprintf(buffer, bufferSize, "%08" B_PRIx32,
*((const uint32*)address)); data);
break; break;
} }
case HexMode64BitInt: case HexMode64BitInt:
{ {
uint64 data = *((const uint16*)address);
if (fCurrentEndianMode != fHostEndianMode) {
switch(fCurrentEndianMode)
{
case EndianModeBigEndian:
{
data = B_HOST_TO_BENDIAN_INT64(data);
}
break;
case EndianModeLittleEndian:
{
data = B_HOST_TO_LENDIAN_INT64(data);
}
break;
}
}
snprintf(buffer, bufferSize, "%0*" B_PRIx64, snprintf(buffer, bufferSize, "%0*" B_PRIx64,
16, *((const uint64*)address)); 16, data);
break; break;
} }
} }
@@ -13,8 +13,9 @@
enum { enum {
MSG_SET_HEX_MODE = 'sofm', MSG_SET_HEX_MODE = 'sehe',
MSG_SET_TEXT_MODE = 'some' MSG_SET_ENDIAN_MODE = 'seme',
MSG_SET_TEXT_MODE = 'stme'
}; };
enum { enum {
@@ -26,21 +27,31 @@ enum {
// TODO: floating point representation? // TODO: floating point representation?
}; };
enum {
EndianModeLittleEndian = 0,
EndianModeBigEndian = 1
};
enum { enum {
TextModeNone = 0, TextModeNone = 0,
TextModeASCII TextModeASCII
}; };
class Team;
class TeamMemoryBlock; class TeamMemoryBlock;
class MemoryView : public BView { class MemoryView : public BView {
public: public:
MemoryView(); MemoryView(int32 hostEndianMode,
int32 targetEndianMode);
virtual ~MemoryView(); virtual ~MemoryView();
static MemoryView* Create(); static MemoryView* Create(int32 hostEndianMode,
int32 targetEndianMode);
// throws // throws
void SetTargetAddress(TeamMemoryBlock* block, void SetTargetAddress(TeamMemoryBlock* block,
@@ -67,6 +78,9 @@ private:
float fLineHeight; float fLineHeight;
int32 fTextCharsPerLine; int32 fTextCharsPerLine;
int32 fHexBlocksPerLine; int32 fHexBlocksPerLine;
int32 fCurrentEndianMode;
int32 fHostEndianMode;
int32 fTargetEndianMode;
int32 fHexMode; int32 fHexMode;
int32 fTextMode; int32 fTextMode;
}; };
@@ -216,7 +216,8 @@ TeamWindow::MessageReceived(BMessage* message)
} }
try { try {
fInspectorWindow = InspectorWindow::Create(fTeam, fListener); fInspectorWindow = InspectorWindow::Create(fTeam, fListener,
this);
if (fInspectorWindow != NULL) if (fInspectorWindow != NULL)
fInspectorWindow->Show(); fInspectorWindow->Show();
} catch (...) { } catch (...) {
@@ -224,6 +225,10 @@ TeamWindow::MessageReceived(BMessage* message)
} }
break; break;
} }
case MSG_INSPECTOR_WINDOW_CLOSED:
{
fInspectorWindow = NULL;
}
case B_REFS_RECEIVED: case B_REFS_RECEIVED:
{ {
entry_ref locatedPath; entry_ref locatedPath;