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 "Architecture.h"
#include "MemoryView.h"
#include "MessageCodes.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,
B_ASYNCHRONOUS_CONTROLS),
@@ -41,7 +43,8 @@ InspectorWindow::InspectorWindow(::Team* team, UserInterfaceListener* listener)
fMemoryView(NULL),
fCurrentBlock(NULL),
fCurrentAddress(0LL),
fTeam(team)
fTeam(team),
fTarget(target)
{
}
@@ -52,9 +55,10 @@ InspectorWindow::~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 {
self->_Init();
@@ -94,6 +98,15 @@ InspectorWindow::_Init()
item = new BMenuItem("64-bit integer", message, '4');
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");
message = new BMessage(MSG_SET_TEXT_MODE);
@@ -117,9 +130,12 @@ InspectorWindow::_Init()
new BMessage(MSG_NAVIGATE_NEXT_BLOCK)))
.End()
.AddGroup(B_HORIZONTAL, 4.0f)
.Add(fHexMode = new BMenuField("outputStyle", "Hex Mode:",
.Add(fHexMode = new BMenuField("hexMode", "Hex Mode:",
hexMenu))
.AddGlue()
.Add(fEndianMode = new BMenuField("endianMode", "Endian Mode:",
endianMenu))
.AddGlue()
.Add(fTextMode = new BMenuField("viewMode", "Text Mode:",
textMenu))
.End()
@@ -128,9 +144,20 @@ InspectorWindow::_Init()
.End();
fHexMode->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
fEndianMode->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);
fPreviousBlockButton->SetTarget(this);
@@ -140,6 +167,8 @@ InspectorWindow::_Init()
hexMenu->SetLabelFromMarked(true);
hexMenu->SetTargetForItems(fMemoryView);
endianMenu->SetLabelFromMarked(true);
endianMenu->SetTargetForItems(fMemoryView);
textMenu->SetLabelFromMarked(true);
textMenu->SetTargetForItems(fMemoryView);
@@ -147,6 +176,11 @@ InspectorWindow::_Init()
hexMenu->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);
}
@@ -238,7 +272,7 @@ InspectorWindow::MessageReceived(BMessage* msg)
bool
InspectorWindow::QuitRequested()
{
be_app_messenger.SendMessage(MSG_INSPECTOR_WINDOW_CLOSED);
BMessenger(fTarget).SendMessage(MSG_INSPECTOR_WINDOW_CLOSED);
return true;
}
@@ -14,6 +14,7 @@
class BButton;
class BMenuField;
class BMessenger;
class BTextControl;
class MemoryView;
class Team;
@@ -24,11 +25,13 @@ class InspectorWindow : public BWindow,
public TeamMemoryBlock::Listener {
public:
InspectorWindow(::Team* team,
UserInterfaceListener* listener);
UserInterfaceListener* listener,
BHandler* target);
virtual ~InspectorWindow();
static InspectorWindow* Create(::Team* team,
UserInterfaceListener* listener);
UserInterfaceListener* listener,
BHandler* target);
// throws
virtual void MessageReceived(BMessage* message);
@@ -43,6 +46,7 @@ private:
UserInterfaceListener* fListener;
BTextControl* fAddressInput;
BMenuField* fHexMode;
BMenuField* fEndianMode;
BMenuField* fTextMode;
MemoryView* fMemoryView;
BButton* fPreviousBlockButton;
@@ -50,6 +54,7 @@ private:
TeamMemoryBlock* fCurrentBlock;
target_addr_t fCurrentAddress;
::Team* fTeam;
BHandler* fTarget;
};
#endif // INSPECTOR_WINDOW_H
@@ -10,6 +10,7 @@
#include <stdio.h>
#include <ByteOrder.h>
#include <Messenger.h>
#include <ScrollView.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),
fTargetBlock(NULL),
@@ -31,6 +32,9 @@ MemoryView::MemoryView()
fLineHeight(0.0),
fTextCharsPerLine(0),
fHexBlocksPerLine(0),
fCurrentEndianMode(hostEndianMode),
fHostEndianMode(hostEndianMode),
fTargetEndianMode(targetEndianMode),
fHexMode(HexMode8BitInt),
fTextMode(TextModeASCII)
{
@@ -45,9 +49,9 @@ MemoryView::~MemoryView()
/*static */ MemoryView*
MemoryView::Create()
MemoryView::Create(int32 hostEndianMode, int32 targetEndianMode)
{
MemoryView* self = new MemoryView();
MemoryView* self = new MemoryView(hostEndianMode, targetEndianMode);
try {
self->_Init();
@@ -264,6 +268,15 @@ MemoryView::MessageReceived(BMessage* message)
}
break;
}
case MSG_SET_ENDIAN_MODE:
{
int32 mode;
if (message->FindInt32("mode", &mode) == B_OK) {
fCurrentEndianMode = mode;
Invalidate();
}
break;
}
case MSG_SET_TEXT_MODE:
{
int32 mode;
@@ -359,20 +372,71 @@ MemoryView::_GetNextHexBlock(char* buffer, int32 bufferSize,
}
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,
*((const uint16*)address));
data);
break;
}
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,
*((const uint32*)address));
data);
break;
}
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,
16, *((const uint64*)address));
16, data);
break;
}
}
@@ -13,8 +13,9 @@
enum {
MSG_SET_HEX_MODE = 'sofm',
MSG_SET_TEXT_MODE = 'some'
MSG_SET_HEX_MODE = 'sehe',
MSG_SET_ENDIAN_MODE = 'seme',
MSG_SET_TEXT_MODE = 'stme'
};
enum {
@@ -26,21 +27,31 @@ enum {
// TODO: floating point representation?
};
enum {
EndianModeLittleEndian = 0,
EndianModeBigEndian = 1
};
enum {
TextModeNone = 0,
TextModeASCII
};
class Team;
class TeamMemoryBlock;
class MemoryView : public BView {
public:
MemoryView();
MemoryView(int32 hostEndianMode,
int32 targetEndianMode);
virtual ~MemoryView();
static MemoryView* Create();
static MemoryView* Create(int32 hostEndianMode,
int32 targetEndianMode);
// throws
void SetTargetAddress(TeamMemoryBlock* block,
@@ -67,6 +78,9 @@ private:
float fLineHeight;
int32 fTextCharsPerLine;
int32 fHexBlocksPerLine;
int32 fCurrentEndianMode;
int32 fHostEndianMode;
int32 fTargetEndianMode;
int32 fHexMode;
int32 fTextMode;
};
@@ -216,7 +216,8 @@ TeamWindow::MessageReceived(BMessage* message)
}
try {
fInspectorWindow = InspectorWindow::Create(fTeam, fListener);
fInspectorWindow = InspectorWindow::Create(fTeam, fListener,
this);
if (fInspectorWindow != NULL)
fInspectorWindow->Show();
} catch (...) {
@@ -224,6 +225,10 @@ TeamWindow::MessageReceived(BMessage* message)
}
break;
}
case MSG_INSPECTOR_WINDOW_CLOSED:
{
fInspectorWindow = NULL;
}
case B_REFS_RECEIVED:
{
entry_ref locatedPath;