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 <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;