1*c9945492SAndroid Build Coastguard Worker #include <stdlib.h> 2*c9945492SAndroid Build Coastguard Worker #include <stdint.h> 3*c9945492SAndroid Build Coastguard Worker #include <errno.h> 4*c9945492SAndroid Build Coastguard Worker #include "malloc_impl.h" 5*c9945492SAndroid Build Coastguard Worker aligned_alloc(size_t align,size_t len)6*c9945492SAndroid Build Coastguard Workervoid *aligned_alloc(size_t align, size_t len) 7*c9945492SAndroid Build Coastguard Worker { 8*c9945492SAndroid Build Coastguard Worker unsigned char *mem, *new; 9*c9945492SAndroid Build Coastguard Worker 10*c9945492SAndroid Build Coastguard Worker if ((align & -align) != align) { 11*c9945492SAndroid Build Coastguard Worker errno = EINVAL; 12*c9945492SAndroid Build Coastguard Worker return 0; 13*c9945492SAndroid Build Coastguard Worker } 14*c9945492SAndroid Build Coastguard Worker 15*c9945492SAndroid Build Coastguard Worker if (len > SIZE_MAX - align || 16*c9945492SAndroid Build Coastguard Worker (__malloc_replaced && !__aligned_alloc_replaced)) { 17*c9945492SAndroid Build Coastguard Worker errno = ENOMEM; 18*c9945492SAndroid Build Coastguard Worker return 0; 19*c9945492SAndroid Build Coastguard Worker } 20*c9945492SAndroid Build Coastguard Worker 21*c9945492SAndroid Build Coastguard Worker if (align <= SIZE_ALIGN) 22*c9945492SAndroid Build Coastguard Worker return malloc(len); 23*c9945492SAndroid Build Coastguard Worker 24*c9945492SAndroid Build Coastguard Worker if (!(mem = malloc(len + align-1))) 25*c9945492SAndroid Build Coastguard Worker return 0; 26*c9945492SAndroid Build Coastguard Worker 27*c9945492SAndroid Build Coastguard Worker new = (void *)((uintptr_t)mem + align-1 & -align); 28*c9945492SAndroid Build Coastguard Worker if (new == mem) return mem; 29*c9945492SAndroid Build Coastguard Worker 30*c9945492SAndroid Build Coastguard Worker struct chunk *c = MEM_TO_CHUNK(mem); 31*c9945492SAndroid Build Coastguard Worker struct chunk *n = MEM_TO_CHUNK(new); 32*c9945492SAndroid Build Coastguard Worker 33*c9945492SAndroid Build Coastguard Worker if (IS_MMAPPED(c)) { 34*c9945492SAndroid Build Coastguard Worker /* Apply difference between aligned and original 35*c9945492SAndroid Build Coastguard Worker * address to the "extra" field of mmapped chunk. */ 36*c9945492SAndroid Build Coastguard Worker n->psize = c->psize + (new-mem); 37*c9945492SAndroid Build Coastguard Worker n->csize = c->csize - (new-mem); 38*c9945492SAndroid Build Coastguard Worker return new; 39*c9945492SAndroid Build Coastguard Worker } 40*c9945492SAndroid Build Coastguard Worker 41*c9945492SAndroid Build Coastguard Worker struct chunk *t = NEXT_CHUNK(c); 42*c9945492SAndroid Build Coastguard Worker 43*c9945492SAndroid Build Coastguard Worker /* Split the allocated chunk into two chunks. The aligned part 44*c9945492SAndroid Build Coastguard Worker * that will be used has the size in its footer reduced by the 45*c9945492SAndroid Build Coastguard Worker * difference between the aligned and original addresses, and 46*c9945492SAndroid Build Coastguard Worker * the resulting size copied to its header. A new header and 47*c9945492SAndroid Build Coastguard Worker * footer are written for the split-off part to be freed. */ 48*c9945492SAndroid Build Coastguard Worker n->psize = c->csize = C_INUSE | (new-mem); 49*c9945492SAndroid Build Coastguard Worker n->csize = t->psize -= new-mem; 50*c9945492SAndroid Build Coastguard Worker 51*c9945492SAndroid Build Coastguard Worker __bin_chunk(c); 52*c9945492SAndroid Build Coastguard Worker return new; 53*c9945492SAndroid Build Coastguard Worker } 54