03b8f0882b8ddf8de84cc603006e1d206f21502d
[platform/upstream/bash.git] / lib / malloc / malloc.c
1 /* malloc.c - dynamic memory allocation for bash. */
2
3 /*  Copyright (C) 1985, 1987, 1997 Free Software Foundation, Inc.
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2, or (at your option)
8     any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
18
19 In other words, you are welcome to use, share and improve this program.
20 You are forbidden to forbid anyone else to use, share and improve
21 what you give them.   Help stamp out software-hoarding!  */
22
23 /*
24  * @(#)nmalloc.c 1 (Caltech) 2/21/82
25  *
26  *      U of M Modified: 20 Jun 1983 ACT: strange hacks for Emacs
27  *
28  *      Nov 1983, Mike@BRL, Added support for 4.1C/4.2 BSD.
29  *
30  * This is a very fast storage allocator.  It allocates blocks of a small 
31  * number of different sizes, and keeps free lists of each size.  Blocks
32  * that don't exactly fit are passed up to the next larger size.  In this 
33  * implementation, the available sizes are (2^n)-4 (or -16) bytes long.
34  * This is designed for use in a program that uses vast quantities of
35  * memory, but bombs when it runs out.  To make it a little better, it
36  * warns the user when he starts to get near the end.
37  *
38  * June 84, ACT: modified rcheck code to check the range given to malloc,
39  * rather than the range determined by the 2-power used.
40  *
41  * Jan 85, RMS: calls malloc_warning to issue warning on nearly full.
42  * No longer Emacs-specific; can serve as all-purpose malloc for GNU.
43  * You should call malloc_init to reinitialize after loading dumped Emacs.
44  * Call malloc_stats to get info on memory stats if MALLOC_STATS turned on.
45  * realloc knows how to return same block given, just changing its size,
46  * if the power of 2 is correct.
47  */
48
49 /*
50  * nextf[i] is the pointer to the next free block of size 2^(i+3).  The
51  * smallest allocatable block is 8 bytes.  The overhead information will
52  * go in the first int of the block, and the returned pointer will point
53  * to the second.
54  */
55
56 /* Define this to have free() write 0xcf into memory as it's freed, to
57    uncover callers that refer to freed memory. */
58 /* SCO 3.2v4 getcwd and possibly other libc routines fail with MEMSCRAMBLE */
59 #if !defined (NO_MEMSCRAMBLE)
60 #  define MEMSCRAMBLE
61 #endif
62
63 #if defined (HAVE_CONFIG_H)
64 #  include <config.h>
65 #endif /* HAVE_CONFIG_H */
66
67 #if defined (SHELL)
68 #  include "bashtypes.h"
69 #  include "stdc.h"
70 #else
71 #  include <sys/types.h>
72
73 #  ifndef __P
74 #    if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus)
75 #      define __P(protos) protos
76 #    else
77 #      define __P(protos) ()
78 #    endif
79 #  endif
80
81 #endif
82
83 #if defined (HAVE_UNISTD_H)
84 #  include <unistd.h>
85 #endif
86
87 /* Determine which kind of system this is.  */
88 #include <signal.h>
89
90 #if defined (HAVE_STRING_H)
91 #  include <string.h>
92 #else
93 #  include <strings.h>
94 #endif
95
96 #include <stdio.h>
97
98 /* Define getpagesize () if the system does not.  */
99 #ifndef HAVE_GETPAGESIZE
100 #  include "getpagesize.h"
101 #endif
102
103 #include "imalloc.h"
104 #ifdef MALLOC_STATS
105 #  include "mstats.h"
106 #endif
107 #ifdef MALLOC_REGISTER
108 #  include "table.h"
109 #endif
110
111 /* System-specific omissions. */
112 #ifdef HPUX
113 #  define NO_VALLOC
114 #endif
115
116 #define NBUCKETS        30
117
118 #define ISALLOC ((char) 0xf7)   /* magic byte that implies allocation */
119 #define ISFREE ((char) 0x54)    /* magic byte that implies free block */
120                                 /* this is for error checking only */
121 #define ISMEMALIGN ((char) 0xd6)  /* Stored before the value returned by
122                                      memalign, with the rest of the word
123                                      being the distance to the true
124                                      beginning of the block.  */
125
126
127 /* We have a flag indicating whether memory is allocated, an index in
128    nextf[], a size field, and a sentinel value to determine whether or
129    not a caller wrote before the start of allocated memory; to realloc()
130    memory we either copy mh_nbytes or just change mh_nbytes if there is
131    enough room in the block for the new size.  Range checking is always
132    done. */
133 union mhead {
134   bits64_t mh_align;                                            /* 8 */
135   struct {
136     char mi_alloc;              /* ISALLOC or ISFREE */         /* 1 */
137     char mi_index;              /* index in nextf[] */          /* 1 */
138     /* Remainder are valid only when block is allocated */
139     u_bits16_t mi_magic2;       /* should be == MAGIC2 */       /* 2 */
140     u_bits32_t mi_nbytes;       /* # of bytes allocated */      /* 4 */
141   } minfo;
142 };
143 #define mh_alloc        minfo.mi_alloc
144 #define mh_index        minfo.mi_index
145 #define mh_nbytes       minfo.mi_nbytes
146 #define mh_magic2       minfo.mi_magic2
147
148 /* Access free-list pointer of a block.
149    It is stored at block + sizeof (char *).
150    This is not a field in the minfo structure member of union mhead
151    because we want sizeof (union mhead)
152    to describe the overhead for when the block is in use,
153    and we do not want the free-list pointer to count in that.  */
154
155 #define CHAIN(a) \
156   (*(union mhead **) (sizeof (char *) + (char *) (a)))
157
158 /* To implement range checking, we write magic values in at the beginning
159    and end of each allocated block, and make sure they are undisturbed
160    whenever a free or a realloc occurs. */
161
162 /* Written in each of the 4 bytes following the block's real space */
163 #define MAGIC1 0x55
164 /* Written in the 2 bytes before the block's real space (-4 bytes) */
165 #define MAGIC2 0x5555
166 #define MSLOP  4                /* 4 bytes extra for MAGIC1s */
167
168 /* How many bytes are actually allocated for a request of size N --
169    rounded up to nearest multiple of 8 after accounting for malloc
170    overhead. */
171 #define ALLOCATED_BYTES(n)  (((n) + sizeof (union mhead) + MSLOP + 7) & ~7)
172
173 #define ASSERT(p) \
174   do \
175     { \
176       if (!(p)) xbotch((PTR_T)0, ERR_ASSERT_FAILED, __STRING(p), file, line); \
177     } \
178   while (0)
179
180 /* Minimum and maximum bucket indices for block splitting (and to bound
181    the search for a block to split). */
182 #define SPLIT_MIN       3
183 #define SPLIT_MID       11      /* XXX - was 9 */
184 #define SPLIT_MAX       14      /* XXX - was 12 */
185
186 /* Minimum and maximum bucket indices for block coalescing. */
187 #define COMBINE_MIN     6
188 #define COMBINE_MAX     (pagebucket - 1)
189
190 #define MIN_COMBINE_FREE        4
191
192 /* Flags for the internal functions. */
193 #define MALLOC_WRAPPER  0x01    /* wrapper function */
194 #define MALLOC_INTERNAL 0x02    /* internal function calling another */
195 #define MALLOC_NOTRACE  0x04    /* don't trace this allocation or free */
196 #define MALLOC_NOREG    0x08    /* don't register this allocation or free */
197
198 /* Future use. */
199 #define ERR_DUPFREE             0x01
200 #define ERR_UNALLOC             0x02
201 #define ERR_UNDERFLOW           0x04    
202 #define ERR_ASSERT_FAILED       0x08
203
204 /* Evaluates to true if NB is appropriate for bucket NU.  NB is adjusted
205    appropriately by the caller to account for malloc overhead. */
206 #define IN_BUCKET(nb, nu) \
207   ((nb) > (4 << (nu)) && ((nb) <= (8 << (nu))))
208
209 /* nextf[i] is free list of blocks of size 2**(i + 3)  */
210
211 static union mhead *nextf[NBUCKETS];
212
213 /* busy[i] is nonzero while allocation of block size i is in progress.  */
214
215 static char busy[NBUCKETS];
216
217 static int pagesz;      /* system page size. */
218 static int pagebucket;  /* bucket for requests a page in size */
219 static int maxbuck;     /* highest bucket receiving allocation request. */
220
221 /* Declarations for internal functions */
222 static PTR_T internal_malloc __P((size_t, const char *, int, int));
223 static PTR_T internal_realloc __P((PTR_T, size_t, const char *, int, int));
224 static void internal_free __P((PTR_T, const char *, int, int));
225 static PTR_T internal_memalign __P((unsigned int, size_t, const char *, int, int));
226 #ifndef NO_CALLOC
227 static PTR_T internal_calloc __P((size_t, size_t, const char *, int, int));
228 static void internal_cfree __P((PTR_T, const char *, int, int));
229 #endif
230 #ifndef NO_VALLOC
231 static PTR_T internal_valloc __P((size_t, const char *, int, int));
232 #endif
233
234 #if defined (botch)
235 extern void botch ();
236 #else
237 static void botch __P((const char *, const char *, int));
238 #endif
239 static void xbotch __P((PTR_T, int, const char *, const char *, int));
240
241 #ifdef MALLOC_STATS
242 extern struct _malstats _mstats;
243 #endif /* MALLOC_STATS */
244
245 #if !HAVE_DECL_SBRK
246 extern char *sbrk ();
247 #endif /* !HAVE_DECL_SBRK */
248
249 #ifdef SHELL
250 extern int interrupt_immediately;
251 extern int signal_is_trapped __P((int));
252 #endif
253
254 /* Debugging variables available to applications. */
255 int malloc_flags = 0;   /* future use */
256 int malloc_trace = 0;   /* trace allocations and frees to stderr */
257 int malloc_register = 0;        /* future use */
258
259 #if !defined (botch)
260 static void
261 botch (s, file, line)
262 {
263   fprintf (stderr, "malloc: failed assertion: %s\n", s);
264   (void)fflush (stderr);
265   abort ();
266 }
267 #endif
268
269 /* print the file and line number that caused the assertion failure and
270    call botch() to do whatever the application wants with the information */
271 static void
272 xbotch (mem, e, s, file, line)
273      PTR_T mem;
274      int e;
275      const char *s;
276      const char *file;
277      int line;
278 {
279   fprintf (stderr, "\r\nmalloc: %s:%d: assertion botched\r\n",
280                         file ? file : "unknown", line);
281 #ifdef MALLOC_REGISTER
282   if (mem != NULL && malloc_register)
283     mregister_describe_mem (mem, stderr);
284 #endif
285   (void)fflush (stderr);
286   botch(s, file, line);
287 }
288
289 #if 0
290 /* Coalesce two adjacent free blocks off the free list for size NU - 1,
291    as long as there are at least MIN_COMBINE_FREE free blocks and we
292    can find two adjacent free blocks.  nextf[NU -1] is assumed to not
293    be busy; the caller (morecore()) checks for this. */
294 static void
295 bcoalesce (nu)
296      register int nu;
297 {
298   register union mhead *mp, *mp1, *mp2;
299   register int nfree, nbuck;
300   unsigned long siz;
301
302   nbuck = nu - 1;
303   if (nextf[nbuck] == 0)
304     return;
305
306   nfree = 1;
307   mp1 = nextf[nbuck];
308   mp = CHAIN (mp1);
309   mp2 = (union mhead *)0;
310   while (CHAIN (mp))
311     {
312       mp2 = mp1;
313       mp1 = mp;
314       mp = CHAIN (mp);
315       nfree++;
316       /* We may not want to run all the way through the free list here;
317          if we do not, we need to check a threshold value here and break
318          if nfree exceeds it. */
319     }
320   if (nfree < MIN_COMBINE_FREE)
321     return;
322   /* OK, now we have mp1 pointing to the block we want to add to nextf[NU].
323      CHAIN(mp2) must equal mp1.  Check that mp1 and mp are adjacent. */
324   if (CHAIN(mp2) != mp1)
325     xbotch ((PTR_T)0, 0, "bcoalesce: CHAIN(mp2) != mp1", (char *)NULL, 0);
326   siz = 1 << (nbuck + 3);
327   if (CHAIN (mp1) != (union mhead *)((char *)mp1 + siz))
328     return;     /* not adjacent */
329
330 #ifdef MALLOC_STATS
331   _mstats.tbcoalesce++;
332 #endif
333
334   /* Since they are adjacent, remove them from the free list */
335   CHAIN (mp2) = CHAIN (mp);
336
337   /* And add the combined two blocks to nextf[NU]. */
338   mp1->mh_alloc = ISFREE;
339   mp1->mh_index = nu;
340   CHAIN (mp1) = nextf[nu];
341   nextf[nu] = mp1;
342 }
343 #endif
344
345 /* Split a block at index > NU (but less than SPLIT_MAX) into a set of
346    blocks of the correct size, and attach them to nextf[NU].  nextf[NU]
347    is assumed to be empty.  Must be called with signals blocked (e.g.,
348    by morecore()). */
349 static void
350 bsplit (nu)
351      register int nu;
352 {
353   register union mhead *mp;
354   int nbuck, nblks, split_max;
355   unsigned long siz;
356
357   split_max = (maxbuck > SPLIT_MAX) ? maxbuck : SPLIT_MAX;
358
359   if (nu >= SPLIT_MID)
360     {
361       for (nbuck = split_max; nbuck > nu; nbuck--)
362         {
363           if (busy[nbuck] || nextf[nbuck] == 0)
364             continue;
365           break;
366         }
367     }
368   else
369     {
370       for (nbuck = nu + 1; nbuck <= split_max; nbuck++)
371         {
372           if (busy[nbuck] || nextf[nbuck] == 0)
373             continue;
374           break;
375         }
376     }
377
378   if (nbuck > split_max || nbuck <= nu)
379     return;
380
381   /* XXX might want to split only if nextf[nbuck] has >= 2 blocks free
382      and nbuck is below some threshold. */
383
384 #ifdef MALLOC_STATS
385   _mstats.tbsplit++;
386   _mstats.nsplit[nbuck]++;
387 #endif
388
389   /* Figure out how many blocks we'll get. */
390   siz = (1 << (nu + 3));
391   nblks = (1 << (nbuck + 3)) / siz;
392
393   /* Remove the block from the chain of larger blocks. */
394   mp = nextf[nbuck];
395   nextf[nbuck] = CHAIN (mp);
396
397   /* Split the block and put it on the requested chain. */
398   nextf[nu] = mp;
399   while (1)
400     {
401       mp->mh_alloc = ISFREE;
402       mp->mh_index = nu;
403       if (--nblks <= 0) break;
404       CHAIN (mp) = (union mhead *)((char *)mp + siz);
405       mp = (union mhead *)((char *)mp + siz);
406     }
407   CHAIN (mp) = 0;
408 }
409
410 static void
411 block_signals (setp, osetp)
412      sigset_t *setp, *osetp;
413 {
414 #ifdef HAVE_POSIX_SIGNALS
415   sigfillset (setp);
416   sigemptyset (osetp);
417   sigprocmask (SIG_BLOCK, setp, osetp);
418 #else
419 #  if defined (HAVE_BSD_SIGNALS)
420   *osetp = sigsetmask (-1);
421 #  endif
422 #endif
423 }
424
425 static void
426 unblock_signals (setp, osetp)
427      sigset_t *setp, *osetp;
428 {
429 #ifdef HAVE_POSIX_SIGNALS
430   sigprocmask (SIG_SETMASK, osetp, (sigset_t *)NULL);
431 #else
432 #  if defined (HAVE_BSD_SIGNALS)
433   sigsetmask (*osetp);
434 #  endif
435 #endif
436 }
437   
438 static void
439 morecore (nu)                   /* ask system for more memory */
440      register int nu;           /* size index to get more of  */
441 {
442   register union mhead *mp;
443   register int nblks;
444   register long siz;
445   long sbrk_amt;                /* amount to get via sbrk() */
446   sigset_t set, oset;
447   int blocked_sigs;
448
449   /* Block all signals in case we are executed from a signal handler. */
450   blocked_sigs = 0;
451 #ifdef SHELL
452   if (interrupt_immediately || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD))
453 #endif
454     {
455       block_signals (&set, &oset);
456       blocked_sigs = 1;
457     }
458
459   siz = 1 << (nu + 3);  /* size of desired block for nextf[nu] */
460
461   if (siz < 0)
462     goto morecore_done;         /* oops */
463
464 #ifdef MALLOC_STATS
465   _mstats.nmorecore[nu]++;
466 #endif
467
468   /* Try to split a larger block here, if we're within the range of sizes
469      to split. */
470   if (nu >= SPLIT_MIN)
471     {
472       bsplit (nu);
473       if (nextf[nu] != 0)
474         goto morecore_done;
475     }
476
477 #if 0
478   /* Try to coalesce two adjacent blocks from the free list on nextf[nu - 1],
479      if we can, and we're withing the range of the block coalescing limits. */
480   if (nu >= COMBINE_MIN && nu < COMBINE_MAX && busy[nu - 1] == 0 && nextf[nu - 1])
481     {
482       bcoalesce (nu);
483       if (nextf[nu] != 0)
484         goto morecore_done;
485     }
486 #endif
487
488   /* Take at least a page, and figure out how many blocks of the requested
489      size we're getting. */
490   if (siz <= pagesz)
491     {
492       sbrk_amt = pagesz;
493       nblks = sbrk_amt / siz;
494     }
495   else
496     {
497       /* We always want to request an integral multiple of the page size
498          from the kernel, so let's compute whether or not `siz' is such
499          an amount.  If it is, we can just request it.  If not, we want
500          the smallest integral multiple of pagesize that is larger than
501          `siz' and will satisfy the request. */
502       sbrk_amt = siz % pagesz;
503       if (sbrk_amt == 0)
504         sbrk_amt = siz;
505       else
506         sbrk_amt = siz + pagesz - sbrk_amt;
507       nblks = 1;
508     }
509
510 #ifdef MALLOC_STATS
511   _mstats.nsbrk++;
512   _mstats.tsbrk += sbrk_amt;
513 #endif
514
515   mp = (union mhead *) sbrk (sbrk_amt);
516
517   /* Totally out of memory. */
518   if ((long)mp == -1)
519     goto morecore_done;
520
521   /* shouldn't happen, but just in case -- require 8-byte alignment */
522   if ((long)mp & 7)
523     {
524       mp = (union mhead *) (((long)mp + 7) & ~7);
525       nblks--;
526     }
527
528   /* save new header and link the nblks blocks together */
529   nextf[nu] = mp;
530   while (1)
531     {
532       mp->mh_alloc = ISFREE;
533       mp->mh_index = nu;
534       if (--nblks <= 0) break;
535       CHAIN (mp) = (union mhead *)((char *)mp + siz);
536       mp = (union mhead *)((char *)mp + siz);
537     }
538   CHAIN (mp) = 0;
539
540 morecore_done:
541   if (blocked_sigs)
542     unblock_signals (&set, &oset);
543 }
544
545 #if defined (MEMSCRAMBLE) || !defined (NO_CALLOC)
546 static char *
547 zmemset (s, c, n)
548      char *s;
549      int c;
550      register int n;
551 {
552   register char *sp;
553
554   sp = s;
555   while (--n >= 0)
556     *sp++ = c;
557   return (s);
558 }
559 #endif /* MEMSCRAMBLE || !NO_CALLOC */
560
561 static void
562 malloc_debug_dummy ()
563 {
564   write (1, "malloc_debug_dummy\n", 19);
565 }
566
567 static PTR_T
568 internal_malloc (n, file, line, flags)          /* get a block */
569      size_t n;
570      const char *file;
571      int line, flags;
572 {
573   register union mhead *p;
574   register long nbytes;
575   register int nunits;
576
577   /* Get the system page size and align break pointer so everything will
578      be page-aligned.  The page size must be at least 1K -- anything
579      smaller is increased. */
580   if (pagesz == 0)
581     {
582       register long sbrk_needed;
583
584       pagesz = getpagesize ();
585       if (pagesz < 1024)
586         pagesz = 1024;
587       /* OK, how much do we need to allocate to make things page-aligned?
588          This partial page is wasted space.  Once we figure out how much
589          to advance the break pointer, go ahead and do it. */
590       sbrk_needed = pagesz - ((long)sbrk (0) & (pagesz - 1));   /* sbrk(0) % pagesz */
591       if (sbrk_needed < 0)
592         sbrk_needed += pagesz;
593       /* Now allocate the wasted space. */
594       if (sbrk_needed)
595         {
596 #ifdef MALLOC_STATS
597           _mstats.nsbrk++;
598           _mstats.tsbrk += sbrk_needed;
599 #endif
600           if ((long)sbrk (sbrk_needed) == -1)
601             return (NULL);
602         }
603       nunits = 0;
604       nbytes = 8;
605       while (pagesz > nbytes)
606         {
607           nbytes <<= 1;
608           nunits++;
609         }
610       pagebucket = nunits;
611     }
612  
613   /* Figure out how many bytes are required, rounding up to the nearest
614      multiple of 8, then figure out which nextf[] area to use.  Try to
615      be smart about where to start searching -- if the number of bytes
616      needed is greater than the page size, we can start at pagebucket. */
617   nbytes = ALLOCATED_BYTES(n);
618   nunits = 0;
619   if (nbytes <= (pagesz >> 1))
620     {
621       register unsigned int shiftr;
622
623       shiftr = (nbytes - 1) >> 2;       /* == (nbytes - 1) / 4 */
624       while (shiftr >>= 1)              /* == (nbytes - 1) / {8,16,32,...} */
625         nunits++;
626     }
627   else
628     {
629       register u_bits32_t amt;
630
631       nunits = pagebucket;
632       amt = pagesz;
633       while (nbytes > amt)
634         {
635           amt <<= 1;
636           nunits++;
637         }
638     }
639
640   /* Silently reject too-large requests. */
641   if (nunits >= NBUCKETS)
642     return ((PTR_T) NULL);
643
644   /* In case this is reentrant use of malloc from signal handler,
645      pick a block size that no other malloc level is currently
646      trying to allocate.  That's the easiest harmless way not to
647      interfere with the other level of execution.  */
648 #ifdef MALLOC_STATS
649   if (busy[nunits]) _mstats.nrecurse++;
650 #endif
651   while (busy[nunits]) nunits++;
652   busy[nunits] = 1;
653
654   if (nunits > maxbuck)
655     maxbuck = nunits;
656
657   /* If there are no blocks of the appropriate size, go get some */
658   if (nextf[nunits] == 0)
659     morecore (nunits);
660
661   /* Get one block off the list, and set the new list head */
662   if ((p = nextf[nunits]) == NULL)
663     {
664       busy[nunits] = 0;
665       return NULL;
666     }
667   nextf[nunits] = CHAIN (p);
668   busy[nunits] = 0;
669
670   /* Check for free block clobbered */
671   /* If not for this check, we would gobble a clobbered free chain ptr
672      and bomb out on the NEXT allocate of this size block */
673   if (p->mh_alloc != ISFREE || p->mh_index != nunits)
674     xbotch ((PTR_T)0, 0, "malloc: block on free list clobbered", file, line);
675
676   /* Fill in the info, and set up the magic numbers for range checking. */
677   p->mh_alloc = ISALLOC;
678   p->mh_magic2 = MAGIC2;
679   p->mh_nbytes = n;
680   {
681     register char  *m = (char *) (p + 1) + n;
682
683     *m++ = MAGIC1, *m++ = MAGIC1, *m++ = MAGIC1, *m = MAGIC1;
684   }
685
686 #ifdef MEMSCRAMBLE
687   zmemset ((char *)(p + 1), 0xdf, n);   /* scramble previous contents */
688 #endif
689 #ifdef MALLOC_STATS
690   _mstats.nmalloc[nunits]++;
691   _mstats.tmalloc[nunits]++;
692   _mstats.nmal++;
693 #endif /* MALLOC_STATS */
694
695 #ifdef MALLOC_TRACE
696   if (malloc_trace && (flags & MALLOC_NOTRACE) == 0)
697     mtrace_alloc ("malloc", p + 1, n, file, line);
698 #endif
699
700 #ifdef MALLOC_REGISTER
701   if (malloc_register && (flags & MALLOC_NOREG) == 0)
702     mregister_alloc ("malloc", p + 1, n, file, line);
703 #endif
704
705   return (char *) (p + 1);      /* XXX - should be cast to PTR_T? */
706 }
707
708 static void
709 internal_free (mem, file, line, flags)
710      PTR_T mem;
711      const char *file;
712      int line, flags;
713 {
714   register union mhead *p;
715   register char *ap;
716   register int nunits;
717   register unsigned int nbytes;
718   int ubytes;           /* caller-requested size */
719
720   if ((ap = (char *)mem) == 0)
721     return;
722
723   p = (union mhead *) ap - 1;
724
725   if (p->mh_alloc == ISMEMALIGN)
726     {
727       ap -= p->mh_nbytes;
728       p = (union mhead *) ap - 1;
729     }
730
731 #if defined (MALLOC_TRACE) || defined (MALLOC_REGISTER)
732   if (malloc_trace || malloc_register)
733     ubytes = p->mh_nbytes;
734 #endif
735
736   if (p->mh_alloc != ISALLOC)
737     {
738       if (p->mh_alloc == ISFREE)
739         xbotch (mem, ERR_DUPFREE,
740                 "free: called with already freed block argument", file, line);
741       else
742         xbotch (mem, ERR_UNALLOC,
743                 "free: called with unallocated block argument", file, line);
744     }
745
746   ASSERT (p->mh_magic2 == MAGIC2);
747
748   nunits = p->mh_index;
749   nbytes = ALLOCATED_BYTES(p->mh_nbytes);
750   /* Since the sizeof(u_bits32_t) bytes before the memory handed to the user
751      are now used for the number of bytes allocated, a simple check of
752      mh_magic2 is no longer sufficient to catch things like p[-1] = 'x'.
753      We sanity-check the value of mh_nbytes against the size of the blocks
754      in the appropriate bucket before we use it.  This can still cause problems
755      and obscure errors if mh_nbytes is wrong but still within range; the
756      checks against MAGIC1 will probably fail then.  Using MALLOC_REGISTER
757      will help here, since it saves the original number of bytes requested. */
758   if (IN_BUCKET(nbytes, nunits) == 0)
759     xbotch (mem, ERR_UNDERFLOW,
760             "free: underflow detected; mh_nbytes out of range", file, line);
761
762   ap += p->mh_nbytes;
763   ASSERT (*ap++ == MAGIC1); ASSERT (*ap++ == MAGIC1);
764   ASSERT (*ap++ == MAGIC1); ASSERT (*ap   == MAGIC1);
765
766 #ifdef MEMSCRAMBLE
767   zmemset (mem, 0xcf, p->mh_nbytes);
768 #endif
769
770   ASSERT (nunits < NBUCKETS);
771   p->mh_alloc = ISFREE;
772
773   if (busy[nunits] == 1)
774     return;     /* this is bogus, but at least it won't corrupt the chains */
775
776   /* Protect against signal handlers calling malloc.  */
777   busy[nunits] = 1;
778   /* Put this block on the free list.  */
779   CHAIN (p) = nextf[nunits];
780   nextf[nunits] = p;
781   busy[nunits] = 0;
782
783 #ifdef MALLOC_STATS
784   _mstats.nmalloc[nunits]--;
785   _mstats.nfre++;
786 #endif /* MALLOC_STATS */
787
788 #ifdef MALLOC_TRACE
789   if (malloc_trace && (flags & MALLOC_NOTRACE) == 0)
790     mtrace_free (mem, ubytes, file, line);
791 #endif
792
793 #ifdef MALLOC_REGISTER
794   if (malloc_register && (flags & MALLOC_NOREG) == 0)
795     mregister_free (mem, ubytes, file, line);
796 #endif
797 }
798
799 static PTR_T
800 internal_realloc (mem, n, file, line, flags)
801      PTR_T mem;
802      register size_t n;
803      const char *file;
804      int line, flags;
805 {
806   register union mhead *p;
807   register u_bits32_t tocopy;
808   register unsigned int nbytes;
809   register int nunits;
810   register char *m;
811
812 #ifdef MALLOC_STATS
813   _mstats.nrealloc++;
814 #endif
815
816   if (n == 0)
817     {
818       internal_free (mem, file, line, MALLOC_INTERNAL);
819       return (NULL);
820     }
821   if ((p = (union mhead *) mem) == 0)
822     return internal_malloc (n, file, line, MALLOC_INTERNAL);
823
824   p--;
825   nunits = p->mh_index;
826   ASSERT (nunits < NBUCKETS);
827
828   if (p->mh_alloc != ISALLOC)
829     xbotch (mem, ERR_UNALLOC,
830             "realloc: called with unallocated block argument", file, line);
831
832   ASSERT (p->mh_magic2 == MAGIC2);
833   nbytes = ALLOCATED_BYTES(p->mh_nbytes);
834   /* Since the sizeof(u_bits32_t) bytes before the memory handed to the user
835      are now used for the number of bytes allocated, a simple check of
836      mh_magic2 is no longer sufficient to catch things like p[-1] = 'x'.
837      We sanity-check the value of mh_nbytes against the size of the blocks
838      in the appropriate bucket before we use it.  This can still cause problems
839      and obscure errors if mh_nbytes is wrong but still within range; the
840      checks against MAGIC1 will probably fail then.  Using MALLOC_REGISTER
841      will help here, since it saves the original number of bytes requested. */
842   if (IN_BUCKET(nbytes, nunits) == 0)
843     xbotch (mem, ERR_UNDERFLOW,
844             "realloc: underflow detected; mh_nbytes out of range", file, line);
845
846   m = (char *)mem + (tocopy = p->mh_nbytes);
847   ASSERT (*m++ == MAGIC1); ASSERT (*m++ == MAGIC1);
848   ASSERT (*m++ == MAGIC1); ASSERT (*m   == MAGIC1);
849
850   /* See if desired size rounds to same power of 2 as actual size. */
851   nbytes = ALLOCATED_BYTES(n);
852
853   /* If ok, use the same block, just marking its size as changed.  */
854   if (IN_BUCKET(nbytes, nunits))
855     {
856       m = (char *)mem + tocopy;
857       *m++ = 0;  *m++ = 0;  *m++ = 0;  *m++ = 0;
858       p->mh_nbytes = n;
859       m = (char *)mem + n;
860       *m++ = MAGIC1;  *m++ = MAGIC1;  *m++ = MAGIC1;  *m++ = MAGIC1;
861       return mem;
862     }
863
864 #ifdef MALLOC_STATS
865   _mstats.nrcopy++;
866 #endif
867
868   if (n < tocopy)
869     tocopy = n;
870
871   if ((m = internal_malloc (n, file, line, MALLOC_INTERNAL|MALLOC_NOTRACE|MALLOC_NOREG)) == 0)
872     return 0;
873   FASTCOPY (mem, m, tocopy);
874   internal_free (mem, file, line, MALLOC_INTERNAL);
875
876 #ifdef MALLOC_TRACE
877   if (malloc_trace && (flags & MALLOC_NOTRACE) == 0)
878     mtrace_alloc ("realloc", m, n, file, line);
879 #endif
880
881 #ifdef MALLOC_REGISTER
882   if (malloc_register && (flags & MALLOC_NOREG) == 0)
883     mregister_alloc ("realloc", m, n, file, line);
884 #endif
885
886   return m;
887 }
888
889 static PTR_T
890 internal_memalign (alignment, size, file, line, flags)
891      unsigned int alignment;
892      size_t size;
893      const char *file;
894      int line, flags;
895 {
896   register char *ptr;
897   register char *aligned;
898   register union mhead *p;
899
900   ptr = internal_malloc (size + alignment, file, line, MALLOC_INTERNAL);
901
902   if (ptr == 0)
903     return 0;
904   /* If entire block has the desired alignment, just accept it.  */
905   if (((long) ptr & (alignment - 1)) == 0)
906     return ptr;
907   /* Otherwise, get address of byte in the block that has that alignment.  */
908 #if 0
909   aligned = (char *) (((long) ptr + alignment - 1) & -alignment);
910 #else
911   aligned = (char *) (((long) ptr + alignment - 1) & (~alignment + 1));
912 #endif
913
914   /* Store a suitable indication of how to free the block,
915      so that free can find the true beginning of it.  */
916   p = (union mhead *) aligned - 1;
917   p->mh_nbytes = aligned - ptr;
918   p->mh_alloc = ISMEMALIGN;
919
920   return aligned;
921 }
922
923 #if !defined (NO_VALLOC)
924 /* This runs into trouble with getpagesize on HPUX, and Multimax machines.
925    Patching out seems cleaner than the ugly fix needed.  */
926 static PTR_T
927 internal_valloc (size, file, line, flags)
928      size_t size;
929      const char *file;
930      int line, flags;
931 {
932   return internal_memalign (getpagesize (), size, file, line, flags|MALLOC_INTERNAL);
933 }
934 #endif /* !NO_VALLOC */
935
936 #ifndef NO_CALLOC
937 static PTR_T
938 internal_calloc (n, s, file, line, flags)
939      size_t n, s;
940      const char *file;
941      int line, flags;
942 {
943   size_t total;
944   PTR_T result;
945
946   total = n * s;
947   result = internal_malloc (total, file, line, flags|MALLOC_INTERNAL);
948   if (result)
949     zmemset (result, 0, total);
950   return result;  
951 }
952
953 static void
954 internal_cfree (p, file, line, flags)
955      PTR_T p;
956      const char *file;
957      int line, flags;
958 {
959   internal_free (p, file, line, flags|MALLOC_INTERNAL);
960 }
961 #endif /* !NO_CALLOC */
962
963 #ifdef MALLOC_STATS
964
965 int
966 malloc_free_blocks (size)
967      int size;
968 {
969   int nfree;
970   register union mhead *p;
971
972   nfree = 0;
973   for (p = nextf[size]; p; p = CHAIN (p))
974     nfree++;
975
976   return nfree;
977 }
978 #endif
979
980 #if defined (SHELL)
981 PTR_T
982 sh_malloc (bytes, file, line)
983      size_t bytes;
984      const char *file;
985      int line;
986 {
987   return internal_malloc (bytes, file, line, MALLOC_WRAPPER);
988 }
989
990 PTR_T
991 sh_realloc (ptr, size, file, line)
992      PTR_T ptr;
993      size_t size;
994      const char *file;
995      int line;
996 {
997   return internal_realloc (ptr, size, file, line, MALLOC_WRAPPER);
998 }
999
1000 void
1001 sh_free (mem, file, line)
1002      PTR_T mem;
1003      const char *file;
1004      int line;
1005 {
1006   internal_free (mem, file, line, MALLOC_WRAPPER);
1007 }
1008
1009 PTR_T
1010 sh_memalign (alignment, size, file, line)
1011      unsigned int alignment;
1012      size_t size;
1013      const char *file;
1014      int line;
1015 {
1016   return internal_memalign (alignment, size, file, line, MALLOC_WRAPPER);
1017 }
1018
1019 #ifndef NO_CALLOC
1020 PTR_T
1021 sh_calloc (n, s, file, line)
1022      size_t n, s;
1023      const char *file;
1024      int line;
1025 {
1026   return internal_calloc (n, s, file, line, MALLOC_WRAPPER);
1027 }
1028
1029 void
1030 sh_cfree (mem, file, line)
1031      PTR_T mem;
1032      const char *file;
1033      int line;
1034 {
1035   internal_cfree (mem, file, line, MALLOC_WRAPPER);
1036 }
1037 #endif
1038
1039 #ifndef NO_VALLOC
1040 PTR_T
1041 sh_valloc (size, file, line)
1042      size_t size;
1043      const char *file;
1044      int line;
1045 {
1046   return internal_valloc (size, file, line, MALLOC_WRAPPER);
1047 }
1048 #endif
1049
1050 #endif
1051
1052 /* Externally-available functions that call their internal counterparts. */
1053
1054 PTR_T
1055 malloc (size)
1056      size_t size;
1057 {
1058   return internal_malloc (size, (char *)NULL, 0, 0);
1059 }
1060
1061 PTR_T
1062 realloc (mem, nbytes)
1063      PTR_T mem;
1064      size_t nbytes;
1065 {
1066   return internal_realloc (mem, nbytes, (char *)NULL, 0, 0);
1067 }
1068
1069 void
1070 free (mem)
1071      PTR_T mem;
1072 {
1073   internal_free (mem,  (char *)NULL, 0, 0);
1074 }
1075
1076 PTR_T
1077 memalign (alignment, size)
1078      unsigned int alignment;
1079      size_t size;
1080 {
1081   return internal_memalign (alignment, size, (char *)NULL, 0, 0);
1082 }
1083
1084 #ifndef NO_VALLOC
1085 PTR_T
1086 valloc (size)
1087      size_t size;
1088 {
1089   return internal_valloc (size, (char *)NULL, 0, 0);
1090 }
1091 #endif
1092
1093 #ifndef NO_CALLOC
1094 PTR_T
1095 calloc (n, s)
1096      size_t n, s;
1097 {
1098   return internal_calloc (n, s, (char *)NULL, 0, 0);
1099 }
1100
1101 void
1102 cfree (mem)
1103      PTR_T mem;
1104 {
1105   internal_cfree (mem, (char *)NULL, 0, 0);
1106 }
1107 #endif