void* _aligned_offset_recalloc(void* memblock, size_t num, size_t size, size_t alignment, size_t offset) { size_t copySize; void* newMemblock; WINPR_ALIGNED_MEM* pMem; WINPR_ALIGNED_MEM* pNewMem; if (!memblock) return _aligned_offset_malloc(size, alignment, offset); if (size == 0) { _aligned_free(memblock); return NULL; } newMemblock = _aligned_offset_malloc(size, alignment, offset); if (!newMemblock) return NULL; pMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(memblock); pNewMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(newMemblock); if (pMem->sig != WINPR_ALIGNED_MEM_SIGNATURE) { fprintf(stderr, "_aligned_offset_recalloc: memory block was not allocated by _aligned_malloc!\n"); return NULL; } ZeroMemory(newMemblock, pNewMem->size); _aligned_free(memblock); return newMemblock; }
void* _aligned_offset_realloc(void* memblock, size_t size, size_t alignment, size_t offset) { size_t copySize; void* newMemblock; WINPR_ALIGNED_MEM* pMem; WINPR_ALIGNED_MEM* pNewMem; if (!memblock) return _aligned_offset_malloc(size, alignment, offset); pMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(memblock); if (pMem->sig != WINPR_ALIGNED_MEM_SIGNATURE) { WLog_ERR(TAG, "_aligned_offset_realloc: memory block was not allocated by _aligned_malloc!"); return NULL; } if (size == 0) { _aligned_free(memblock); return NULL; } newMemblock = _aligned_offset_malloc(size, alignment, offset); if (!newMemblock) return NULL; pNewMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(newMemblock); copySize = (pNewMem->size < pMem->size) ? pNewMem->size : pMem->size; CopyMemory(newMemblock, memblock, copySize); _aligned_free(memblock); return newMemblock; }
void* _aligned_offset_recalloc(void* memblock, size_t num, size_t size, size_t alignment, size_t offset) { void* newMemblock; WINPR_ALIGNED_MEM* pMem; WINPR_ALIGNED_MEM* pNewMem; if (!memblock) { newMemblock = _aligned_offset_malloc(size * num, alignment, offset); if (newMemblock) { pNewMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(newMemblock); ZeroMemory(newMemblock, pNewMem->size); } return memblock; } pMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(memblock); if (pMem->sig != WINPR_ALIGNED_MEM_SIGNATURE) { WLog_ERR(TAG, "_aligned_offset_recalloc: memory block was not allocated by _aligned_malloc!"); return NULL; } if (size == 0) { _aligned_free(memblock); return NULL; } newMemblock = _aligned_offset_malloc(size * num, alignment, offset); if (!newMemblock) return NULL; pNewMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(newMemblock); ZeroMemory(newMemblock, pNewMem->size); _aligned_free(memblock); return newMemblock; }
void allocAlignedMalloc(bool bFree) { void* leaked = _aligned_offset_malloc(64, 16, 1); int* leaked_memory = (int*)_aligned_malloc(64, 16); int* leaked_memory_dbg = (int*)_aligned_malloc_dbg(32, 16, __FILE__, __LINE__); if (bFree) { _aligned_free(leaked); _aligned_free(leaked_memory); _aligned_free_dbg(leaked_memory_dbg); } }
void allocAlignedRealloc(bool bFree) { void* leaked = _aligned_offset_malloc(64, 16, 1); int* leaked_memory = (int*)_aligned_malloc(64, 16); int* leaked_memory_dbg = (int*)_aligned_malloc_dbg(32, 16, __FILE__, __LINE__); leaked = (int*)_aligned_offset_realloc(leaked, 48, 16, 2); leaked_memory = (int*)_aligned_realloc(leaked_memory, 128, 16); leaked_memory_dbg = (int*)_aligned_realloc_dbg(leaked_memory_dbg, 48, 16, __FILE__, __LINE__); leaked = (int*)_aligned_offset_recalloc(leaked, 1, 52, 16, 2); leaked_memory = (int*)_aligned_recalloc(leaked_memory, 1, 132, 16); leaked_memory_dbg = (int*)_aligned_recalloc_dbg(leaked_memory_dbg, 1, 64, 16, __FILE__, __LINE__); if (bFree) { _aligned_free(leaked); _aligned_free(leaked_memory); _aligned_free_dbg(leaked_memory_dbg); } }
void * __cdecl _aligned_offset_malloc_dbg( size_t size, size_t align, size_t offset, const char * f_name, int line_n) { return _aligned_offset_malloc(size, align, offset); }
void *CTsPacket::Allocate(size_t Size) { // スクランブル解除時に都合がいいように、ペイロードを16バイト境界に合わせる return _aligned_offset_malloc(Size, 16, 4); }
/********************************************************************* * _aligned_offset_realloc (MSVCRT.@) */ void * CDECL _aligned_offset_realloc(void *memblock, MSVCRT_size_t size, MSVCRT_size_t alignment, MSVCRT_size_t offset) { void * temp, **saved; MSVCRT_size_t old_padding, new_padding, old_size; TRACE("(%p, %lu, %lu, %lu)\n", memblock, size, alignment, offset); if (!memblock) return _aligned_offset_malloc(size, alignment, offset); /* alignment must be a power of 2 */ if ((alignment & (alignment - 1)) != 0) { *MSVCRT__errno() = MSVCRT_EINVAL; return NULL; } /* offset must be less than size */ if (offset >= size) { *MSVCRT__errno() = MSVCRT_EINVAL; return NULL; } if (size == 0) { _aligned_free(memblock); return NULL; } /* don't align to less than void pointer size */ if (alignment < sizeof(void *)) alignment = sizeof(void *); /* make sure alignment and offset didn't change */ saved = SAVED_PTR(memblock); if (memblock != ALIGN_PTR(*saved, alignment, offset)) { *MSVCRT__errno() = MSVCRT_EINVAL; return NULL; } old_padding = (char *)memblock - (char *)*saved; /* Get previous size of block */ old_size = _msize(*saved); if (old_size == -1) { /* It seems this function was called with an invalid pointer. Bail out. */ return NULL; } /* Adjust old_size to get amount of actual data in old block. */ if (old_size < old_padding) { /* Shouldn't happen. Something's weird, so bail out. */ return NULL; } old_size -= old_padding; temp = MSVCRT_realloc(*saved, size + alignment + sizeof(void *)); if (!temp) return NULL; /* adjust pointer for proper alignment and offset */ memblock = ALIGN_PTR(temp, alignment, offset); /* Save the real allocation address below returned address */ /* so it can be found later to free. */ saved = SAVED_PTR(memblock); new_padding = (char *)memblock - (char *)temp; /* Memory layout of old block is as follows: +-------+---------------------+-+--------------------------+-----------+ | ... | "old_padding" bytes | | ... "old_size" bytes ... | ... | +-------+---------------------+-+--------------------------+-----------+ ^ ^ ^ | | | *saved saved memblock Memory layout of new block is as follows: +-------+-----------------------------+-+----------------------+-------+ | ... | "new_padding" bytes | | ... "size" bytes ... | ... | +-------+-----------------------------+-+----------------------+-------+ ^ ^ ^ | | | temp saved memblock However, in the new block, actual data is still written as follows (because it was copied by MSVCRT_realloc): +-------+---------------------+--------------------------------+-------+ | ... | "old_padding" bytes | ... "old_size" bytes ... | ... | +-------+---------------------+--------------------------------+-------+ ^ ^ ^ | | | temp saved memblock Therefore, min(old_size,size) bytes of actual data have to be moved from the offset they were at in the old block (temp + old_padding), to the offset they have to be in the new block (temp + new_padding == memblock). */ if (new_padding != old_padding) memmove((char *)memblock, (char *)temp + old_padding, (old_size < size) ? old_size : size); *saved = temp; return memblock; }
/********************************************************************* * _aligned_malloc (MSVCRT.@) */ void * CDECL _aligned_malloc(MSVCRT_size_t size, MSVCRT_size_t alignment) { TRACE("(%lu, %lu)\n", size, alignment); return _aligned_offset_malloc(size, alignment, 0); }
int TestAlignment(int argc, char* argv[]) { void* ptr; size_t alignment; size_t offset; /* Alignment should be 2^N where N is a positive integer */ alignment = 16; offset = 5; /* _aligned_malloc */ ptr = _aligned_malloc(100, alignment); if (ptr == NULL) { printf("Error allocating aligned memory.\n"); return -1; } if (((size_t) ptr % alignment) != 0) { printf("This pointer, %d, is not aligned on %d\n", ptr, alignment); return -1; } /* _aligned_realloc */ ptr = _aligned_realloc(ptr, 200, alignment); if (((size_t) ptr % alignment) != 0) { printf("This pointer, %d, is not aligned on %d\n", ptr, alignment); return -1; } _aligned_free(ptr); /* _aligned_offset_malloc */ ptr = _aligned_offset_malloc(200, alignment, offset); if (ptr == NULL) { printf("Error reallocating aligned offset memory."); return -1; } if (((((size_t) ptr) + offset) % alignment) != 0) { printf("This pointer, %d, does not satisfy offset %d and alignment %d\n", ptr, offset, alignment); return -1; } /* _aligned_offset_realloc */ ptr = _aligned_offset_realloc(ptr, 200, alignment, offset); if (ptr == NULL) { printf("Error reallocating aligned offset memory."); return -1; } if (((((size_t) ptr) + offset) % alignment) != 0) { printf("This pointer, %d, does not satisfy offset %d and alignment %d\n", ptr, offset, alignment); return -1; } /* _aligned_free works for both _aligned_malloc and _aligned_offset_malloc. free() should not be used. */ _aligned_free(ptr); return 0; }
void* _aligned_malloc(size_t size, size_t alignment) { return _aligned_offset_malloc(size, alignment, 0); }