1*4a5d661aSToomas Soome /*
2*4a5d661aSToomas Soome * This module derived from code donated to the FreeBSD Project by
3*4a5d661aSToomas Soome * Matthew Dillon <dillon@backplane.com>
4*4a5d661aSToomas Soome *
5*4a5d661aSToomas Soome * Copyright (c) 1998 The FreeBSD Project
6*4a5d661aSToomas Soome * All rights reserved.
7*4a5d661aSToomas Soome *
8*4a5d661aSToomas Soome * Redistribution and use in source and binary forms, with or without
9*4a5d661aSToomas Soome * modification, are permitted provided that the following conditions
10*4a5d661aSToomas Soome * are met:
11*4a5d661aSToomas Soome * 1. Redistributions of source code must retain the above copyright
12*4a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer.
13*4a5d661aSToomas Soome * 2. Redistributions in binary form must reproduce the above copyright
14*4a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer in the
15*4a5d661aSToomas Soome * documentation and/or other materials provided with the distribution.
16*4a5d661aSToomas Soome *
17*4a5d661aSToomas Soome * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18*4a5d661aSToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19*4a5d661aSToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20*4a5d661aSToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21*4a5d661aSToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22*4a5d661aSToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23*4a5d661aSToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24*4a5d661aSToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25*4a5d661aSToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26*4a5d661aSToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27*4a5d661aSToomas Soome * SUCH DAMAGE.
28*4a5d661aSToomas Soome */
29*4a5d661aSToomas Soome
30*4a5d661aSToomas Soome #include <sys/cdefs.h>
31*4a5d661aSToomas Soome __FBSDID("$FreeBSD$");
32*4a5d661aSToomas Soome
33*4a5d661aSToomas Soome /*
34*4a5d661aSToomas Soome * MALLOC.C - malloc equivalent, runs on top of zalloc and uses sbrk
35*4a5d661aSToomas Soome */
36*4a5d661aSToomas Soome
37*4a5d661aSToomas Soome #include "zalloc_defs.h"
38*4a5d661aSToomas Soome
39*4a5d661aSToomas Soome static MemPool MallocPool;
40*4a5d661aSToomas Soome
41*4a5d661aSToomas Soome #ifdef DMALLOCDEBUG
42*4a5d661aSToomas Soome static int MallocMax;
43*4a5d661aSToomas Soome static int MallocCount;
44*4a5d661aSToomas Soome
45*4a5d661aSToomas Soome void mallocstats(void);
46*4a5d661aSToomas Soome #endif
47*4a5d661aSToomas Soome
48*4a5d661aSToomas Soome #ifdef malloc
49*4a5d661aSToomas Soome #undef malloc
50*4a5d661aSToomas Soome #undef free
51*4a5d661aSToomas Soome #endif
52*4a5d661aSToomas Soome
53*4a5d661aSToomas Soome void *
Malloc(size_t bytes,const char * file,int line)54*4a5d661aSToomas Soome Malloc(size_t bytes, const char *file, int line)
55*4a5d661aSToomas Soome {
56*4a5d661aSToomas Soome Guard *res;
57*4a5d661aSToomas Soome
58*4a5d661aSToomas Soome #ifdef USEENDGUARD
59*4a5d661aSToomas Soome bytes += MALLOCALIGN + 1;
60*4a5d661aSToomas Soome #else
61*4a5d661aSToomas Soome bytes += MALLOCALIGN;
62*4a5d661aSToomas Soome #endif
63*4a5d661aSToomas Soome
64*4a5d661aSToomas Soome while ((res = znalloc(&MallocPool, bytes)) == NULL) {
65*4a5d661aSToomas Soome int incr = (bytes + BLKEXTENDMASK) & ~BLKEXTENDMASK;
66*4a5d661aSToomas Soome char *base;
67*4a5d661aSToomas Soome
68*4a5d661aSToomas Soome if ((base = sbrk(incr)) == (char *)-1)
69*4a5d661aSToomas Soome return(NULL);
70*4a5d661aSToomas Soome zextendPool(&MallocPool, base, incr);
71*4a5d661aSToomas Soome zfree(&MallocPool, base, incr);
72*4a5d661aSToomas Soome }
73*4a5d661aSToomas Soome #ifdef DMALLOCDEBUG
74*4a5d661aSToomas Soome if (++MallocCount > MallocMax)
75*4a5d661aSToomas Soome MallocMax = MallocCount;
76*4a5d661aSToomas Soome #endif
77*4a5d661aSToomas Soome #ifdef USEGUARD
78*4a5d661aSToomas Soome res->ga_Magic = GAMAGIC;
79*4a5d661aSToomas Soome #endif
80*4a5d661aSToomas Soome res->ga_Bytes = bytes;
81*4a5d661aSToomas Soome #ifdef USEENDGUARD
82*4a5d661aSToomas Soome *((signed char *)res + bytes - 1) = -2;
83*4a5d661aSToomas Soome #endif
84*4a5d661aSToomas Soome
85*4a5d661aSToomas Soome return((char *)res + MALLOCALIGN);
86*4a5d661aSToomas Soome }
87*4a5d661aSToomas Soome
88*4a5d661aSToomas Soome void
Free(void * ptr,const char * file,int line)89*4a5d661aSToomas Soome Free(void *ptr, const char *file, int line)
90*4a5d661aSToomas Soome {
91*4a5d661aSToomas Soome size_t bytes;
92*4a5d661aSToomas Soome
93*4a5d661aSToomas Soome if (ptr != NULL) {
94*4a5d661aSToomas Soome Guard *res = (void *)((char *)ptr - MALLOCALIGN);
95*4a5d661aSToomas Soome
96*4a5d661aSToomas Soome if (file == NULL)
97*4a5d661aSToomas Soome file = "unknown";
98*4a5d661aSToomas Soome #ifdef USEGUARD
99*4a5d661aSToomas Soome if (res->ga_Magic == GAFREE) {
100*4a5d661aSToomas Soome printf("free: duplicate free @ %p from %s:%d\n", ptr, file, line);
101*4a5d661aSToomas Soome return;
102*4a5d661aSToomas Soome }
103*4a5d661aSToomas Soome if (res->ga_Magic != GAMAGIC)
104*4a5d661aSToomas Soome panic("free: guard1 fail @ %p from %s:%d", ptr, file, line);
105*4a5d661aSToomas Soome res->ga_Magic = GAFREE;
106*4a5d661aSToomas Soome #endif
107*4a5d661aSToomas Soome #ifdef USEENDGUARD
108*4a5d661aSToomas Soome if (*((signed char *)res + res->ga_Bytes - 1) == -1) {
109*4a5d661aSToomas Soome printf("free: duplicate2 free @ %p from %s:%d\n", ptr, file, line);
110*4a5d661aSToomas Soome return;
111*4a5d661aSToomas Soome }
112*4a5d661aSToomas Soome if (*((signed char *)res + res->ga_Bytes - 1) != -2)
113*4a5d661aSToomas Soome panic("free: guard2 fail @ %p + %zu from %s:%d", ptr, res->ga_Bytes - MALLOCALIGN, file, line);
114*4a5d661aSToomas Soome *((signed char *)res + res->ga_Bytes - 1) = -1;
115*4a5d661aSToomas Soome #endif
116*4a5d661aSToomas Soome
117*4a5d661aSToomas Soome bytes = res->ga_Bytes;
118*4a5d661aSToomas Soome zfree(&MallocPool, res, bytes);
119*4a5d661aSToomas Soome #ifdef DMALLOCDEBUG
120*4a5d661aSToomas Soome --MallocCount;
121*4a5d661aSToomas Soome #endif
122*4a5d661aSToomas Soome }
123*4a5d661aSToomas Soome }
124*4a5d661aSToomas Soome
125*4a5d661aSToomas Soome
126*4a5d661aSToomas Soome void *
Calloc(size_t n1,size_t n2,const char * file,int line)127*4a5d661aSToomas Soome Calloc(size_t n1, size_t n2, const char *file, int line)
128*4a5d661aSToomas Soome {
129*4a5d661aSToomas Soome uintptr_t bytes = (uintptr_t)n1 * (uintptr_t)n2;
130*4a5d661aSToomas Soome void *res;
131*4a5d661aSToomas Soome
132*4a5d661aSToomas Soome if ((res = Malloc(bytes, file, line)) != NULL) {
133*4a5d661aSToomas Soome bzero(res, bytes);
134*4a5d661aSToomas Soome #ifdef DMALLOCDEBUG
135*4a5d661aSToomas Soome if (++MallocCount > MallocMax)
136*4a5d661aSToomas Soome MallocMax = MallocCount;
137*4a5d661aSToomas Soome #endif
138*4a5d661aSToomas Soome }
139*4a5d661aSToomas Soome return(res);
140*4a5d661aSToomas Soome }
141*4a5d661aSToomas Soome
142*4a5d661aSToomas Soome /*
143*4a5d661aSToomas Soome * realloc() - I could be fancier here and free the old buffer before
144*4a5d661aSToomas Soome * allocating the new one (saving potential fragmentation
145*4a5d661aSToomas Soome * and potential buffer copies). But I don't bother.
146*4a5d661aSToomas Soome */
147*4a5d661aSToomas Soome
148*4a5d661aSToomas Soome void *
Realloc(void * ptr,size_t size,const char * file,int line)149*4a5d661aSToomas Soome Realloc(void *ptr, size_t size, const char *file, int line)
150*4a5d661aSToomas Soome {
151*4a5d661aSToomas Soome void *res;
152*4a5d661aSToomas Soome size_t old;
153*4a5d661aSToomas Soome
154*4a5d661aSToomas Soome if ((res = Malloc(size, file, line)) != NULL) {
155*4a5d661aSToomas Soome if (ptr) {
156*4a5d661aSToomas Soome old = *(size_t *)((char *)ptr - MALLOCALIGN) - MALLOCALIGN;
157*4a5d661aSToomas Soome if (old < size)
158*4a5d661aSToomas Soome bcopy(ptr, res, old);
159*4a5d661aSToomas Soome else
160*4a5d661aSToomas Soome bcopy(ptr, res, size);
161*4a5d661aSToomas Soome Free(ptr, file, line);
162*4a5d661aSToomas Soome } else {
163*4a5d661aSToomas Soome #ifdef DMALLOCDEBUG
164*4a5d661aSToomas Soome if (++MallocCount > MallocMax)
165*4a5d661aSToomas Soome MallocMax = MallocCount;
166*4a5d661aSToomas Soome #ifdef EXITSTATS
167*4a5d661aSToomas Soome if (DidAtExit == 0) {
168*4a5d661aSToomas Soome DidAtExit = 1;
169*4a5d661aSToomas Soome atexit(mallocstats);
170*4a5d661aSToomas Soome }
171*4a5d661aSToomas Soome #endif
172*4a5d661aSToomas Soome #endif
173*4a5d661aSToomas Soome }
174*4a5d661aSToomas Soome }
175*4a5d661aSToomas Soome return(res);
176*4a5d661aSToomas Soome }
177*4a5d661aSToomas Soome
178*4a5d661aSToomas Soome void *
Reallocf(void * ptr,size_t size,const char * file,int line)179*4a5d661aSToomas Soome Reallocf(void *ptr, size_t size, const char *file, int line)
180*4a5d661aSToomas Soome {
181*4a5d661aSToomas Soome void *res;
182*4a5d661aSToomas Soome
183*4a5d661aSToomas Soome if ((res = Realloc(ptr, size, file, line)) == NULL)
184*4a5d661aSToomas Soome Free(ptr, file, line);
185*4a5d661aSToomas Soome return(res);
186*4a5d661aSToomas Soome }
187*4a5d661aSToomas Soome
188*4a5d661aSToomas Soome #ifdef DMALLOCDEBUG
189*4a5d661aSToomas Soome
190*4a5d661aSToomas Soome void
mallocstats(void)191*4a5d661aSToomas Soome mallocstats(void)
192*4a5d661aSToomas Soome {
193*4a5d661aSToomas Soome printf("Active Allocations: %d/%d\n", MallocCount, MallocMax);
194*4a5d661aSToomas Soome #ifdef ZALLOCDEBUG
195*4a5d661aSToomas Soome zallocstats(&MallocPool);
196*4a5d661aSToomas Soome #endif
197*4a5d661aSToomas Soome }
198*4a5d661aSToomas Soome
199*4a5d661aSToomas Soome #endif
200*4a5d661aSToomas Soome
201