104 lines
2.1 KiB
C++
104 lines
2.1 KiB
C++
/*
|
|||
|
|
* Copyright 2005, Ingo Weinhold, [email protected].
|
||
|
|
* Distributed under the terms of the MIT License.
|
||
|
|
*/
|
||
|
|
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <string.h>
|
||
|
|
|
||
|
|
#include <debugger.h>
|
||
|
|
|
||
|
|
#include "MemoryReader.h"
|
||
|
|
|
||
|
|
// constructor
|
||
|
|
MemoryReader::MemoryReader(port_id nubPort)
|
||
|
|
: fNubPort(nubPort),
|
||
|
|
fReplyPort(-1)
|
||
|
|
{
|
||
|
|
fReplyPort = create_port(1, "memory reader reply");
|
||
|
|
if (fReplyPort < 0) {
|
||
|
|
fprintf(stderr, "Failed to create memory reader reply port: %s\n",
|
||
|
|
strerror(fReplyPort));
|
||
|
|
exit(1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// constructor
|
||
|
|
MemoryReader::~MemoryReader()
|
||
|
|
{
|
||
|
|
if (fReplyPort >= 0)
|
||
|
|
delete_port(fReplyPort);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Read
|
||
|
|
status_t
|
||
|
|
MemoryReader::Read(void *_address, void *_buffer, int32 size, int32 &bytesRead)
|
||
|
|
{
|
||
|
|
char *address = (char*)_address;
|
||
|
|
char *buffer = (char*)_buffer;
|
||
|
|
bytesRead = 0;
|
||
|
|
|
||
|
|
while (size > 0) {
|
||
|
|
int32 toRead = size;
|
||
|
|
if (toRead > B_MAX_READ_WRITE_MEMORY_SIZE)
|
||
|
|
toRead = B_MAX_READ_WRITE_MEMORY_SIZE;
|
||
|
|
|
||
int32 actuallyRead = 0;
|
|||
|
|
status_t error = _Read(address, buffer, toRead, actuallyRead);
|
||
|
|||
// If reading fails, we only fail, if we haven't read anything yet.
|
|||
if (error != B_OK) {
|
|||
|
|
if (bytesRead > 0)
|
||
|
|
return B_OK;
|
||
|
|
return error;
|
||
|
|
}
|
||
|
|
|
||
bytesRead += actuallyRead;
|
|||
|
|
address += actuallyRead;
|
||
|
|
buffer += actuallyRead;
|
||
|
|
size -= actuallyRead;
|
||
}
|
|||
|
|
|
||
|
|
return B_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
// _Read
|
||
|
|
status_t
|
||
MemoryReader::_Read(void *address, void *buffer, int32 size, int32 &bytesRead)
|
|||
{
|
|||
|
|
// prepare message
|
||
|
|
debug_nub_read_memory message;
|
||
|
|
message.reply_port = fReplyPort;
|
||
|
|
message.address = address;
|
||
|
|
message.size = size;
|
||
|
|
|
||
|
|
// send message
|
||
|
|
while (true) {
|
||
|
|
status_t error = write_port(fNubPort, B_DEBUG_MESSAGE_READ_MEMORY,
|
||
|
|
&message, sizeof(message));
|
||
|
|
if (error == B_OK)
|
||
|
|
break;
|
||
|
|
if (error != B_INTERRUPTED)
|
||
|
|
return error;
|
||
|
|
}
|
||
|
|
|
||
|
|
// get reply
|
||
|
|
int32 code;
|
||
|
|
debug_nub_read_memory_reply reply;
|
||
|
|
while (true) {
|
||
|
|
ssize_t bytesRead = read_port(fReplyPort, &code, &reply, sizeof(reply));
|
||
|
|
if (bytesRead > 0)
|
||
|
|
break;
|
||
|
|
if (bytesRead != B_INTERRUPTED)
|
||
|
|
return bytesRead;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (reply.error != B_OK)
|
||
|
|
return reply.error;
|
||
|
|
|
||
bytesRead = reply.size;
|
|||
|
|
memcpy(buffer, reply.data, bytesRead);
|
||
|
|||
|
|
return B_OK;
|
||
|
|
}
|