1/* 2 * Copyright 2005-2011, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include <stdio.h> 8#include <stdlib.h> 9#include <string.h> 10 11#include <debugger.h> 12 13#include "MemoryReader.h" 14 15 16MemoryReader::MemoryReader() 17 : 18 fNubPort(-1), 19 fReplyPort(-1) 20{ 21} 22 23 24MemoryReader::~MemoryReader() 25{ 26 if (fReplyPort >= 0) 27 delete_port(fReplyPort); 28} 29 30 31status_t 32MemoryReader::Init(port_id nubPort) 33{ 34 if (fReplyPort >= 0) 35 delete_port(fReplyPort); 36 37 fNubPort = nubPort; 38 39 fReplyPort = create_port(1, "memory reader reply"); 40 if (fReplyPort < 0) { 41 fprintf(stderr, "Failed to create memory reader reply port: %s\n", 42 strerror(fReplyPort)); 43 return fReplyPort; 44 } 45 46 return B_OK; 47} 48 49 50status_t 51MemoryReader::Read(void *_address, void *_buffer, int32 size, int32 &bytesRead) 52{ 53 char *address = (char*)_address; 54 char *buffer = (char*)_buffer; 55 bytesRead = 0; 56 57 while (size > 0) { 58 int32 toRead = size; 59 if (toRead > B_MAX_READ_WRITE_MEMORY_SIZE) 60 toRead = B_MAX_READ_WRITE_MEMORY_SIZE; 61 62 int32 actuallyRead = 0; 63 status_t error = _Read(address, buffer, toRead, actuallyRead); 64 65 // If reading fails, we only fail, if we haven't read anything yet. 66 if (error != B_OK) { 67 if (bytesRead > 0) 68 return B_OK; 69 return error; 70 } 71 72 bytesRead += actuallyRead; 73 address += actuallyRead; 74 buffer += actuallyRead; 75 size -= actuallyRead; 76 } 77 78 return B_OK; 79} 80 81 82status_t 83MemoryReader::_Read(void *address, void *buffer, int32 size, int32 &bytesRead) 84{ 85 // prepare message 86 debug_nub_read_memory message; 87 message.reply_port = fReplyPort; 88 message.address = address; 89 message.size = size; 90 91 // send message 92 while (true) { 93 status_t error = write_port(fNubPort, B_DEBUG_MESSAGE_READ_MEMORY, 94 &message, sizeof(message)); 95 if (error == B_OK) 96 break; 97 if (error != B_INTERRUPTED) 98 return error; 99 } 100 101 // get reply 102 int32 code; 103 debug_nub_read_memory_reply reply; 104 while (true) { 105 ssize_t bytesRead = read_port(fReplyPort, &code, &reply, sizeof(reply)); 106 if (bytesRead > 0) 107 break; 108 if (bytesRead != B_INTERRUPTED) 109 return bytesRead; 110 } 111 112 if (reply.error != B_OK) 113 return reply.error; 114 115 bytesRead = reply.size; 116 memcpy(buffer, reply.data, bytesRead); 117 118 return B_OK; 119} 120