mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +00:00
- Reallocating overaligned memory with the LibcAllocator was unsafe.
This commit is contained in:
@@ -15,7 +15,6 @@ module std::core::mem::allocator @if(env::POSIX);
|
|||||||
import std::os;
|
import std::os;
|
||||||
import libc;
|
import libc;
|
||||||
|
|
||||||
|
|
||||||
fn void*? LibcAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz alignment) @dynamic
|
fn void*? LibcAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz alignment) @dynamic
|
||||||
{
|
{
|
||||||
if (init_type == ZERO)
|
if (init_type == ZERO)
|
||||||
@@ -50,24 +49,38 @@ fn void*? LibcAllocator.acquire(&self, usz bytes, AllocInitType init_type, usz a
|
|||||||
fn void*? LibcAllocator.resize(&self, void* old_ptr, usz new_bytes, usz alignment) @dynamic
|
fn void*? LibcAllocator.resize(&self, void* old_ptr, usz new_bytes, usz alignment) @dynamic
|
||||||
{
|
{
|
||||||
if (alignment <= mem::DEFAULT_MEM_ALIGNMENT) return libc::realloc(old_ptr, new_bytes) ?: mem::OUT_OF_MEMORY~;
|
if (alignment <= mem::DEFAULT_MEM_ALIGNMENT) return libc::realloc(old_ptr, new_bytes) ?: mem::OUT_OF_MEMORY~;
|
||||||
void* new_ptr;
|
|
||||||
if (posix::posix_memalign(&new_ptr, alignment, new_bytes)) return mem::OUT_OF_MEMORY~;
|
|
||||||
|
|
||||||
$switch:
|
// Easy case, it's 0
|
||||||
$case env::DARWIN:
|
if (!new_bytes)
|
||||||
usz old_usable_size = darwin::malloc_size(old_ptr);
|
{
|
||||||
$case env::LINUX:
|
libc::free(old_ptr);
|
||||||
usz old_usable_size = linux::malloc_usable_size(old_ptr);
|
return null;
|
||||||
$default:
|
}
|
||||||
usz old_usable_size = new_bytes;
|
|
||||||
$endswitch
|
// Try realloc, even though it might be unaligned.
|
||||||
|
void* new_ptr = libc::realloc(old_ptr, new_bytes) ?: mem::OUT_OF_MEMORY~!;
|
||||||
|
|
||||||
|
// If it's aligned then we're done!
|
||||||
|
uptr ptr_val = (uptr)new_ptr;
|
||||||
|
if (ptr_val & (alignment - 1) == 0) return new_ptr;
|
||||||
|
|
||||||
|
// We failed, so we need to use memalign
|
||||||
|
// We will free new_ptr before we exit.
|
||||||
|
defer libc::free(new_ptr);
|
||||||
|
|
||||||
|
// Create a pointer which is sure to be aligned.
|
||||||
|
void* aligned_ptr;
|
||||||
|
if (posix::posix_memalign(&aligned_ptr, alignment, new_bytes))
|
||||||
|
{
|
||||||
|
return mem::OUT_OF_MEMORY~;
|
||||||
|
}
|
||||||
|
// Now it is safe to copy the full range of data.
|
||||||
|
mem::copy(aligned_ptr, old_ptr, new_bytes, mem::DEFAULT_MEM_ALIGNMENT, mem::DEFAULT_MEM_ALIGNMENT);
|
||||||
|
return aligned_ptr;
|
||||||
|
|
||||||
usz copy_size = new_bytes < old_usable_size ? new_bytes : old_usable_size;
|
|
||||||
mem::copy(new_ptr, old_ptr, copy_size, mem::DEFAULT_MEM_ALIGNMENT, mem::DEFAULT_MEM_ALIGNMENT);
|
|
||||||
libc::free(old_ptr);
|
|
||||||
return new_ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn void LibcAllocator.release(&self, void* old_ptr, bool aligned) @dynamic
|
fn void LibcAllocator.release(&self, void* old_ptr, bool aligned) @dynamic
|
||||||
{
|
{
|
||||||
libc::free(old_ptr);
|
libc::free(old_ptr);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
- Const inline enums would not always implicitly get converted to the underlying type.
|
- Const inline enums would not always implicitly get converted to the underlying type.
|
||||||
- Update to dstring.append_string to take any type converting to String.
|
- Update to dstring.append_string to take any type converting to String.
|
||||||
- Flag `--cpu-flags` doesn't work if the first item is an exclusion. #2905
|
- Flag `--cpu-flags` doesn't work if the first item is an exclusion. #2905
|
||||||
|
- Reallocating overaligned memory with the LibcAllocator was unsafe.
|
||||||
|
|
||||||
## 0.7.9 Change list
|
## 0.7.9 Change list
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user