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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user