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 16 MemoryReader::MemoryReader() 17 : 18 fNubPort(-1), 19 fReplyPort(-1) 20 { 21 } 22 23 24 MemoryReader::~MemoryReader() 25 { 26 if (fReplyPort >= 0) 27 delete_port(fReplyPort); 28 } 29 30 31 status_t 32 MemoryReader::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 50 status_t 51 MemoryReader::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 82 status_t 83 MemoryReader::_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