Skip to content
Snippets Groups Projects
Commit c2c8806f authored by jD91mZM2's avatar jD91mZM2
Browse files

Merge branch 'malloc_errno' into 'master'

Set errno in alloc functions and add further tests

See merge request !205
parents 7bde0360 912385b5
No related branches found
No related tags found
No related merge requests found
Pipeline #3897 failed
......@@ -78,11 +78,15 @@ pub extern "C" fn abs(i: c_int) -> c_int {
#[no_mangle]
pub unsafe extern "C" fn aligned_alloc(alignment: size_t, size: size_t) -> *mut c_void {
if size % alignment != 0 {
return ptr::null_mut();
if size % alignment == 0 {
/* The size-is-multiple-of-alignment requirement is the only
* difference between aligned_alloc() and memalign(). */
memalign(alignment, size)
}
else {
platform::errno = errno::EINVAL;
ptr::null_mut()
}
memalign(alignment, size)
}
#[no_mangle]
......@@ -190,13 +194,19 @@ pub unsafe extern "C" fn calloc(nelem: size_t, elsize: size_t) -> *mut c_void {
let size_result = nelem.checked_mul(elsize);
match size_result {
Some(size) => {
/* If allocation fails here, errno setting will be handled
* by malloc() */
let ptr = malloc(size);
if !ptr.is_null() {
intrinsics::write_bytes(ptr as *mut u8, 0, size);
}
ptr
},
None => {
// For overflowing multiplication, we have to set errno here
platform::errno = errno::ENOMEM;
ptr::null_mut()
}
None => core::ptr::null_mut(),
}
}
......@@ -403,12 +413,29 @@ pub extern "C" fn lrand48() -> c_long {
#[no_mangle]
pub unsafe extern "C" fn malloc(size: size_t) -> *mut c_void {
platform::alloc(size)
let ptr = platform::alloc(size);
if ptr.is_null() {
platform::errno = errno::ENOMEM;
}
ptr
}
#[no_mangle]
pub unsafe extern "C" fn memalign(alignment: size_t, size: size_t) -> *mut c_void {
platform::alloc_align(size, alignment)
/* Check if alignment is a (positive) power of two. The second
* expression will never underflow, due to Rust's lazy boolean
* operators. */
if alignment > 0 && (alignment & (alignment - 1)) == 0 {
let ptr = platform::alloc_align(size, alignment);
if ptr.is_null() {
platform::errno = errno::ENOMEM;
}
ptr
}
else {
platform::errno = errno::EINVAL;
ptr::null_mut()
}
}
#[no_mangle]
......@@ -613,7 +640,11 @@ pub extern "C" fn random() -> c_long {
#[no_mangle]
pub unsafe extern "C" fn realloc(ptr: *mut c_void, size: size_t) -> *mut c_void {
platform::realloc(ptr, size)
let ptr = platform::realloc(ptr, size);
if ptr.is_null() {
platform::errno = errno::ENOMEM;
}
ptr
}
#[no_mangle]
......
#include <malloc.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h> /* for size_t */
#include <stdint.h> /* for SIZE_MAX */
#include "test_helpers.h"
int main(void) {
char * ptr = (char *)malloc(256);
printf("malloc %p\n", ptr);
size_t sample_alloc_size = 256;
size_t sample_realloc_size = sample_alloc_size + 1;
/* ensure values are mapped to variables */
size_t max_size = SIZE_MAX;
size_t aligned_alloc_alignment = 128;
size_t aligned_alloc_goodsize = 256;
size_t aligned_alloc_badsize = 257;
int i;
for(i = 0; i < 256; i++) {
ptr[i] = (char)i;
errno = 0;
char * ptr_malloc = (char *)malloc(sample_alloc_size);
int malloc_errno = errno;
printf("malloc : %p, errno: %d = %s\n",
ptr_malloc, malloc_errno, strerror(malloc_errno));
for(i = 0; i < sample_alloc_size; i++) {
ptr_malloc[i] = (char)i;
}
free(ptr);
char * ptrc = (char *)calloc(256, 1);
printf("calloc %p\n", ptrc);
for(i = 0; i < 256; i++) {
ptrc[i] = (char)i;
free(ptr_malloc);
errno = 0;
char * ptr_malloc_maxsize = (char *)malloc(max_size);
int malloc_maxsize_errno = errno;
printf("malloc (SIZE_MAX) : %p, errno: %d = %s\n",
ptr_malloc_maxsize, malloc_maxsize_errno,
strerror(malloc_maxsize_errno));
free(ptr_malloc_maxsize);
errno = 0;
char * ptr_calloc = (char *)calloc(sample_alloc_size, 1);
int calloc_errno = errno;
printf("calloc : %p, errno: %d = %s\n", ptr_calloc,
calloc_errno, strerror(calloc_errno));
for(i = 0; i < sample_alloc_size; i++) {
ptr_calloc[i] = (char)i;
}
free(ptrc);
char * ptrco = (char *)calloc(SIZE_MAX, SIZE_MAX);
printf("calloc (overflowing) %p\n", ptrco);
free(ptrco); /* clean up correctly even if overflow is not handled */
char * ptra = (char *)memalign(256, 256);
printf("memalign %p\n", ptra);
for(i = 0; i < 256; i++) {
ptra[i] = (char)i;
free(ptr_calloc);
errno = 0;
char * ptr_calloc_overflow = (char *)calloc(max_size, max_size);
int calloc_overflow_errno = errno;
printf("calloc (overflowing) : %p, errno: %d = %s\n",
ptr_calloc_overflow, calloc_overflow_errno,
strerror(calloc_overflow_errno));
free(ptr_calloc_overflow); /* clean up correctly even if overflow is not handled */
char * ptr_realloc = (char *)malloc(sample_alloc_size);
errno = 0;
ptr_realloc = (char *)realloc(ptr_realloc, sample_realloc_size);
int realloc_errno = errno;
printf("realloc : %p, errno: %d = %s\n",
ptr_realloc, realloc_errno, strerror(realloc_errno));
for(i = 0; i < sample_realloc_size; i++) {
ptr_realloc[i] = (char)i;
}
free(ptr_realloc);
char * ptr_realloc_maxsize = (char *)malloc(sample_alloc_size);
errno = 0;
ptr_realloc_maxsize = (char *)realloc(ptr_realloc_maxsize, max_size);
int realloc_maxsize_errno = errno;
printf("realloc (SIZE_MAX) : %p, errno: %d = %s\n",
ptr_realloc_maxsize, realloc_maxsize_errno,
strerror(realloc_maxsize_errno));
free(ptr_realloc_maxsize);
errno = 0;
char * ptr_memalign = (char *)memalign(256, sample_alloc_size);
int memalign_errno = errno;
printf("memalign : %p, errno: %d = %s\n", ptr_memalign,
memalign_errno, strerror(memalign_errno));
for(i = 0; i < sample_alloc_size; i++) {
ptr_memalign[i] = (char)i;
}
free(ptra);
free(ptr_memalign);
errno = 0;
char * ptr_memalign_maxsize = (char *)memalign(256, max_size);
int memalign_maxsize_errno = errno;
printf("memalign (SIZE_MAX) : %p, errno: %d = %s\n",
ptr_memalign_maxsize, memalign_maxsize_errno,
strerror(memalign_maxsize_errno));
free(ptr_memalign_maxsize);
errno = 0;
char * ptr_memalign_align0 = (char *)memalign(0, sample_alloc_size);
int memalign_align0_errno = errno;
printf("memalign (alignment 0): %p, errno: %d = %s\n",
ptr_memalign_align0, memalign_align0_errno,
strerror(memalign_align0_errno));
free(ptr_memalign_align0);
errno = 0;
char * ptr_memalign_align3 = (char *)memalign(3, sample_alloc_size);
int memalign_align3_errno = errno;
printf("memalign (alignment 3): %p, errno: %d = %s\n",
ptr_memalign_align3, memalign_align3_errno,
strerror(memalign_align3_errno));
free(ptr_memalign_align3);
errno = 0;
char * ptr_aligned_alloc_goodsize = (char *)aligned_alloc(aligned_alloc_alignment, aligned_alloc_goodsize);
int aligned_alloc_goodsize_errno = errno;
printf("aligned_alloc (size %% alignment == 0):\n");
printf(" %p, errno: %d = %s\n",
ptr_aligned_alloc_goodsize, aligned_alloc_goodsize_errno,
strerror(aligned_alloc_goodsize_errno));
free(ptr_aligned_alloc_goodsize);
errno = 0;
char * ptr_aligned_alloc_badsize = (char *)aligned_alloc(aligned_alloc_alignment, aligned_alloc_badsize);
int aligned_alloc_badsize_errno = errno;
printf("aligned_alloc (size %% alignment != 0):\n");
printf(" %p, errno: %d = %s\n",
ptr_aligned_alloc_badsize, aligned_alloc_badsize_errno,
strerror(aligned_alloc_badsize_errno));
free(ptr_aligned_alloc_badsize);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment