Ensure proper alignment instead of just checking for it.
* If there is an alignment requirement then better use memalign() to make sure that it is met. * Since the BMessageAdapter possibly sets a buffer directly, make a properly aligned copy of the buffer if it happens to be misaligned.
This commit is contained in:
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#include <util/KMessage.h>
|
#include <util/KMessage.h>
|
||||||
|
|
||||||
|
#include <malloc.h>
|
||||||
|
// for memalign()
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -37,6 +39,7 @@
|
|||||||
|
|
||||||
|
|
||||||
static const int32 kMessageReallocChunkSize = 64;
|
static const int32 kMessageReallocChunkSize = 64;
|
||||||
|
static const size_t kMessageBufferAlignment = 4;
|
||||||
|
|
||||||
const uint32 KMessage::kMessageHeaderMagic = 'kMsG';
|
const uint32 KMessage::kMessageHeaderMagic = 'kMsG';
|
||||||
|
|
||||||
@@ -46,14 +49,16 @@ const uint32 KMessage::kMessageHeaderMagic = 'kMsG';
|
|||||||
static inline int32
|
static inline int32
|
||||||
_Align(int32 offset)
|
_Align(int32 offset)
|
||||||
{
|
{
|
||||||
return (offset + 3) & ~0x3;
|
return (offset + kMessageBufferAlignment - 1)
|
||||||
|
& ~(kMessageBufferAlignment - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void*
|
static inline void*
|
||||||
_Align(void* address, int32 offset = 0)
|
_Align(void* address, int32 offset = 0)
|
||||||
{
|
{
|
||||||
return (void*)(((addr_t)address + offset + 3) & ~0x3);
|
return (void*)(((addr_t)address + offset + kMessageBufferAlignment - 1)
|
||||||
|
& ~(kMessageBufferAlignment - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -605,7 +610,8 @@ KMessage::ReceiveFrom(port_id fromPort, bigtime_t timeout,
|
|||||||
return error;
|
return error;
|
||||||
|
|
||||||
// allocate a buffer
|
// allocate a buffer
|
||||||
uint8* buffer = (uint8*)malloc(messageInfo->size);
|
uint8* buffer = (uint8*)memalign(kMessageBufferAlignment,
|
||||||
|
messageInfo->size);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
@@ -817,24 +823,29 @@ KMessage::_InitFromBuffer(bool sizeFromBuffer)
|
|||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
|
||||||
// clone the buffer, if requested
|
// clone the buffer, if requested
|
||||||
if ((fFlags & KMESSAGE_CLONE_BUFFER) != 0) {
|
if ((fFlags & KMESSAGE_CLONE_BUFFER) != 0 || _Align(fBuffer) != fBuffer) {
|
||||||
if (sizeFromBuffer) {
|
if (sizeFromBuffer) {
|
||||||
int32 size = fBufferCapacity;
|
int32 size = fBufferCapacity;
|
||||||
memcpy(&size, &_Header()->size, 4);
|
memcpy(&size, &_Header()->size, 4);
|
||||||
fBufferCapacity = size;
|
fBufferCapacity = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* buffer = malloc(fBufferCapacity);
|
void* buffer = memalign(kMessageBufferAlignment, fBufferCapacity);
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
memcpy(buffer, fBuffer, fBufferCapacity);
|
memcpy(buffer, fBuffer, fBufferCapacity);
|
||||||
|
|
||||||
|
if ((fFlags & KMESSAGE_CLONE_BUFFER) == 0)
|
||||||
|
free(fBuffer);
|
||||||
|
|
||||||
fBuffer = buffer;
|
fBuffer = buffer;
|
||||||
fFlags &= ~(uint32)(KMESSAGE_READ_ONLY | KMESSAGE_CLONE_BUFFER);
|
fFlags &= ~(uint32)(KMESSAGE_READ_ONLY | KMESSAGE_CLONE_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_Align(fBuffer) != fBuffer)
|
if (_Align(fBuffer) != fBuffer)
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
|
|
||||||
Header* header = _Header();
|
Header* header = _Header();
|
||||||
|
|
||||||
if (sizeFromBuffer)
|
if (sizeFromBuffer)
|
||||||
@@ -952,7 +963,7 @@ KMessage::_AllocateSpace(int32 size, bool alignAddress, bool alignSize,
|
|||||||
// reallocate if necessary
|
// reallocate if necessary
|
||||||
if (fBuffer == &fHeader) {
|
if (fBuffer == &fHeader) {
|
||||||
int32 newCapacity = _CapacityFor(newSize);
|
int32 newCapacity = _CapacityFor(newSize);
|
||||||
void* newBuffer = malloc(newCapacity);
|
void* newBuffer = memalign(kMessageBufferAlignment, newCapacity);
|
||||||
if (!newBuffer)
|
if (!newBuffer)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
fBuffer = newBuffer;
|
fBuffer = newBuffer;
|
||||||
|
|||||||
Reference in New Issue
Block a user