1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
3*77c1e3ccSAndroid Build Coastguard Worker *
4*77c1e3ccSAndroid Build Coastguard Worker * This source code is subject to the terms of the BSD 2 Clause License and
5*77c1e3ccSAndroid Build Coastguard Worker * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6*77c1e3ccSAndroid Build Coastguard Worker * was not distributed with this source code in the LICENSE file, you can
7*77c1e3ccSAndroid Build Coastguard Worker * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8*77c1e3ccSAndroid Build Coastguard Worker * Media Patent License 1.0 was not distributed with this source code in the
9*77c1e3ccSAndroid Build Coastguard Worker * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10*77c1e3ccSAndroid Build Coastguard Worker */
11*77c1e3ccSAndroid Build Coastguard Worker
12*77c1e3ccSAndroid Build Coastguard Worker #include "aom_mem.h"
13*77c1e3ccSAndroid Build Coastguard Worker #include <assert.h>
14*77c1e3ccSAndroid Build Coastguard Worker #include <stdlib.h>
15*77c1e3ccSAndroid Build Coastguard Worker #include <string.h>
16*77c1e3ccSAndroid Build Coastguard Worker #include "include/aom_mem_intrnl.h"
17*77c1e3ccSAndroid Build Coastguard Worker #include "aom/aom_integer.h"
18*77c1e3ccSAndroid Build Coastguard Worker
GetAllocationPaddingSize(size_t align)19*77c1e3ccSAndroid Build Coastguard Worker static size_t GetAllocationPaddingSize(size_t align) {
20*77c1e3ccSAndroid Build Coastguard Worker assert(align > 0);
21*77c1e3ccSAndroid Build Coastguard Worker assert(align < SIZE_MAX - ADDRESS_STORAGE_SIZE);
22*77c1e3ccSAndroid Build Coastguard Worker return align - 1 + ADDRESS_STORAGE_SIZE;
23*77c1e3ccSAndroid Build Coastguard Worker }
24*77c1e3ccSAndroid Build Coastguard Worker
25*77c1e3ccSAndroid Build Coastguard Worker // Returns 0 in case of overflow of nmemb * size.
check_size_argument_overflow(size_t nmemb,size_t size,size_t align)26*77c1e3ccSAndroid Build Coastguard Worker static int check_size_argument_overflow(size_t nmemb, size_t size,
27*77c1e3ccSAndroid Build Coastguard Worker size_t align) {
28*77c1e3ccSAndroid Build Coastguard Worker if (nmemb == 0) return 1;
29*77c1e3ccSAndroid Build Coastguard Worker const size_t alloc_padding = GetAllocationPaddingSize(align);
30*77c1e3ccSAndroid Build Coastguard Worker #if defined(AOM_MAX_ALLOCABLE_MEMORY)
31*77c1e3ccSAndroid Build Coastguard Worker assert(AOM_MAX_ALLOCABLE_MEMORY >= alloc_padding);
32*77c1e3ccSAndroid Build Coastguard Worker assert(AOM_MAX_ALLOCABLE_MEMORY <= SIZE_MAX);
33*77c1e3ccSAndroid Build Coastguard Worker if (size > (AOM_MAX_ALLOCABLE_MEMORY - alloc_padding) / nmemb) return 0;
34*77c1e3ccSAndroid Build Coastguard Worker #else
35*77c1e3ccSAndroid Build Coastguard Worker if (size > (SIZE_MAX - alloc_padding) / nmemb) return 0;
36*77c1e3ccSAndroid Build Coastguard Worker #endif
37*77c1e3ccSAndroid Build Coastguard Worker return 1;
38*77c1e3ccSAndroid Build Coastguard Worker }
39*77c1e3ccSAndroid Build Coastguard Worker
GetMallocAddressLocation(void * const mem)40*77c1e3ccSAndroid Build Coastguard Worker static size_t *GetMallocAddressLocation(void *const mem) {
41*77c1e3ccSAndroid Build Coastguard Worker return ((size_t *)mem) - 1;
42*77c1e3ccSAndroid Build Coastguard Worker }
43*77c1e3ccSAndroid Build Coastguard Worker
SetActualMallocAddress(void * const mem,const void * const malloc_addr)44*77c1e3ccSAndroid Build Coastguard Worker static void SetActualMallocAddress(void *const mem,
45*77c1e3ccSAndroid Build Coastguard Worker const void *const malloc_addr) {
46*77c1e3ccSAndroid Build Coastguard Worker size_t *const malloc_addr_location = GetMallocAddressLocation(mem);
47*77c1e3ccSAndroid Build Coastguard Worker *malloc_addr_location = (size_t)malloc_addr;
48*77c1e3ccSAndroid Build Coastguard Worker }
49*77c1e3ccSAndroid Build Coastguard Worker
GetActualMallocAddress(void * const mem)50*77c1e3ccSAndroid Build Coastguard Worker static void *GetActualMallocAddress(void *const mem) {
51*77c1e3ccSAndroid Build Coastguard Worker const size_t *const malloc_addr_location = GetMallocAddressLocation(mem);
52*77c1e3ccSAndroid Build Coastguard Worker return (void *)(*malloc_addr_location);
53*77c1e3ccSAndroid Build Coastguard Worker }
54*77c1e3ccSAndroid Build Coastguard Worker
aom_memalign(size_t align,size_t size)55*77c1e3ccSAndroid Build Coastguard Worker void *aom_memalign(size_t align, size_t size) {
56*77c1e3ccSAndroid Build Coastguard Worker void *x = NULL;
57*77c1e3ccSAndroid Build Coastguard Worker if (!check_size_argument_overflow(1, size, align)) return NULL;
58*77c1e3ccSAndroid Build Coastguard Worker const size_t aligned_size = size + GetAllocationPaddingSize(align);
59*77c1e3ccSAndroid Build Coastguard Worker void *const addr = malloc(aligned_size);
60*77c1e3ccSAndroid Build Coastguard Worker if (addr) {
61*77c1e3ccSAndroid Build Coastguard Worker x = aom_align_addr((unsigned char *)addr + ADDRESS_STORAGE_SIZE, align);
62*77c1e3ccSAndroid Build Coastguard Worker SetActualMallocAddress(x, addr);
63*77c1e3ccSAndroid Build Coastguard Worker }
64*77c1e3ccSAndroid Build Coastguard Worker return x;
65*77c1e3ccSAndroid Build Coastguard Worker }
66*77c1e3ccSAndroid Build Coastguard Worker
aom_malloc(size_t size)67*77c1e3ccSAndroid Build Coastguard Worker void *aom_malloc(size_t size) { return aom_memalign(DEFAULT_ALIGNMENT, size); }
68*77c1e3ccSAndroid Build Coastguard Worker
aom_calloc(size_t num,size_t size)69*77c1e3ccSAndroid Build Coastguard Worker void *aom_calloc(size_t num, size_t size) {
70*77c1e3ccSAndroid Build Coastguard Worker if (!check_size_argument_overflow(num, size, DEFAULT_ALIGNMENT)) return NULL;
71*77c1e3ccSAndroid Build Coastguard Worker const size_t total_size = num * size;
72*77c1e3ccSAndroid Build Coastguard Worker void *const x = aom_malloc(total_size);
73*77c1e3ccSAndroid Build Coastguard Worker if (x) memset(x, 0, total_size);
74*77c1e3ccSAndroid Build Coastguard Worker return x;
75*77c1e3ccSAndroid Build Coastguard Worker }
76*77c1e3ccSAndroid Build Coastguard Worker
aom_free(void * memblk)77*77c1e3ccSAndroid Build Coastguard Worker void aom_free(void *memblk) {
78*77c1e3ccSAndroid Build Coastguard Worker if (memblk) {
79*77c1e3ccSAndroid Build Coastguard Worker void *addr = GetActualMallocAddress(memblk);
80*77c1e3ccSAndroid Build Coastguard Worker free(addr);
81*77c1e3ccSAndroid Build Coastguard Worker }
82*77c1e3ccSAndroid Build Coastguard Worker }
83