Files
haiku-beta6/src/apps/bin/strace/MemoryReader.cpp
T

104 lines
2.1 KiB
C++
Raw Normal View History

/*
* 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;
2005-03-08 23:11:21 +00:00
int32 actuallyRead = 0;
status_t error = _Read(address, buffer, toRead, actuallyRead);
2005-03-08 23:11:21 +00:00
// 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;
}
2005-03-08 23:11:21 +00:00
bytesRead += actuallyRead;
address += actuallyRead;
buffer += actuallyRead;
size -= actuallyRead;
}
return B_OK;
}
// _Read
status_t
2005-03-08 23:11:21 +00:00
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;
2005-03-08 23:11:21 +00:00
bytesRead = reply.size;
memcpy(buffer, reply.data, bytesRead);
return B_OK;
}