blob: cd987c0dc3b47e9f206c1a24dd5439e91f6ff196 [file] [log] [blame]
Jari Aaltocce855b1998-04-17 19:52:44 +00001/* malloc.c - dynamic memory allocation for bash. */
Jari Aalto726f6381996-08-26 18:22:31 +00002
Jari Aalto95732b42005-12-07 14:08:12 +00003/* Copyright (C) 1985-2005 Free Software Foundation, Inc.
Jari Aalto726f6381996-08-26 18:22:31 +00004
Jari Aalto31859422009-01-12 13:36:28 +00005 This file is part of GNU Bash, the Bourne-Again SHell.
6
7 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
Jari Aalto726f6381996-08-26 18:22:31 +000011
Jari Aalto31859422009-01-12 13:36:28 +000012 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
Jari Aalto726f6381996-08-26 18:22:31 +000016
Jari Aalto31859422009-01-12 13:36:28 +000017 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19*/
Jari Aalto726f6381996-08-26 18:22:31 +000020
21/*
22 * @(#)nmalloc.c 1 (Caltech) 2/21/82
23 *
24 * U of M Modified: 20 Jun 1983 ACT: strange hacks for Emacs
25 *
26 * Nov 1983, Mike@BRL, Added support for 4.1C/4.2 BSD.
27 *
28 * This is a very fast storage allocator. It allocates blocks of a small
29 * number of different sizes, and keeps free lists of each size. Blocks
30 * that don't exactly fit are passed up to the next larger size. In this
31 * implementation, the available sizes are (2^n)-4 (or -16) bytes long.
32 * This is designed for use in a program that uses vast quantities of
33 * memory, but bombs when it runs out. To make it a little better, it
34 * warns the user when he starts to get near the end.
35 *
36 * June 84, ACT: modified rcheck code to check the range given to malloc,
37 * rather than the range determined by the 2-power used.
38 *
39 * Jan 85, RMS: calls malloc_warning to issue warning on nearly full.
40 * No longer Emacs-specific; can serve as all-purpose malloc for GNU.
41 * You should call malloc_init to reinitialize after loading dumped Emacs.
Jari Aaltocce855b1998-04-17 19:52:44 +000042 * Call malloc_stats to get info on memory stats if MALLOC_STATS turned on.
Jari Aalto726f6381996-08-26 18:22:31 +000043 * realloc knows how to return same block given, just changing its size,
44 * if the power of 2 is correct.
45 */
46
47/*
48 * nextf[i] is the pointer to the next free block of size 2^(i+3). The
49 * smallest allocatable block is 8 bytes. The overhead information will
50 * go in the first int of the block, and the returned pointer will point
51 * to the second.
Jari Aalto726f6381996-08-26 18:22:31 +000052 */
53
Jari Aalto7117c2d2002-07-17 14:10:11 +000054/* Define MEMSCRAMBLE to have free() write 0xcf into memory as it's freed, to
55 uncover callers that refer to freed memory, and to have malloc() write 0xdf
56 into memory as it's allocated to avoid referring to previous contents. */
57
58/* SCO 3.2v4 getcwd and possibly other libc routines fail with MEMSCRAMBLE;
59 handled by configure. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +000060
Jari Aaltocce855b1998-04-17 19:52:44 +000061#if defined (HAVE_CONFIG_H)
Jari Aaltoccc6cda1996-12-23 17:02:34 +000062# include <config.h>
Jari Aaltocce855b1998-04-17 19:52:44 +000063#endif /* HAVE_CONFIG_H */
64
65#if defined (SHELL)
66# include "bashtypes.h"
Jari Aaltof73dda02001-11-13 17:56:06 +000067# include "stdc.h"
Jari Aaltocce855b1998-04-17 19:52:44 +000068#else
69# include <sys/types.h>
70#endif
Jari Aalto726f6381996-08-26 18:22:31 +000071
Jari Aaltoccc6cda1996-12-23 17:02:34 +000072#if defined (HAVE_UNISTD_H)
73# include <unistd.h>
74#endif
Jari Aalto726f6381996-08-26 18:22:31 +000075
76/* Determine which kind of system this is. */
Jari Aalto726f6381996-08-26 18:22:31 +000077#include <signal.h>
78
Jari Aaltocce855b1998-04-17 19:52:44 +000079#if defined (HAVE_STRING_H)
80# include <string.h>
81#else
82# include <strings.h>
83#endif
84
Jari Aaltof73dda02001-11-13 17:56:06 +000085#include <stdio.h>
Jari Aaltocce855b1998-04-17 19:52:44 +000086
Jari Aaltoccc6cda1996-12-23 17:02:34 +000087/* Define getpagesize () if the system does not. */
88#ifndef HAVE_GETPAGESIZE
Jari Aalto726f6381996-08-26 18:22:31 +000089# include "getpagesize.h"
90#endif
91
Jari Aaltof73dda02001-11-13 17:56:06 +000092#include "imalloc.h"
93#ifdef MALLOC_STATS
94# include "mstats.h"
95#endif
96#ifdef MALLOC_REGISTER
97# include "table.h"
Jari Aaltobb706242000-03-17 21:46:59 +000098#endif
Jari Aalto7117c2d2002-07-17 14:10:11 +000099#ifdef MALLOC_WATCH
100# include "watch.h"
101#endif
Jari Aaltobb706242000-03-17 21:46:59 +0000102
Jari Aaltof73dda02001-11-13 17:56:06 +0000103/* System-specific omissions. */
104#ifdef HPUX
105# define NO_VALLOC
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000106#endif
107
Jari Aaltocce855b1998-04-17 19:52:44 +0000108#define NBUCKETS 30
Jari Aalto726f6381996-08-26 18:22:31 +0000109
110#define ISALLOC ((char) 0xf7) /* magic byte that implies allocation */
111#define ISFREE ((char) 0x54) /* magic byte that implies free block */
112 /* this is for error checking only */
113#define ISMEMALIGN ((char) 0xd6) /* Stored before the value returned by
114 memalign, with the rest of the word
115 being the distance to the true
116 beginning of the block. */
Jari Aalto726f6381996-08-26 18:22:31 +0000117
Jari Aaltocce855b1998-04-17 19:52:44 +0000118
119/* We have a flag indicating whether memory is allocated, an index in
120 nextf[], a size field, and a sentinel value to determine whether or
121 not a caller wrote before the start of allocated memory; to realloc()
122 memory we either copy mh_nbytes or just change mh_nbytes if there is
123 enough room in the block for the new size. Range checking is always
124 done. */
125union mhead {
Jari Aaltof73dda02001-11-13 17:56:06 +0000126 bits64_t mh_align; /* 8 */
Jari Aaltocce855b1998-04-17 19:52:44 +0000127 struct {
Jari Aaltof73dda02001-11-13 17:56:06 +0000128 char mi_alloc; /* ISALLOC or ISFREE */ /* 1 */
129 char mi_index; /* index in nextf[] */ /* 1 */
Jari Aaltocce855b1998-04-17 19:52:44 +0000130 /* Remainder are valid only when block is allocated */
Jari Aaltof73dda02001-11-13 17:56:06 +0000131 u_bits16_t mi_magic2; /* should be == MAGIC2 */ /* 2 */
132 u_bits32_t mi_nbytes; /* # of bytes allocated */ /* 4 */
Jari Aaltocce855b1998-04-17 19:52:44 +0000133 } minfo;
134};
135#define mh_alloc minfo.mi_alloc
136#define mh_index minfo.mi_index
137#define mh_nbytes minfo.mi_nbytes
138#define mh_magic2 minfo.mi_magic2
139
Jari Aalto7117c2d2002-07-17 14:10:11 +0000140#define MOVERHEAD sizeof(union mhead)
141#define MALIGN_MASK 7 /* one less than desired alignment */
142
143typedef union _malloc_guard {
144 char s[4];
145 u_bits32_t i;
146} mguard_t;
147
Jari Aalto726f6381996-08-26 18:22:31 +0000148/* Access free-list pointer of a block.
Jari Aaltocce855b1998-04-17 19:52:44 +0000149 It is stored at block + sizeof (char *).
Jari Aaltob72432f1999-02-19 17:11:39 +0000150 This is not a field in the minfo structure member of union mhead
151 because we want sizeof (union mhead)
Jari Aaltocce855b1998-04-17 19:52:44 +0000152 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. */
Jari Aalto726f6381996-08-26 18:22:31 +0000154
155#define CHAIN(a) \
Jari Aaltocce855b1998-04-17 19:52:44 +0000156 (*(union mhead **) (sizeof (char *) + (char *) (a)))
Jari Aalto726f6381996-08-26 18:22:31 +0000157
Jari Aaltocce855b1998-04-17 19:52:44 +0000158/* 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. */
Jari Aalto726f6381996-08-26 18:22:31 +0000161
Jari Aaltof73dda02001-11-13 17:56:06 +0000162/* Written in the 2 bytes before the block's real space (-4 bytes) */
Jari Aaltocce855b1998-04-17 19:52:44 +0000163#define MAGIC2 0x5555
Jari Aalto7117c2d2002-07-17 14:10:11 +0000164#define MSLOP 4 /* 4 bytes extra for u_bits32_t size */
Jari Aaltocce855b1998-04-17 19:52:44 +0000165
Jari Aaltof73dda02001-11-13 17:56:06 +0000166/* How many bytes are actually allocated for a request of size N --
167 rounded up to nearest multiple of 8 after accounting for malloc
168 overhead. */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000169#define ALLOCATED_BYTES(n) \
170 (((n) + MOVERHEAD + MSLOP + MALIGN_MASK) & ~MALIGN_MASK)
Jari Aaltof73dda02001-11-13 17:56:06 +0000171
172#define ASSERT(p) \
173 do \
174 { \
Chet Rameyac50fba2014-02-26 09:36:43 -0500175 if (!(p)) xbotch((PTR_T)0, ERR_ASSERT_FAILED, CPP_STRING(p), file, line); \
Jari Aaltof73dda02001-11-13 17:56:06 +0000176 } \
177 while (0)
178
Jari Aaltocce855b1998-04-17 19:52:44 +0000179/* Minimum and maximum bucket indices for block splitting (and to bound
180 the search for a block to split). */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000181#define SPLIT_MIN 2 /* XXX - was 3 */
182#define SPLIT_MID 11
183#define SPLIT_MAX 14
Jari Aaltocce855b1998-04-17 19:52:44 +0000184
185/* Minimum and maximum bucket indices for block coalescing. */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000186#define COMBINE_MIN 2
187#define COMBINE_MAX (pagebucket - 1) /* XXX */
Jari Aaltocce855b1998-04-17 19:52:44 +0000188
Jari Aalto7117c2d2002-07-17 14:10:11 +0000189#define LESSCORE_MIN 10
190#define LESSCORE_FRC 13
191
192#define STARTBUCK 1
Jari Aalto726f6381996-08-26 18:22:31 +0000193
Jari Aaltof73dda02001-11-13 17:56:06 +0000194/* Flags for the internal functions. */
195#define MALLOC_WRAPPER 0x01 /* wrapper function */
196#define MALLOC_INTERNAL 0x02 /* internal function calling another */
197#define MALLOC_NOTRACE 0x04 /* don't trace this allocation or free */
198#define MALLOC_NOREG 0x08 /* don't register this allocation or free */
199
200/* Future use. */
201#define ERR_DUPFREE 0x01
202#define ERR_UNALLOC 0x02
203#define ERR_UNDERFLOW 0x04
204#define ERR_ASSERT_FAILED 0x08
205
206/* Evaluates to true if NB is appropriate for bucket NU. NB is adjusted
Jari Aalto7117c2d2002-07-17 14:10:11 +0000207 appropriately by the caller to account for malloc overhead. This only
208 checks that the recorded size is not too big for the bucket. We
209 can't check whether or not it's in between NU and NU-1 because we
210 might have encountered a busy bucket when allocating and moved up to
211 the next size. */
212#define IN_BUCKET(nb, nu) ((nb) <= binsizes[(nu)])
213
214/* Use this when we want to be sure that NB is in bucket NU. */
215#define RIGHT_BUCKET(nb, nu) \
216 (((nb) > binsizes[(nu)-1]) && ((nb) <= binsizes[(nu)]))
Jari Aaltof73dda02001-11-13 17:56:06 +0000217
Jari Aalto726f6381996-08-26 18:22:31 +0000218/* nextf[i] is free list of blocks of size 2**(i + 3) */
219
Jari Aaltocce855b1998-04-17 19:52:44 +0000220static union mhead *nextf[NBUCKETS];
Jari Aalto726f6381996-08-26 18:22:31 +0000221
Jari Aalto95732b42005-12-07 14:08:12 +0000222/* busy[i] is nonzero while allocation or free of block size i is in progress. */
Jari Aalto726f6381996-08-26 18:22:31 +0000223
Jari Aaltocce855b1998-04-17 19:52:44 +0000224static char busy[NBUCKETS];
Jari Aalto726f6381996-08-26 18:22:31 +0000225
Jari Aaltocce855b1998-04-17 19:52:44 +0000226static int pagesz; /* system page size. */
227static int pagebucket; /* bucket for requests a page in size */
Jari Aaltobb706242000-03-17 21:46:59 +0000228static int maxbuck; /* highest bucket receiving allocation request. */
Jari Aalto726f6381996-08-26 18:22:31 +0000229
Jari Aalto7117c2d2002-07-17 14:10:11 +0000230static char *memtop; /* top of heap */
231
Jari Aalto31859422009-01-12 13:36:28 +0000232static const unsigned long binsizes[NBUCKETS] = {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000233 8UL, 16UL, 32UL, 64UL, 128UL, 256UL, 512UL, 1024UL, 2048UL, 4096UL,
234 8192UL, 16384UL, 32768UL, 65536UL, 131072UL, 262144UL, 524288UL,
235 1048576UL, 2097152UL, 4194304UL, 8388608UL, 16777216UL, 33554432UL,
236 67108864UL, 134217728UL, 268435456UL, 536870912UL, 1073741824UL,
Jari Aaltob80f6442004-07-27 13:29:18 +0000237 2147483648UL, 4294967295UL
Jari Aalto7117c2d2002-07-17 14:10:11 +0000238};
239
240/* binsizes[x] == (1 << ((x) + 3)) */
241#define binsize(x) binsizes[(x)]
242
Jari Aaltof73dda02001-11-13 17:56:06 +0000243/* Declarations for internal functions */
244static PTR_T internal_malloc __P((size_t, const char *, int, int));
245static PTR_T internal_realloc __P((PTR_T, size_t, const char *, int, int));
246static void internal_free __P((PTR_T, const char *, int, int));
Jari Aalto95732b42005-12-07 14:08:12 +0000247static PTR_T internal_memalign __P((size_t, size_t, const char *, int, int));
Jari Aaltof73dda02001-11-13 17:56:06 +0000248#ifndef NO_CALLOC
249static PTR_T internal_calloc __P((size_t, size_t, const char *, int, int));
250static void internal_cfree __P((PTR_T, const char *, int, int));
251#endif
252#ifndef NO_VALLOC
253static PTR_T internal_valloc __P((size_t, const char *, int, int));
254#endif
255
256#if defined (botch)
257extern void botch ();
258#else
259static void botch __P((const char *, const char *, int));
260#endif
261static void xbotch __P((PTR_T, int, const char *, const char *, int));
262
Jari Aaltof73dda02001-11-13 17:56:06 +0000263#if !HAVE_DECL_SBRK
264extern char *sbrk ();
265#endif /* !HAVE_DECL_SBRK */
266
Jari Aalto28ef6c32001-04-06 19:14:31 +0000267#ifdef SHELL
Chet Rameyac50fba2014-02-26 09:36:43 -0500268extern int interrupt_immediately, running_trap;
Jari Aaltof73dda02001-11-13 17:56:06 +0000269extern int signal_is_trapped __P((int));
Jari Aalto28ef6c32001-04-06 19:14:31 +0000270#endif
271
Jari Aalto7117c2d2002-07-17 14:10:11 +0000272#ifdef MALLOC_STATS
273struct _malstats _mstats;
274#endif /* MALLOC_STATS */
275
Jari Aaltof73dda02001-11-13 17:56:06 +0000276/* Debugging variables available to applications. */
277int malloc_flags = 0; /* future use */
278int malloc_trace = 0; /* trace allocations and frees to stderr */
279int malloc_register = 0; /* future use */
280
Jari Aalto7117c2d2002-07-17 14:10:11 +0000281#ifdef MALLOC_TRACE
282char _malloc_trace_buckets[NBUCKETS];
283
284/* These should really go into a header file. */
285extern void mtrace_alloc __P((const char *, PTR_T, size_t, const char *, int));
286extern void mtrace_free __P((PTR_T, int, const char *, int));
287#endif
288
Jari Aaltof73dda02001-11-13 17:56:06 +0000289#if !defined (botch)
290static void
291botch (s, file, line)
Jari Aaltob80f6442004-07-27 13:29:18 +0000292 const char *s;
293 const char *file;
294 int line;
Jari Aaltof73dda02001-11-13 17:56:06 +0000295{
Jari Aaltob80f6442004-07-27 13:29:18 +0000296 fprintf (stderr, _("malloc: failed assertion: %s\n"), s);
Jari Aaltof73dda02001-11-13 17:56:06 +0000297 (void)fflush (stderr);
298 abort ();
299}
300#endif
301
302/* print the file and line number that caused the assertion failure and
303 call botch() to do whatever the application wants with the information */
304static void
305xbotch (mem, e, s, file, line)
306 PTR_T mem;
307 int e;
308 const char *s;
309 const char *file;
310 int line;
311{
Jari Aaltob80f6442004-07-27 13:29:18 +0000312 fprintf (stderr, _("\r\nmalloc: %s:%d: assertion botched\r\n"),
Jari Aalto31859422009-01-12 13:36:28 +0000313 file ? file : _("unknown"), line);
Jari Aaltof73dda02001-11-13 17:56:06 +0000314#ifdef MALLOC_REGISTER
315 if (mem != NULL && malloc_register)
316 mregister_describe_mem (mem, stderr);
317#endif
318 (void)fflush (stderr);
319 botch(s, file, line);
320}
321
Jari Aaltocce855b1998-04-17 19:52:44 +0000322/* Coalesce two adjacent free blocks off the free list for size NU - 1,
Jari Aalto7117c2d2002-07-17 14:10:11 +0000323 as long as we can find two adjacent free blocks. nextf[NU -1] is
Jari Aalto95732b42005-12-07 14:08:12 +0000324 assumed to not be busy; the caller (morecore()) checks for this.
325 BUSY[NU] must be set to 1. */
Jari Aaltocce855b1998-04-17 19:52:44 +0000326static void
327bcoalesce (nu)
328 register int nu;
Jari Aalto726f6381996-08-26 18:22:31 +0000329{
Jari Aaltocce855b1998-04-17 19:52:44 +0000330 register union mhead *mp, *mp1, *mp2;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000331 register int nbuck;
Jari Aaltocce855b1998-04-17 19:52:44 +0000332 unsigned long siz;
333
334 nbuck = nu - 1;
Jari Aalto95732b42005-12-07 14:08:12 +0000335 if (nextf[nbuck] == 0 || busy[nbuck])
Jari Aaltocce855b1998-04-17 19:52:44 +0000336 return;
337
Jari Aalto95732b42005-12-07 14:08:12 +0000338 busy[nbuck] = 1;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000339 siz = binsize (nbuck);
340
341 mp2 = mp1 = nextf[nbuck];
Jari Aaltocce855b1998-04-17 19:52:44 +0000342 mp = CHAIN (mp1);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000343 while (mp && mp != (union mhead *)((char *)mp1 + siz))
Jari Aaltocce855b1998-04-17 19:52:44 +0000344 {
345 mp2 = mp1;
346 mp1 = mp;
347 mp = CHAIN (mp);
Jari Aaltocce855b1998-04-17 19:52:44 +0000348 }
Jari Aalto95732b42005-12-07 14:08:12 +0000349
Jari Aalto7117c2d2002-07-17 14:10:11 +0000350 if (mp == 0)
Jari Aalto95732b42005-12-07 14:08:12 +0000351 {
352 busy[nbuck] = 0;
353 return;
354 }
Jari Aalto7117c2d2002-07-17 14:10:11 +0000355
Jari Aaltocce855b1998-04-17 19:52:44 +0000356 /* OK, now we have mp1 pointing to the block we want to add to nextf[NU].
357 CHAIN(mp2) must equal mp1. Check that mp1 and mp are adjacent. */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000358 if (mp2 != mp1 && CHAIN(mp2) != mp1)
Jari Aalto95732b42005-12-07 14:08:12 +0000359 {
360 busy[nbuck] = 0;
361 xbotch ((PTR_T)0, 0, "bcoalesce: CHAIN(mp2) != mp1", (char *)NULL, 0);
362 }
Jari Aalto7117c2d2002-07-17 14:10:11 +0000363
364#ifdef MALLOC_DEBUG
Jari Aaltocce855b1998-04-17 19:52:44 +0000365 if (CHAIN (mp1) != (union mhead *)((char *)mp1 + siz))
Jari Aalto95732b42005-12-07 14:08:12 +0000366 {
367 busy[nbuck] = 0;
368 return; /* not adjacent */
369 }
Jari Aaltocce855b1998-04-17 19:52:44 +0000370#endif
371
372 /* Since they are adjacent, remove them from the free list */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000373 if (mp1 == nextf[nbuck])
374 nextf[nbuck] = CHAIN (mp);
375 else
376 CHAIN (mp2) = CHAIN (mp);
Jari Aalto95732b42005-12-07 14:08:12 +0000377 busy[nbuck] = 0;
378
379#ifdef MALLOC_STATS
380 _mstats.tbcoalesce++;
381 _mstats.ncoalesce[nbuck]++;
382#endif
Jari Aaltocce855b1998-04-17 19:52:44 +0000383
384 /* And add the combined two blocks to nextf[NU]. */
385 mp1->mh_alloc = ISFREE;
386 mp1->mh_index = nu;
387 CHAIN (mp1) = nextf[nu];
388 nextf[nu] = mp1;
Jari Aalto726f6381996-08-26 18:22:31 +0000389}
390
Jari Aaltocce855b1998-04-17 19:52:44 +0000391/* Split a block at index > NU (but less than SPLIT_MAX) into a set of
392 blocks of the correct size, and attach them to nextf[NU]. nextf[NU]
393 is assumed to be empty. Must be called with signals blocked (e.g.,
Jari Aalto95732b42005-12-07 14:08:12 +0000394 by morecore()). BUSY[NU] must be set to 1. */
Jari Aaltocce855b1998-04-17 19:52:44 +0000395static void
396bsplit (nu)
397 register int nu;
Jari Aalto726f6381996-08-26 18:22:31 +0000398{
Jari Aaltocce855b1998-04-17 19:52:44 +0000399 register union mhead *mp;
Jari Aaltobb706242000-03-17 21:46:59 +0000400 int nbuck, nblks, split_max;
Jari Aaltocce855b1998-04-17 19:52:44 +0000401 unsigned long siz;
Jari Aalto726f6381996-08-26 18:22:31 +0000402
Jari Aaltobb706242000-03-17 21:46:59 +0000403 split_max = (maxbuck > SPLIT_MAX) ? maxbuck : SPLIT_MAX;
404
Jari Aaltocce855b1998-04-17 19:52:44 +0000405 if (nu >= SPLIT_MID)
406 {
Jari Aaltobb706242000-03-17 21:46:59 +0000407 for (nbuck = split_max; nbuck > nu; nbuck--)
Jari Aaltocce855b1998-04-17 19:52:44 +0000408 {
409 if (busy[nbuck] || nextf[nbuck] == 0)
410 continue;
411 break;
412 }
413 }
414 else
415 {
Jari Aaltobb706242000-03-17 21:46:59 +0000416 for (nbuck = nu + 1; nbuck <= split_max; nbuck++)
Jari Aaltocce855b1998-04-17 19:52:44 +0000417 {
418 if (busy[nbuck] || nextf[nbuck] == 0)
419 continue;
420 break;
421 }
422 }
423
Jari Aaltobb706242000-03-17 21:46:59 +0000424 if (nbuck > split_max || nbuck <= nu)
Jari Aaltocce855b1998-04-17 19:52:44 +0000425 return;
426
427 /* XXX might want to split only if nextf[nbuck] has >= 2 blocks free
428 and nbuck is below some threshold. */
429
Jari Aalto95732b42005-12-07 14:08:12 +0000430 /* Remove the block from the chain of larger blocks. */
431 busy[nbuck] = 1;
432 mp = nextf[nbuck];
433 nextf[nbuck] = CHAIN (mp);
434 busy[nbuck] = 0;
435
Jari Aaltocce855b1998-04-17 19:52:44 +0000436#ifdef MALLOC_STATS
Jari Aaltobb706242000-03-17 21:46:59 +0000437 _mstats.tbsplit++;
438 _mstats.nsplit[nbuck]++;
Jari Aaltocce855b1998-04-17 19:52:44 +0000439#endif
440
441 /* Figure out how many blocks we'll get. */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000442 siz = binsize (nu);
443 nblks = binsize (nbuck) / siz;
Jari Aaltocce855b1998-04-17 19:52:44 +0000444
Jari Aaltocce855b1998-04-17 19:52:44 +0000445 /* Split the block and put it on the requested chain. */
446 nextf[nu] = mp;
447 while (1)
448 {
449 mp->mh_alloc = ISFREE;
450 mp->mh_index = nu;
451 if (--nblks <= 0) break;
452 CHAIN (mp) = (union mhead *)((char *)mp + siz);
453 mp = (union mhead *)((char *)mp + siz);
454 }
455 CHAIN (mp) = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000456}
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000457
Jari Aalto95732b42005-12-07 14:08:12 +0000458/* Take the memory block MP and add it to a chain < NU. NU is the right bucket,
459 but is busy. This avoids memory orphaning. */
460static void
461xsplit (mp, nu)
462 union mhead *mp;
463 int nu;
464{
465 union mhead *nh;
466 int nbuck, nblks, split_max;
467 unsigned long siz;
468
469 nbuck = nu - 1;
470 while (nbuck >= SPLIT_MIN && busy[nbuck])
471 nbuck--;
472 if (nbuck < SPLIT_MIN)
473 return;
474
475#ifdef MALLOC_STATS
476 _mstats.tbsplit++;
477 _mstats.nsplit[nu]++;
478#endif
479
480 /* Figure out how many blocks we'll get. */
481 siz = binsize (nu); /* original block size */
482 nblks = siz / binsize (nbuck); /* should be 2 most of the time */
483
484 /* And add it to nextf[nbuck] */
485 siz = binsize (nbuck); /* XXX - resetting here */
486 nh = mp;
487 while (1)
488 {
489 mp->mh_alloc = ISFREE;
490 mp->mh_index = nbuck;
491 if (--nblks <= 0) break;
492 CHAIN (mp) = (union mhead *)((char *)mp + siz);
493 mp = (union mhead *)((char *)mp + siz);
494 }
495 busy[nbuck] = 1;
496 CHAIN (mp) = nextf[nbuck];
497 nextf[nbuck] = nh;
498 busy[nbuck] = 0;
499}
500
Chet Rameyac50fba2014-02-26 09:36:43 -0500501void
502_malloc_block_signals (setp, osetp)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000503 sigset_t *setp, *osetp;
504{
505#ifdef HAVE_POSIX_SIGNALS
506 sigfillset (setp);
507 sigemptyset (osetp);
508 sigprocmask (SIG_BLOCK, setp, osetp);
509#else
510# if defined (HAVE_BSD_SIGNALS)
511 *osetp = sigsetmask (-1);
512# endif
513#endif
514}
515
Chet Rameyac50fba2014-02-26 09:36:43 -0500516void
517_malloc_unblock_signals (setp, osetp)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000518 sigset_t *setp, *osetp;
519{
520#ifdef HAVE_POSIX_SIGNALS
521 sigprocmask (SIG_SETMASK, osetp, (sigset_t *)NULL);
522#else
523# if defined (HAVE_BSD_SIGNALS)
524 sigsetmask (*osetp);
525# endif
526#endif
527}
Jari Aalto7117c2d2002-07-17 14:10:11 +0000528
529/* Return some memory to the system by reducing the break. This is only
530 called with NU > pagebucket, so we're always assured of giving back
531 more than one page of memory. */
532static void
533lesscore (nu) /* give system back some memory */
534 register int nu; /* size index we're discarding */
535{
536 long siz;
537
538 siz = binsize (nu);
539 /* Should check for errors here, I guess. */
540 sbrk (-siz);
541 memtop -= siz;
542
543#ifdef MALLOC_STATS
544 _mstats.nsbrk++;
545 _mstats.tsbrk -= siz;
546 _mstats.nlesscore[nu]++;
547#endif
548}
Jari Aalto95732b42005-12-07 14:08:12 +0000549
550/* Ask system for more memory; add to NEXTF[NU]. BUSY[NU] must be set to 1. */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000551static void
Jari Aalto95732b42005-12-07 14:08:12 +0000552morecore (nu)
Jari Aalto726f6381996-08-26 18:22:31 +0000553 register int nu; /* size index to get more of */
554{
Jari Aaltocce855b1998-04-17 19:52:44 +0000555 register union mhead *mp;
Jari Aalto726f6381996-08-26 18:22:31 +0000556 register int nblks;
Jari Aaltocce855b1998-04-17 19:52:44 +0000557 register long siz;
558 long sbrk_amt; /* amount to get via sbrk() */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000559 sigset_t set, oset;
560 int blocked_sigs;
Jari Aalto726f6381996-08-26 18:22:31 +0000561
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000562 /* Block all signals in case we are executed from a signal handler. */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000563 blocked_sigs = 0;
564#ifdef SHELL
Chet Rameyac50fba2014-02-26 09:36:43 -0500565# if defined (SIGCHLD)
566 if (interrupt_immediately || running_trap || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD))
567# else
568 if (interrupt_immediately || running_trap || signal_is_trapped (SIGINT))
569# endif
Jari Aalto28ef6c32001-04-06 19:14:31 +0000570#endif
571 {
Chet Rameyac50fba2014-02-26 09:36:43 -0500572 _malloc_block_signals (&set, &oset);
Jari Aalto28ef6c32001-04-06 19:14:31 +0000573 blocked_sigs = 1;
574 }
Jari Aalto726f6381996-08-26 18:22:31 +0000575
Jari Aalto7117c2d2002-07-17 14:10:11 +0000576 siz = binsize (nu); /* size of desired block for nextf[nu] */
Jari Aaltocce855b1998-04-17 19:52:44 +0000577
578 if (siz < 0)
Jari Aaltobb706242000-03-17 21:46:59 +0000579 goto morecore_done; /* oops */
Jari Aaltocce855b1998-04-17 19:52:44 +0000580
581#ifdef MALLOC_STATS
582 _mstats.nmorecore[nu]++;
583#endif
584
585 /* Try to split a larger block here, if we're within the range of sizes
586 to split. */
Jari Aaltobb706242000-03-17 21:46:59 +0000587 if (nu >= SPLIT_MIN)
Jari Aalto726f6381996-08-26 18:22:31 +0000588 {
Jari Aaltocce855b1998-04-17 19:52:44 +0000589 bsplit (nu);
590 if (nextf[nu] != 0)
591 goto morecore_done;
Jari Aalto726f6381996-08-26 18:22:31 +0000592 }
593
Jari Aaltocce855b1998-04-17 19:52:44 +0000594 /* Try to coalesce two adjacent blocks from the free list on nextf[nu - 1],
Jari Aalto95732b42005-12-07 14:08:12 +0000595 if we can, and we're within the range of the block coalescing limits. */
Jari Aaltocce855b1998-04-17 19:52:44 +0000596 if (nu >= COMBINE_MIN && nu < COMBINE_MAX && busy[nu - 1] == 0 && nextf[nu - 1])
597 {
598 bcoalesce (nu);
599 if (nextf[nu] != 0)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000600 goto morecore_done;
Jari Aaltocce855b1998-04-17 19:52:44 +0000601 }
Jari Aalto726f6381996-08-26 18:22:31 +0000602
Jari Aaltocce855b1998-04-17 19:52:44 +0000603 /* Take at least a page, and figure out how many blocks of the requested
604 size we're getting. */
605 if (siz <= pagesz)
606 {
607 sbrk_amt = pagesz;
608 nblks = sbrk_amt / siz;
609 }
610 else
611 {
612 /* We always want to request an integral multiple of the page size
613 from the kernel, so let's compute whether or not `siz' is such
614 an amount. If it is, we can just request it. If not, we want
615 the smallest integral multiple of pagesize that is larger than
616 `siz' and will satisfy the request. */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000617 sbrk_amt = siz & (pagesz - 1);
Jari Aaltocce855b1998-04-17 19:52:44 +0000618 if (sbrk_amt == 0)
619 sbrk_amt = siz;
620 else
621 sbrk_amt = siz + pagesz - sbrk_amt;
622 nblks = 1;
623 }
Jari Aalto726f6381996-08-26 18:22:31 +0000624
Jari Aaltocce855b1998-04-17 19:52:44 +0000625#ifdef MALLOC_STATS
626 _mstats.nsbrk++;
627 _mstats.tsbrk += sbrk_amt;
628#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000629
Jari Aaltocce855b1998-04-17 19:52:44 +0000630 mp = (union mhead *) sbrk (sbrk_amt);
Jari Aalto726f6381996-08-26 18:22:31 +0000631
Jari Aaltocce855b1998-04-17 19:52:44 +0000632 /* Totally out of memory. */
633 if ((long)mp == -1)
Jari Aaltobb706242000-03-17 21:46:59 +0000634 goto morecore_done;
Jari Aalto726f6381996-08-26 18:22:31 +0000635
Jari Aalto7117c2d2002-07-17 14:10:11 +0000636 memtop += sbrk_amt;
637
Jari Aaltocce855b1998-04-17 19:52:44 +0000638 /* shouldn't happen, but just in case -- require 8-byte alignment */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000639 if ((long)mp & MALIGN_MASK)
Jari Aaltocce855b1998-04-17 19:52:44 +0000640 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000641 mp = (union mhead *) (((long)mp + MALIGN_MASK) & ~MALIGN_MASK);
Jari Aalto726f6381996-08-26 18:22:31 +0000642 nblks--;
643 }
644
Jari Aaltocce855b1998-04-17 19:52:44 +0000645 /* save new header and link the nblks blocks together */
646 nextf[nu] = mp;
Jari Aalto726f6381996-08-26 18:22:31 +0000647 while (1)
648 {
Jari Aaltocce855b1998-04-17 19:52:44 +0000649 mp->mh_alloc = ISFREE;
650 mp->mh_index = nu;
Jari Aalto726f6381996-08-26 18:22:31 +0000651 if (--nblks <= 0) break;
Jari Aaltocce855b1998-04-17 19:52:44 +0000652 CHAIN (mp) = (union mhead *)((char *)mp + siz);
653 mp = (union mhead *)((char *)mp + siz);
Jari Aalto726f6381996-08-26 18:22:31 +0000654 }
Jari Aaltocce855b1998-04-17 19:52:44 +0000655 CHAIN (mp) = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000656
Jari Aaltocce855b1998-04-17 19:52:44 +0000657morecore_done:
Jari Aalto28ef6c32001-04-06 19:14:31 +0000658 if (blocked_sigs)
Chet Rameyac50fba2014-02-26 09:36:43 -0500659 _malloc_unblock_signals (&set, &oset);
Jari Aalto726f6381996-08-26 18:22:31 +0000660}
661
Jari Aaltocce855b1998-04-17 19:52:44 +0000662static void
663malloc_debug_dummy ()
664{
Jari Aaltobb706242000-03-17 21:46:59 +0000665 write (1, "malloc_debug_dummy\n", 19);
Jari Aaltocce855b1998-04-17 19:52:44 +0000666}
667
Jari Aalto7117c2d2002-07-17 14:10:11 +0000668#define PREPOP_BIN 2
669#define PREPOP_SIZE 32
670
671static int
672pagealign ()
673{
674 register int nunits;
675 register union mhead *mp;
676 long sbrk_needed;
677 char *curbrk;
678
679 pagesz = getpagesize ();
680 if (pagesz < 1024)
681 pagesz = 1024;
682
683 /* OK, how much do we need to allocate to make things page-aligned?
684 Some of this partial page will be wasted space, but we'll use as
685 much as we can. Once we figure out how much to advance the break
686 pointer, go ahead and do it. */
687 memtop = curbrk = sbrk (0);
688 sbrk_needed = pagesz - ((long)curbrk & (pagesz - 1)); /* sbrk(0) % pagesz */
689 if (sbrk_needed < 0)
690 sbrk_needed += pagesz;
691
692 /* Now allocate the wasted space. */
693 if (sbrk_needed)
694 {
695#ifdef MALLOC_STATS
696 _mstats.nsbrk++;
697 _mstats.tsbrk += sbrk_needed;
698#endif
699 curbrk = sbrk (sbrk_needed);
700 if ((long)curbrk == -1)
701 return -1;
702 memtop += sbrk_needed;
703
704 /* Take the memory which would otherwise be wasted and populate the most
705 popular bin (2 == 32 bytes) with it. Add whatever we need to curbrk
706 to make things 32-byte aligned, compute how many 32-byte chunks we're
707 going to get, and set up the bin. */
708 curbrk += sbrk_needed & (PREPOP_SIZE - 1);
709 sbrk_needed -= sbrk_needed & (PREPOP_SIZE - 1);
710 nunits = sbrk_needed / PREPOP_SIZE;
711
712 if (nunits > 0)
713 {
714 mp = (union mhead *)curbrk;
715
716 nextf[PREPOP_BIN] = mp;
717 while (1)
718 {
719 mp->mh_alloc = ISFREE;
720 mp->mh_index = PREPOP_BIN;
721 if (--nunits <= 0) break;
722 CHAIN(mp) = (union mhead *)((char *)mp + PREPOP_SIZE);
723 mp = (union mhead *)((char *)mp + PREPOP_SIZE);
724 }
725 CHAIN(mp) = 0;
726 }
727 }
728
729 /* compute which bin corresponds to the page size. */
730 for (nunits = 7; nunits < NBUCKETS; nunits++)
731 if (pagesz <= binsize(nunits))
732 break;
733 pagebucket = nunits;
734
735 return 0;
736}
737
Jari Aaltof73dda02001-11-13 17:56:06 +0000738static PTR_T
739internal_malloc (n, file, line, flags) /* get a block */
Jari Aaltocce855b1998-04-17 19:52:44 +0000740 size_t n;
Jari Aaltof73dda02001-11-13 17:56:06 +0000741 const char *file;
742 int line, flags;
Jari Aalto726f6381996-08-26 18:22:31 +0000743{
Jari Aaltocce855b1998-04-17 19:52:44 +0000744 register union mhead *p;
Jari Aaltocce855b1998-04-17 19:52:44 +0000745 register int nunits;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000746 register char *m, *z;
747 long nbytes;
748 mguard_t mg;
Jari Aalto726f6381996-08-26 18:22:31 +0000749
Jari Aalto7117c2d2002-07-17 14:10:11 +0000750 /* Get the system page size and align break pointer so future sbrks will
Jari Aaltocce855b1998-04-17 19:52:44 +0000751 be page-aligned. The page size must be at least 1K -- anything
752 smaller is increased. */
753 if (pagesz == 0)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000754 if (pagealign () < 0)
755 return ((PTR_T)NULL);
Jari Aaltocce855b1998-04-17 19:52:44 +0000756
Jari Aalto726f6381996-08-26 18:22:31 +0000757 /* Figure out how many bytes are required, rounding up to the nearest
Jari Aaltof73dda02001-11-13 17:56:06 +0000758 multiple of 8, then figure out which nextf[] area to use. Try to
Jari Aaltocce855b1998-04-17 19:52:44 +0000759 be smart about where to start searching -- if the number of bytes
760 needed is greater than the page size, we can start at pagebucket. */
Jari Aaltof73dda02001-11-13 17:56:06 +0000761 nbytes = ALLOCATED_BYTES(n);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000762 nunits = (nbytes <= (pagesz >> 1)) ? STARTBUCK : pagebucket;
763 for ( ; nunits < NBUCKETS; nunits++)
764 if (nbytes <= binsize(nunits))
765 break;
Jari Aalto726f6381996-08-26 18:22:31 +0000766
Jari Aaltof73dda02001-11-13 17:56:06 +0000767 /* Silently reject too-large requests. */
768 if (nunits >= NBUCKETS)
769 return ((PTR_T) NULL);
770
Jari Aalto726f6381996-08-26 18:22:31 +0000771 /* In case this is reentrant use of malloc from signal handler,
772 pick a block size that no other malloc level is currently
773 trying to allocate. That's the easiest harmless way not to
774 interfere with the other level of execution. */
Jari Aaltocce855b1998-04-17 19:52:44 +0000775#ifdef MALLOC_STATS
776 if (busy[nunits]) _mstats.nrecurse++;
777#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000778 while (busy[nunits]) nunits++;
779 busy[nunits] = 1;
780
Jari Aaltobb706242000-03-17 21:46:59 +0000781 if (nunits > maxbuck)
782 maxbuck = nunits;
783
Jari Aalto726f6381996-08-26 18:22:31 +0000784 /* If there are no blocks of the appropriate size, go get some */
Jari Aalto726f6381996-08-26 18:22:31 +0000785 if (nextf[nunits] == 0)
786 morecore (nunits);
787
788 /* Get one block off the list, and set the new list head */
Jari Aaltocce855b1998-04-17 19:52:44 +0000789 if ((p = nextf[nunits]) == NULL)
Jari Aalto726f6381996-08-26 18:22:31 +0000790 {
791 busy[nunits] = 0;
Jari Aaltocce855b1998-04-17 19:52:44 +0000792 return NULL;
Jari Aalto726f6381996-08-26 18:22:31 +0000793 }
794 nextf[nunits] = CHAIN (p);
795 busy[nunits] = 0;
796
797 /* Check for free block clobbered */
Jari Aaltocce855b1998-04-17 19:52:44 +0000798 /* If not for this check, we would gobble a clobbered free chain ptr
799 and bomb out on the NEXT allocate of this size block */
800 if (p->mh_alloc != ISFREE || p->mh_index != nunits)
Jari Aaltob80f6442004-07-27 13:29:18 +0000801 xbotch ((PTR_T)(p+1), 0, _("malloc: block on free list clobbered"), file, line);
Jari Aalto726f6381996-08-26 18:22:31 +0000802
Jari Aaltof73dda02001-11-13 17:56:06 +0000803 /* Fill in the info, and set up the magic numbers for range checking. */
Jari Aaltocce855b1998-04-17 19:52:44 +0000804 p->mh_alloc = ISALLOC;
Jari Aaltocce855b1998-04-17 19:52:44 +0000805 p->mh_magic2 = MAGIC2;
Jari Aaltof73dda02001-11-13 17:56:06 +0000806 p->mh_nbytes = n;
Jari Aalto726f6381996-08-26 18:22:31 +0000807
Jari Aalto7117c2d2002-07-17 14:10:11 +0000808 /* End guard */
809 mg.i = n;
810 z = mg.s;
811 m = (char *) (p + 1) + n;
812 *m++ = *z++, *m++ = *z++, *m++ = *z++, *m++ = *z++;
Jari Aaltocce855b1998-04-17 19:52:44 +0000813
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000814#ifdef MEMSCRAMBLE
Jari Aalto7117c2d2002-07-17 14:10:11 +0000815 if (n)
816 MALLOC_MEMSET ((char *)(p + 1), 0xdf, n); /* scramble previous contents */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000817#endif
Jari Aaltocce855b1998-04-17 19:52:44 +0000818#ifdef MALLOC_STATS
819 _mstats.nmalloc[nunits]++;
820 _mstats.tmalloc[nunits]++;
821 _mstats.nmal++;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000822 _mstats.bytesreq += n;
Jari Aaltocce855b1998-04-17 19:52:44 +0000823#endif /* MALLOC_STATS */
Jari Aaltof73dda02001-11-13 17:56:06 +0000824
825#ifdef MALLOC_TRACE
826 if (malloc_trace && (flags & MALLOC_NOTRACE) == 0)
827 mtrace_alloc ("malloc", p + 1, n, file, line);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000828 else if (_malloc_trace_buckets[nunits])
829 mtrace_alloc ("malloc", p + 1, n, file, line);
Jari Aaltof73dda02001-11-13 17:56:06 +0000830#endif
831
832#ifdef MALLOC_REGISTER
833 if (malloc_register && (flags & MALLOC_NOREG) == 0)
834 mregister_alloc ("malloc", p + 1, n, file, line);
835#endif
836
Jari Aalto7117c2d2002-07-17 14:10:11 +0000837#ifdef MALLOC_WATCH
838 if (_malloc_nwatch > 0)
839 _malloc_ckwatch (p + 1, file, line, W_ALLOC, n);
840#endif
841
842 return (PTR_T) (p + 1);
Jari Aalto726f6381996-08-26 18:22:31 +0000843}
844
Jari Aaltof73dda02001-11-13 17:56:06 +0000845static void
846internal_free (mem, file, line, flags)
Jari Aaltobb706242000-03-17 21:46:59 +0000847 PTR_T mem;
Jari Aaltof73dda02001-11-13 17:56:06 +0000848 const char *file;
849 int line, flags;
Jari Aalto726f6381996-08-26 18:22:31 +0000850{
Jari Aaltocce855b1998-04-17 19:52:44 +0000851 register union mhead *p;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000852 register char *ap, *z;
Jari Aaltocce855b1998-04-17 19:52:44 +0000853 register int nunits;
Jari Aaltof73dda02001-11-13 17:56:06 +0000854 register unsigned int nbytes;
855 int ubytes; /* caller-requested size */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000856 mguard_t mg;
Jari Aalto726f6381996-08-26 18:22:31 +0000857
Jari Aaltobb706242000-03-17 21:46:59 +0000858 if ((ap = (char *)mem) == 0)
Jari Aaltocce855b1998-04-17 19:52:44 +0000859 return;
Jari Aalto726f6381996-08-26 18:22:31 +0000860
Jari Aaltocce855b1998-04-17 19:52:44 +0000861 p = (union mhead *) ap - 1;
Jari Aalto726f6381996-08-26 18:22:31 +0000862
Jari Aaltocce855b1998-04-17 19:52:44 +0000863 if (p->mh_alloc == ISMEMALIGN)
864 {
865 ap -= p->mh_nbytes;
866 p = (union mhead *) ap - 1;
867 }
Jari Aalto726f6381996-08-26 18:22:31 +0000868
Jari Aaltof73dda02001-11-13 17:56:06 +0000869#if defined (MALLOC_TRACE) || defined (MALLOC_REGISTER)
870 if (malloc_trace || malloc_register)
871 ubytes = p->mh_nbytes;
872#endif
873
Jari Aaltocce855b1998-04-17 19:52:44 +0000874 if (p->mh_alloc != ISALLOC)
875 {
876 if (p->mh_alloc == ISFREE)
Jari Aaltof73dda02001-11-13 17:56:06 +0000877 xbotch (mem, ERR_DUPFREE,
Jari Aaltob80f6442004-07-27 13:29:18 +0000878 _("free: called with already freed block argument"), file, line);
Jari Aaltocce855b1998-04-17 19:52:44 +0000879 else
Jari Aaltof73dda02001-11-13 17:56:06 +0000880 xbotch (mem, ERR_UNALLOC,
Jari Aaltob80f6442004-07-27 13:29:18 +0000881 _("free: called with unallocated block argument"), file, line);
Jari Aaltocce855b1998-04-17 19:52:44 +0000882 }
Jari Aalto726f6381996-08-26 18:22:31 +0000883
Jari Aaltocce855b1998-04-17 19:52:44 +0000884 ASSERT (p->mh_magic2 == MAGIC2);
Jari Aaltof73dda02001-11-13 17:56:06 +0000885
886 nunits = p->mh_index;
887 nbytes = ALLOCATED_BYTES(p->mh_nbytes);
888 /* Since the sizeof(u_bits32_t) bytes before the memory handed to the user
889 are now used for the number of bytes allocated, a simple check of
890 mh_magic2 is no longer sufficient to catch things like p[-1] = 'x'.
891 We sanity-check the value of mh_nbytes against the size of the blocks
892 in the appropriate bucket before we use it. This can still cause problems
893 and obscure errors if mh_nbytes is wrong but still within range; the
Jari Aalto7117c2d2002-07-17 14:10:11 +0000894 checks against the size recorded at the end of the chunk will probably
895 fail then. Using MALLOC_REGISTER will help here, since it saves the
896 original number of bytes requested. */
897
Jari Aaltof73dda02001-11-13 17:56:06 +0000898 if (IN_BUCKET(nbytes, nunits) == 0)
899 xbotch (mem, ERR_UNDERFLOW,
Jari Aaltob80f6442004-07-27 13:29:18 +0000900 _("free: underflow detected; mh_nbytes out of range"), file, line);
Jari Aaltof73dda02001-11-13 17:56:06 +0000901
Jari Aaltocce855b1998-04-17 19:52:44 +0000902 ap += p->mh_nbytes;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000903 z = mg.s;
904 *z++ = *ap++, *z++ = *ap++, *z++ = *ap++, *z++ = *ap++;
905 if (mg.i != p->mh_nbytes)
Jari Aaltob80f6442004-07-27 13:29:18 +0000906 xbotch (mem, ERR_ASSERT_FAILED, _("free: start and end chunk sizes differ"), file, line);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000907
Chet Rameyac50fba2014-02-26 09:36:43 -0500908#if GLIBC21
909 if (nunits >= LESSCORE_MIN && ((char *)p + binsize(nunits) == sbrk (0)))
Jari Aalto7117c2d2002-07-17 14:10:11 +0000910#else
Chet Rameyac50fba2014-02-26 09:36:43 -0500911 if (nunits >= LESSCORE_MIN && ((char *)p + binsize(nunits) == memtop))
Jari Aalto7117c2d2002-07-17 14:10:11 +0000912#endif
913 {
914 /* If above LESSCORE_FRC, give back unconditionally. This should be set
915 high enough to be infrequently encountered. If between LESSCORE_MIN
Jari Aalto95732b42005-12-07 14:08:12 +0000916 and LESSCORE_FRC, call lesscore if the bucket is marked as busy or if
917 there's already a block on the free list. */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000918 if ((nunits >= LESSCORE_FRC) || busy[nunits] || nextf[nunits] != 0)
919 {
920 lesscore (nunits);
921 /* keeps the tracing and registering code in one place */
922 goto free_return;
923 }
924 }
Jari Aalto726f6381996-08-26 18:22:31 +0000925
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000926#ifdef MEMSCRAMBLE
Jari Aalto7117c2d2002-07-17 14:10:11 +0000927 if (p->mh_nbytes)
928 MALLOC_MEMSET (mem, 0xcf, p->mh_nbytes);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000929#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000930
Jari Aaltocce855b1998-04-17 19:52:44 +0000931 ASSERT (nunits < NBUCKETS);
Jari Aalto726f6381996-08-26 18:22:31 +0000932
Jari Aaltobb706242000-03-17 21:46:59 +0000933 if (busy[nunits] == 1)
Jari Aalto95732b42005-12-07 14:08:12 +0000934 {
935 xsplit (p, nunits); /* split block and add to different chain */
936 goto free_return;
937 }
Jari Aaltobb706242000-03-17 21:46:59 +0000938
Jari Aalto95732b42005-12-07 14:08:12 +0000939 p->mh_alloc = ISFREE;
Jari Aaltocce855b1998-04-17 19:52:44 +0000940 /* Protect against signal handlers calling malloc. */
941 busy[nunits] = 1;
942 /* Put this block on the free list. */
943 CHAIN (p) = nextf[nunits];
944 nextf[nunits] = p;
945 busy[nunits] = 0;
946
Jari Aalto7117c2d2002-07-17 14:10:11 +0000947free_return:
Jari Aaltob80f6442004-07-27 13:29:18 +0000948 ; /* Empty statement in case this is the end of the function */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000949
Jari Aaltocce855b1998-04-17 19:52:44 +0000950#ifdef MALLOC_STATS
951 _mstats.nmalloc[nunits]--;
952 _mstats.nfre++;
953#endif /* MALLOC_STATS */
Jari Aaltof73dda02001-11-13 17:56:06 +0000954
955#ifdef MALLOC_TRACE
956 if (malloc_trace && (flags & MALLOC_NOTRACE) == 0)
957 mtrace_free (mem, ubytes, file, line);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000958 else if (_malloc_trace_buckets[nunits])
959 mtrace_free (mem, ubytes, file, line);
Jari Aaltof73dda02001-11-13 17:56:06 +0000960#endif
961
962#ifdef MALLOC_REGISTER
963 if (malloc_register && (flags & MALLOC_NOREG) == 0)
964 mregister_free (mem, ubytes, file, line);
965#endif
Jari Aalto7117c2d2002-07-17 14:10:11 +0000966
967#ifdef MALLOC_WATCH
968 if (_malloc_nwatch > 0)
969 _malloc_ckwatch (mem, file, line, W_FREE, ubytes);
970#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000971}
972
Jari Aaltof73dda02001-11-13 17:56:06 +0000973static PTR_T
974internal_realloc (mem, n, file, line, flags)
Jari Aaltobb706242000-03-17 21:46:59 +0000975 PTR_T mem;
Jari Aaltocce855b1998-04-17 19:52:44 +0000976 register size_t n;
Jari Aaltof73dda02001-11-13 17:56:06 +0000977 const char *file;
978 int line, flags;
Jari Aalto726f6381996-08-26 18:22:31 +0000979{
Jari Aaltocce855b1998-04-17 19:52:44 +0000980 register union mhead *p;
Jari Aaltobb706242000-03-17 21:46:59 +0000981 register u_bits32_t tocopy;
Jari Aalto726f6381996-08-26 18:22:31 +0000982 register unsigned int nbytes;
983 register int nunits;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000984 register char *m, *z;
985 mguard_t mg;
Jari Aalto726f6381996-08-26 18:22:31 +0000986
Jari Aaltocce855b1998-04-17 19:52:44 +0000987#ifdef MALLOC_STATS
988 _mstats.nrealloc++;
989#endif
990
991 if (n == 0)
992 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000993 internal_free (mem, file, line, MALLOC_INTERNAL);
Jari Aaltocce855b1998-04-17 19:52:44 +0000994 return (NULL);
995 }
996 if ((p = (union mhead *) mem) == 0)
Jari Aaltof73dda02001-11-13 17:56:06 +0000997 return internal_malloc (n, file, line, MALLOC_INTERNAL);
998
Jari Aalto726f6381996-08-26 18:22:31 +0000999 p--;
Jari Aaltocce855b1998-04-17 19:52:44 +00001000 nunits = p->mh_index;
Jari Aaltof73dda02001-11-13 17:56:06 +00001001 ASSERT (nunits < NBUCKETS);
1002
1003 if (p->mh_alloc != ISALLOC)
1004 xbotch (mem, ERR_UNALLOC,
Jari Aaltob80f6442004-07-27 13:29:18 +00001005 _("realloc: called with unallocated block argument"), file, line);
Jari Aaltof73dda02001-11-13 17:56:06 +00001006
Jari Aaltocce855b1998-04-17 19:52:44 +00001007 ASSERT (p->mh_magic2 == MAGIC2);
Jari Aaltof73dda02001-11-13 17:56:06 +00001008 nbytes = ALLOCATED_BYTES(p->mh_nbytes);
1009 /* Since the sizeof(u_bits32_t) bytes before the memory handed to the user
1010 are now used for the number of bytes allocated, a simple check of
1011 mh_magic2 is no longer sufficient to catch things like p[-1] = 'x'.
1012 We sanity-check the value of mh_nbytes against the size of the blocks
1013 in the appropriate bucket before we use it. This can still cause problems
1014 and obscure errors if mh_nbytes is wrong but still within range; the
Jari Aalto7117c2d2002-07-17 14:10:11 +00001015 checks against the size recorded at the end of the chunk will probably
1016 fail then. Using MALLOC_REGISTER will help here, since it saves the
1017 original number of bytes requested. */
Jari Aaltof73dda02001-11-13 17:56:06 +00001018 if (IN_BUCKET(nbytes, nunits) == 0)
1019 xbotch (mem, ERR_UNDERFLOW,
Jari Aaltob80f6442004-07-27 13:29:18 +00001020 _("realloc: underflow detected; mh_nbytes out of range"), file, line);
Jari Aaltocce855b1998-04-17 19:52:44 +00001021
Jari Aaltobb706242000-03-17 21:46:59 +00001022 m = (char *)mem + (tocopy = p->mh_nbytes);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001023 z = mg.s;
1024 *z++ = *m++, *z++ = *m++, *z++ = *m++, *z++ = *m++;
1025 if (mg.i != p->mh_nbytes)
Jari Aaltob80f6442004-07-27 13:29:18 +00001026 xbotch (mem, ERR_ASSERT_FAILED, _("realloc: start and end chunk sizes differ"), file, line);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001027
1028#ifdef MALLOC_WATCH
1029 if (_malloc_nwatch > 0)
1030 _malloc_ckwatch (p + 1, file, line, W_REALLOC, n);
1031#endif
1032#ifdef MALLOC_STATS
1033 _mstats.bytesreq += (n < tocopy) ? 0 : n - tocopy;
1034#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001035
1036 /* See if desired size rounds to same power of 2 as actual size. */
Jari Aaltof73dda02001-11-13 17:56:06 +00001037 nbytes = ALLOCATED_BYTES(n);
Jari Aalto726f6381996-08-26 18:22:31 +00001038
1039 /* If ok, use the same block, just marking its size as changed. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00001040 if (RIGHT_BUCKET(nbytes, nunits))
Jari Aalto726f6381996-08-26 18:22:31 +00001041 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00001042#if 0
1043 m = (char *)mem + p->mh_nbytes;
1044#else
1045 /* Compensate for increment above. */
1046 m -= 4;
1047#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001048 *m++ = 0; *m++ = 0; *m++ = 0; *m++ = 0;
Jari Aalto7117c2d2002-07-17 14:10:11 +00001049 m = (char *)mem + (p->mh_nbytes = n);
1050
1051 mg.i = n;
1052 z = mg.s;
1053 *m++ = *z++, *m++ = *z++, *m++ = *z++, *m++ = *z++;
1054
Jari Aalto726f6381996-08-26 18:22:31 +00001055 return mem;
1056 }
1057
Jari Aalto7117c2d2002-07-17 14:10:11 +00001058 if (n < tocopy)
1059 tocopy = n;
1060
Jari Aaltocce855b1998-04-17 19:52:44 +00001061#ifdef MALLOC_STATS
1062 _mstats.nrcopy++;
1063#endif
1064
Jari Aaltof73dda02001-11-13 17:56:06 +00001065 if ((m = internal_malloc (n, file, line, MALLOC_INTERNAL|MALLOC_NOTRACE|MALLOC_NOREG)) == 0)
Jari Aaltocce855b1998-04-17 19:52:44 +00001066 return 0;
1067 FASTCOPY (mem, m, tocopy);
Jari Aaltof73dda02001-11-13 17:56:06 +00001068 internal_free (mem, file, line, MALLOC_INTERNAL);
1069
1070#ifdef MALLOC_TRACE
1071 if (malloc_trace && (flags & MALLOC_NOTRACE) == 0)
1072 mtrace_alloc ("realloc", m, n, file, line);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001073 else if (_malloc_trace_buckets[nunits])
1074 mtrace_alloc ("realloc", m, n, file, line);
Jari Aaltof73dda02001-11-13 17:56:06 +00001075#endif
1076
1077#ifdef MALLOC_REGISTER
1078 if (malloc_register && (flags & MALLOC_NOREG) == 0)
1079 mregister_alloc ("realloc", m, n, file, line);
1080#endif
1081
Jari Aalto7117c2d2002-07-17 14:10:11 +00001082#ifdef MALLOC_WATCH
1083 if (_malloc_nwatch > 0)
1084 _malloc_ckwatch (m, file, line, W_RESIZED, n);
1085#endif
1086
Jari Aaltocce855b1998-04-17 19:52:44 +00001087 return m;
Jari Aalto726f6381996-08-26 18:22:31 +00001088}
1089
Jari Aaltof73dda02001-11-13 17:56:06 +00001090static PTR_T
1091internal_memalign (alignment, size, file, line, flags)
Jari Aalto95732b42005-12-07 14:08:12 +00001092 size_t alignment;
Jari Aaltof73dda02001-11-13 17:56:06 +00001093 size_t size;
1094 const char *file;
1095 int line, flags;
1096{
1097 register char *ptr;
1098 register char *aligned;
1099 register union mhead *p;
1100
1101 ptr = internal_malloc (size + alignment, file, line, MALLOC_INTERNAL);
1102
1103 if (ptr == 0)
1104 return 0;
1105 /* If entire block has the desired alignment, just accept it. */
1106 if (((long) ptr & (alignment - 1)) == 0)
1107 return ptr;
1108 /* Otherwise, get address of byte in the block that has that alignment. */
1109#if 0
1110 aligned = (char *) (((long) ptr + alignment - 1) & -alignment);
1111#else
1112 aligned = (char *) (((long) ptr + alignment - 1) & (~alignment + 1));
1113#endif
1114
1115 /* Store a suitable indication of how to free the block,
1116 so that free can find the true beginning of it. */
1117 p = (union mhead *) aligned - 1;
1118 p->mh_nbytes = aligned - ptr;
1119 p->mh_alloc = ISMEMALIGN;
1120
1121 return aligned;
1122}
1123
1124#if !defined (NO_VALLOC)
1125/* This runs into trouble with getpagesize on HPUX, and Multimax machines.
1126 Patching out seems cleaner than the ugly fix needed. */
1127static PTR_T
1128internal_valloc (size, file, line, flags)
1129 size_t size;
1130 const char *file;
1131 int line, flags;
1132{
1133 return internal_memalign (getpagesize (), size, file, line, flags|MALLOC_INTERNAL);
1134}
1135#endif /* !NO_VALLOC */
1136
1137#ifndef NO_CALLOC
1138static PTR_T
1139internal_calloc (n, s, file, line, flags)
1140 size_t n, s;
1141 const char *file;
1142 int line, flags;
1143{
1144 size_t total;
1145 PTR_T result;
1146
1147 total = n * s;
1148 result = internal_malloc (total, file, line, flags|MALLOC_INTERNAL);
1149 if (result)
Jari Aalto7117c2d2002-07-17 14:10:11 +00001150 memset (result, 0, total);
Jari Aaltof73dda02001-11-13 17:56:06 +00001151 return result;
1152}
1153
1154static void
1155internal_cfree (p, file, line, flags)
1156 PTR_T p;
1157 const char *file;
1158 int line, flags;
1159{
1160 internal_free (p, file, line, flags|MALLOC_INTERNAL);
1161}
1162#endif /* !NO_CALLOC */
1163
1164#ifdef MALLOC_STATS
Jari Aaltof73dda02001-11-13 17:56:06 +00001165int
1166malloc_free_blocks (size)
1167 int size;
1168{
1169 int nfree;
1170 register union mhead *p;
1171
1172 nfree = 0;
1173 for (p = nextf[size]; p; p = CHAIN (p))
1174 nfree++;
1175
1176 return nfree;
1177}
1178#endif
1179
Jari Aalto7117c2d2002-07-17 14:10:11 +00001180#if defined (MALLOC_WRAPFUNCS)
Jari Aaltof73dda02001-11-13 17:56:06 +00001181PTR_T
1182sh_malloc (bytes, file, line)
1183 size_t bytes;
1184 const char *file;
1185 int line;
1186{
1187 return internal_malloc (bytes, file, line, MALLOC_WRAPPER);
1188}
1189
1190PTR_T
1191sh_realloc (ptr, size, file, line)
1192 PTR_T ptr;
1193 size_t size;
1194 const char *file;
1195 int line;
1196{
1197 return internal_realloc (ptr, size, file, line, MALLOC_WRAPPER);
1198}
1199
1200void
1201sh_free (mem, file, line)
1202 PTR_T mem;
1203 const char *file;
1204 int line;
1205{
1206 internal_free (mem, file, line, MALLOC_WRAPPER);
1207}
1208
1209PTR_T
1210sh_memalign (alignment, size, file, line)
Jari Aalto95732b42005-12-07 14:08:12 +00001211 size_t alignment;
Jari Aaltof73dda02001-11-13 17:56:06 +00001212 size_t size;
1213 const char *file;
1214 int line;
1215{
1216 return internal_memalign (alignment, size, file, line, MALLOC_WRAPPER);
1217}
1218
1219#ifndef NO_CALLOC
1220PTR_T
1221sh_calloc (n, s, file, line)
1222 size_t n, s;
1223 const char *file;
1224 int line;
1225{
1226 return internal_calloc (n, s, file, line, MALLOC_WRAPPER);
1227}
1228
1229void
1230sh_cfree (mem, file, line)
1231 PTR_T mem;
1232 const char *file;
1233 int line;
1234{
1235 internal_cfree (mem, file, line, MALLOC_WRAPPER);
1236}
1237#endif
1238
1239#ifndef NO_VALLOC
1240PTR_T
1241sh_valloc (size, file, line)
1242 size_t size;
1243 const char *file;
1244 int line;
1245{
1246 return internal_valloc (size, file, line, MALLOC_WRAPPER);
1247}
Jari Aalto7117c2d2002-07-17 14:10:11 +00001248#endif /* !NO_VALLOC */
Jari Aaltof73dda02001-11-13 17:56:06 +00001249
Jari Aalto7117c2d2002-07-17 14:10:11 +00001250#endif /* MALLOC_WRAPFUNCS */
Jari Aaltof73dda02001-11-13 17:56:06 +00001251
1252/* Externally-available functions that call their internal counterparts. */
1253
1254PTR_T
1255malloc (size)
1256 size_t size;
1257{
1258 return internal_malloc (size, (char *)NULL, 0, 0);
1259}
1260
1261PTR_T
1262realloc (mem, nbytes)
1263 PTR_T mem;
1264 size_t nbytes;
1265{
1266 return internal_realloc (mem, nbytes, (char *)NULL, 0, 0);
1267}
1268
1269void
1270free (mem)
1271 PTR_T mem;
1272{
1273 internal_free (mem, (char *)NULL, 0, 0);
1274}
1275
Jari Aaltobb706242000-03-17 21:46:59 +00001276PTR_T
Jari Aalto726f6381996-08-26 18:22:31 +00001277memalign (alignment, size)
Jari Aalto95732b42005-12-07 14:08:12 +00001278 size_t alignment;
Jari Aaltocce855b1998-04-17 19:52:44 +00001279 size_t size;
Jari Aalto726f6381996-08-26 18:22:31 +00001280{
Jari Aaltof73dda02001-11-13 17:56:06 +00001281 return internal_memalign (alignment, size, (char *)NULL, 0, 0);
Jari Aalto726f6381996-08-26 18:22:31 +00001282}
1283
Jari Aaltof73dda02001-11-13 17:56:06 +00001284#ifndef NO_VALLOC
Jari Aaltobb706242000-03-17 21:46:59 +00001285PTR_T
Jari Aalto726f6381996-08-26 18:22:31 +00001286valloc (size)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001287 size_t size;
Jari Aalto726f6381996-08-26 18:22:31 +00001288{
Jari Aaltof73dda02001-11-13 17:56:06 +00001289 return internal_valloc (size, (char *)NULL, 0, 0);
Jari Aalto726f6381996-08-26 18:22:31 +00001290}
Jari Aaltof73dda02001-11-13 17:56:06 +00001291#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001292
1293#ifndef NO_CALLOC
Jari Aaltobb706242000-03-17 21:46:59 +00001294PTR_T
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001295calloc (n, s)
1296 size_t n, s;
1297{
Jari Aaltof73dda02001-11-13 17:56:06 +00001298 return internal_calloc (n, s, (char *)NULL, 0, 0);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001299}
1300
1301void
Jari Aaltof73dda02001-11-13 17:56:06 +00001302cfree (mem)
1303 PTR_T mem;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001304{
Jari Aaltof73dda02001-11-13 17:56:06 +00001305 internal_cfree (mem, (char *)NULL, 0, 0);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001306}
Jari Aaltof73dda02001-11-13 17:56:06 +00001307#endif