1 /* $OpenBSD: alloc.c,v 1.19 2018/01/16 22:52:32 jca Exp $ */
3 /* Public domain, like most of the rest of ksh */
6 * area-based allocation built on malloc/free
31 for (l
= ap
->freelist
; l
!= NULL
; l
= l2
) {
38 #define L2P(l) ( (void *)(((char *)(l)) + sizeof(struct link)) )
39 #define P2L(p) ( (struct link *)(((char *)(p)) - sizeof(struct link)) )
42 alloc(size_t size
, Area
*ap
)
46 /* ensure that we don't overflow by allocating space for link */
47 if (size
> SIZE_MAX
- sizeof(struct link
))
48 internal_errorf("unable to allocate memory");
50 l
= malloc(sizeof(struct link
) + size
);
52 internal_errorf("unable to allocate memory");
53 l
->next
= ap
->freelist
;
56 ap
->freelist
->prev
= l
;
63 * Copied from calloc().
65 * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
66 * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
68 #define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4))
71 areallocarray(void *ptr
, size_t nmemb
, size_t size
, Area
*ap
)
73 /* condition logic cloned from calloc() */
74 if ((nmemb
>= MUL_NO_OVERFLOW
|| size
>= MUL_NO_OVERFLOW
) &&
75 nmemb
> 0 && SIZE_MAX
/ nmemb
< size
) {
76 internal_errorf("unable to allocate memory");
79 return aresize(ptr
, nmemb
* size
, ap
);
83 aresize(void *ptr
, size_t size
, Area
*ap
)
85 struct link
*l
, *l2
, *lprev
, *lnext
;
88 return alloc(size
, ap
);
90 /* ensure that we don't overflow by allocating space for link */
91 if (size
> SIZE_MAX
- sizeof(struct link
))
92 internal_errorf("unable to allocate memory");
98 l2
= realloc(l
, sizeof(struct link
) + size
);
100 internal_errorf("unable to allocate memory");
112 afree(void *ptr
, Area
*ap
)
121 l
->prev
->next
= l
->next
;
123 ap
->freelist
= l
->next
;
125 l
->next
->prev
= l
->prev
;