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:
Michael Lotz
2011-12-10 17:55:47 +01:00
parent 268ddbd76f
commit d0aa07489c
+17 -6
View File
@@ -6,6 +6,8 @@
#include <util/KMessage.h>
#include <malloc.h>
// for memalign()
#include <stdlib.h>
#include <string.h>
@@ -37,6 +39,7 @@
static const int32 kMessageReallocChunkSize = 64;
static const size_t kMessageBufferAlignment = 4;
const uint32 KMessage::kMessageHeaderMagic = 'kMsG';
@@ -46,14 +49,16 @@ const uint32 KMessage::kMessageHeaderMagic = 'kMsG';
static inline int32
_Align(int32 offset)
{
return (offset + 3) & ~0x3;
return (offset + kMessageBufferAlignment - 1)
& ~(kMessageBufferAlignment - 1);
}
static inline void*
_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;
// allocate a buffer
uint8* buffer = (uint8*)malloc(messageInfo->size);
uint8* buffer = (uint8*)memalign(kMessageBufferAlignment,
messageInfo->size);
if (!buffer)
return B_NO_MEMORY;
@@ -817,24 +823,29 @@ KMessage::_InitFromBuffer(bool sizeFromBuffer)
return B_BAD_DATA;
// clone the buffer, if requested
if ((fFlags & KMESSAGE_CLONE_BUFFER) != 0) {
if ((fFlags & KMESSAGE_CLONE_BUFFER) != 0 || _Align(fBuffer) != fBuffer) {
if (sizeFromBuffer) {
int32 size = fBufferCapacity;
memcpy(&size, &_Header()->size, 4);
fBufferCapacity = size;
}
void* buffer = malloc(fBufferCapacity);
void* buffer = memalign(kMessageBufferAlignment, fBufferCapacity);
if (buffer == NULL)
return B_NO_MEMORY;
memcpy(buffer, fBuffer, fBufferCapacity);
if ((fFlags & KMESSAGE_CLONE_BUFFER) == 0)
free(fBuffer);
fBuffer = buffer;
fFlags &= ~(uint32)(KMESSAGE_READ_ONLY | KMESSAGE_CLONE_BUFFER);
}
if (_Align(fBuffer) != fBuffer)
return B_BAD_DATA;
Header* header = _Header();
if (sizeFromBuffer)
@@ -952,7 +963,7 @@ KMessage::_AllocateSpace(int32 size, bool alignAddress, bool alignSize,
// reallocate if necessary
if (fBuffer == &fHeader) {
int32 newCapacity = _CapacityFor(newSize);
void* newBuffer = malloc(newCapacity);
void* newBuffer = memalign(kMessageBufferAlignment, newCapacity);
if (!newBuffer)
return B_NO_MEMORY;
fBuffer = newBuffer;