Support partial reads from memory.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11625 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2005-03-08 23:10:55 +00:00
parent 7586a0f3d6
commit bd5d59c4cc
+61 -3
View File
@@ -694,6 +694,61 @@ nub_thread_cleanup(struct thread *nubThread)
}
/** \brief Reads data from user memory.
*
* Tries to read \a size bytes of data from user memory address \a address
* into the supplied buffer \a buffer. If only a part could be read the
* function won't fail. The number of bytes actually read is return through
* \a bytesRead.
*
* \param address The user memory address from which to read.
* \param buffer The buffer into which to write.
* \param size The number of bytes to read.
* \param bytesRead Will be set to the number of bytes actually read.
* \return \c B_OK, if reading went fine. Then \a bytesRead will be set to
* the amount of data actually read. An error indicates that nothing
* has been read.
*/
static status_t
read_user_memory(const void *_address, void *_buffer, int32 size,
int32 &bytesRead)
{
const char *address = (const char*)_address;
char *buffer = (char*)_buffer;
// check the parameters
if (!IS_USER_ADDRESS(address))
return B_BAD_ADDRESS;
if (size <= 0)
return B_BAD_VALUE;
// If the region to be read crosses page boundaries, we split it up into
// smaller chunks.
bytesRead = 0;
while (size > 0) {
int32 toRead = size;
if ((uint32)address % B_PAGE_SIZE + toRead > B_PAGE_SIZE)
toRead = B_PAGE_SIZE - (uint32)address % B_PAGE_SIZE;
status_t error = user_memcpy(buffer, address, toRead);
// 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 += toRead;
address += toRead;
buffer += toRead;
size -= toRead;
}
return B_OK;
}
static status_t
debug_nub_thread(void *)
{
@@ -761,8 +816,11 @@ debug_nub_thread(void *)
result = B_BAD_VALUE;
// read the memory
if (result == B_OK)
result = user_memcpy(reply.read_memory.data, address, size);
int32 bytesRead = 0;
if (result == B_OK) {
result = read_user_memory(address, reply.read_memory.data,
size, bytesRead);
}
reply.read_memory.error = result;
TRACE(("nub thread %ld: B_DEBUG_MESSAGE_READ_MEMORY: "
@@ -770,7 +828,7 @@ debug_nub_thread(void *)
nubThread->id, replyPort, address, size, result));
// send only as much data as necessary
int32 bytesRead = (result == B_OK ? size : 0);
reply.read_memory.size = bytesRead;
replySize = reply.read_memory.data + bytesRead - (char*)&reply;
sendReply = true;
break;