Merge tag 'u-boot-at91-fixes-2023.10-b' of https://source.denx.de/u-boot/custodians...
[platform/kernel/u-boot.git] / common / dlmalloc.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * This code is based on a version (aka dlmalloc) of malloc/free/realloc written
4  * by Doug Lea and released to the public domain, as explained at
5  * http://creativecommons.org/publicdomain/zero/1.0/-
6  *
7  * The original code is available at http://gee.cs.oswego.edu/pub/misc/
8  * as file malloc-2.6.6.c.
9  */
10
11 #include <common.h>
12 #include <log.h>
13 #include <asm/global_data.h>
14
15 #if CONFIG_IS_ENABLED(UNIT_TEST)
16 #define DEBUG
17 #endif
18
19 #include <malloc.h>
20 #include <asm/io.h>
21 #include <valgrind/memcheck.h>
22
23 #ifdef DEBUG
24 #if __STD_C
25 static void malloc_update_mallinfo (void);
26 void malloc_stats (void);
27 #else
28 static void malloc_update_mallinfo ();
29 void malloc_stats();
30 #endif
31 #endif  /* DEBUG */
32
33 DECLARE_GLOBAL_DATA_PTR;
34
35 /*
36   Emulation of sbrk for WIN32
37   All code within the ifdef WIN32 is untested by me.
38
39   Thanks to Martin Fong and others for supplying this.
40 */
41
42
43 #ifdef WIN32
44
45 #define AlignPage(add) (((add) + (malloc_getpagesize-1)) & \
46 ~(malloc_getpagesize-1))
47 #define AlignPage64K(add) (((add) + (0x10000 - 1)) & ~(0x10000 - 1))
48
49 /* resrve 64MB to insure large contiguous space */
50 #define RESERVED_SIZE (1024*1024*64)
51 #define NEXT_SIZE (2048*1024)
52 #define TOP_MEMORY ((unsigned long)2*1024*1024*1024)
53
54 struct GmListElement;
55 typedef struct GmListElement GmListElement;
56
57 struct GmListElement
58 {
59         GmListElement* next;
60         void* base;
61 };
62
63 static GmListElement* head = 0;
64 static unsigned int gNextAddress = 0;
65 static unsigned int gAddressBase = 0;
66 static unsigned int gAllocatedSize = 0;
67
68 static
69 GmListElement* makeGmListElement (void* bas)
70 {
71         GmListElement* this;
72         this = (GmListElement*)(void*)LocalAlloc (0, sizeof (GmListElement));
73         assert (this);
74         if (this)
75         {
76                 this->base = bas;
77                 this->next = head;
78                 head = this;
79         }
80         return this;
81 }
82
83 void gcleanup (void)
84 {
85         BOOL rval;
86         assert ( (head == NULL) || (head->base == (void*)gAddressBase));
87         if (gAddressBase && (gNextAddress - gAddressBase))
88         {
89                 rval = VirtualFree ((void*)gAddressBase,
90                                                         gNextAddress - gAddressBase,
91                                                         MEM_DECOMMIT);
92         assert (rval);
93         }
94         while (head)
95         {
96                 GmListElement* next = head->next;
97                 rval = VirtualFree (head->base, 0, MEM_RELEASE);
98                 assert (rval);
99                 LocalFree (head);
100                 head = next;
101         }
102 }
103
104 static
105 void* findRegion (void* start_address, unsigned long size)
106 {
107         MEMORY_BASIC_INFORMATION info;
108         if (size >= TOP_MEMORY) return NULL;
109
110         while ((unsigned long)start_address + size < TOP_MEMORY)
111         {
112                 VirtualQuery (start_address, &info, sizeof (info));
113                 if ((info.State == MEM_FREE) && (info.RegionSize >= size))
114                         return start_address;
115                 else
116                 {
117                         /* Requested region is not available so see if the */
118                         /* next region is available.  Set 'start_address' */
119                         /* to the next region and call 'VirtualQuery()' */
120                         /* again. */
121
122                         start_address = (char*)info.BaseAddress + info.RegionSize;
123
124                         /* Make sure we start looking for the next region */
125                         /* on the *next* 64K boundary.  Otherwise, even if */
126                         /* the new region is free according to */
127                         /* 'VirtualQuery()', the subsequent call to */
128                         /* 'VirtualAlloc()' (which follows the call to */
129                         /* this routine in 'wsbrk()') will round *down* */
130                         /* the requested address to a 64K boundary which */
131                         /* we already know is an address in the */
132                         /* unavailable region.  Thus, the subsequent call */
133                         /* to 'VirtualAlloc()' will fail and bring us back */
134                         /* here, causing us to go into an infinite loop. */
135
136                         start_address =
137                                 (void *) AlignPage64K((unsigned long) start_address);
138                 }
139         }
140         return NULL;
141
142 }
143
144
145 void* wsbrk (long size)
146 {
147         void* tmp;
148         if (size > 0)
149         {
150                 if (gAddressBase == 0)
151                 {
152                         gAllocatedSize = max (RESERVED_SIZE, AlignPage (size));
153                         gNextAddress = gAddressBase =
154                                 (unsigned int)VirtualAlloc (NULL, gAllocatedSize,
155                                                                                         MEM_RESERVE, PAGE_NOACCESS);
156                 } else if (AlignPage (gNextAddress + size) > (gAddressBase +
157 gAllocatedSize))
158                 {
159                         long new_size = max (NEXT_SIZE, AlignPage (size));
160                         void* new_address = (void*)(gAddressBase+gAllocatedSize);
161                         do
162                         {
163                                 new_address = findRegion (new_address, new_size);
164
165                                 if (!new_address)
166                                         return (void*)-1;
167
168                                 gAddressBase = gNextAddress =
169                                         (unsigned int)VirtualAlloc (new_address, new_size,
170                                                                                                 MEM_RESERVE, PAGE_NOACCESS);
171                                 /* repeat in case of race condition */
172                                 /* The region that we found has been snagged */
173                                 /* by another thread */
174                         }
175                         while (gAddressBase == 0);
176
177                         assert (new_address == (void*)gAddressBase);
178
179                         gAllocatedSize = new_size;
180
181                         if (!makeGmListElement ((void*)gAddressBase))
182                                 return (void*)-1;
183                 }
184                 if ((size + gNextAddress) > AlignPage (gNextAddress))
185                 {
186                         void* res;
187                         res = VirtualAlloc ((void*)AlignPage (gNextAddress),
188                                                                 (size + gNextAddress -
189                                                                  AlignPage (gNextAddress)),
190                                                                 MEM_COMMIT, PAGE_READWRITE);
191                         if (!res)
192                                 return (void*)-1;
193                 }
194                 tmp = (void*)gNextAddress;
195                 gNextAddress = (unsigned int)tmp + size;
196                 return tmp;
197         }
198         else if (size < 0)
199         {
200                 unsigned int alignedGoal = AlignPage (gNextAddress + size);
201                 /* Trim by releasing the virtual memory */
202                 if (alignedGoal >= gAddressBase)
203                 {
204                         VirtualFree ((void*)alignedGoal, gNextAddress - alignedGoal,
205                                                  MEM_DECOMMIT);
206                         gNextAddress = gNextAddress + size;
207                         return (void*)gNextAddress;
208                 }
209                 else
210                 {
211                         VirtualFree ((void*)gAddressBase, gNextAddress - gAddressBase,
212                                                  MEM_DECOMMIT);
213                         gNextAddress = gAddressBase;
214                         return (void*)-1;
215                 }
216         }
217         else
218         {
219                 return (void*)gNextAddress;
220         }
221 }
222
223 #endif
224
225
226
227 /*
228   Type declarations
229 */
230
231
232 struct malloc_chunk
233 {
234   INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */
235   INTERNAL_SIZE_T size;      /* Size in bytes, including overhead. */
236   struct malloc_chunk* fd;   /* double links -- used only if free. */
237   struct malloc_chunk* bk;
238 } __attribute__((__may_alias__)) ;
239
240 typedef struct malloc_chunk* mchunkptr;
241
242 /*
243
244    malloc_chunk details:
245
246     (The following includes lightly edited explanations by Colin Plumb.)
247
248     Chunks of memory are maintained using a `boundary tag' method as
249     described in e.g., Knuth or Standish.  (See the paper by Paul
250     Wilson ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a
251     survey of such techniques.)  Sizes of free chunks are stored both
252     in the front of each chunk and at the end.  This makes
253     consolidating fragmented chunks into bigger chunks very fast.  The
254     size fields also hold bits representing whether chunks are free or
255     in use.
256
257     An allocated chunk looks like this:
258
259
260     chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
261             |             Size of previous chunk, if allocated            | |
262             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
263             |             Size of chunk, in bytes                         |P|
264       mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
265             |             User data starts here...                          .
266             .                                                               .
267             .             (malloc_usable_space() bytes)                     .
268             .                                                               |
269 nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
270             |             Size of chunk                                     |
271             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
272
273
274     Where "chunk" is the front of the chunk for the purpose of most of
275     the malloc code, but "mem" is the pointer that is returned to the
276     user.  "Nextchunk" is the beginning of the next contiguous chunk.
277
278     Chunks always begin on even word boundries, so the mem portion
279     (which is returned to the user) is also on an even word boundary, and
280     thus double-word aligned.
281
282     Free chunks are stored in circular doubly-linked lists, and look like this:
283
284     chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
285             |             Size of previous chunk                            |
286             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
287     `head:' |             Size of chunk, in bytes                         |P|
288       mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
289             |             Forward pointer to next chunk in list             |
290             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
291             |             Back pointer to previous chunk in list            |
292             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
293             |             Unused space (may be 0 bytes long)                .
294             .                                                               .
295             .                                                               |
296
297 nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
298     `foot:' |             Size of chunk, in bytes                           |
299             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
300
301     The P (PREV_INUSE) bit, stored in the unused low-order bit of the
302     chunk size (which is always a multiple of two words), is an in-use
303     bit for the *previous* chunk.  If that bit is *clear*, then the
304     word before the current chunk size contains the previous chunk
305     size, and can be used to find the front of the previous chunk.
306     (The very first chunk allocated always has this bit set,
307     preventing access to non-existent (or non-owned) memory.)
308
309     Note that the `foot' of the current chunk is actually represented
310     as the prev_size of the NEXT chunk. (This makes it easier to
311     deal with alignments etc).
312
313     The two exceptions to all this are
314
315      1. The special chunk `top', which doesn't bother using the
316         trailing size field since there is no
317         next contiguous chunk that would have to index off it. (After
318         initialization, `top' is forced to always exist.  If it would
319         become less than MINSIZE bytes long, it is replenished via
320         malloc_extend_top.)
321
322      2. Chunks allocated via mmap, which have the second-lowest-order
323         bit (IS_MMAPPED) set in their size fields.  Because they are
324         never merged or traversed from any other chunk, they have no
325         foot size or inuse information.
326
327     Available chunks are kept in any of several places (all declared below):
328
329     * `av': An array of chunks serving as bin headers for consolidated
330        chunks. Each bin is doubly linked.  The bins are approximately
331        proportionally (log) spaced.  There are a lot of these bins
332        (128). This may look excessive, but works very well in
333        practice.  All procedures maintain the invariant that no
334        consolidated chunk physically borders another one. Chunks in
335        bins are kept in size order, with ties going to the
336        approximately least recently used chunk.
337
338        The chunks in each bin are maintained in decreasing sorted order by
339        size.  This is irrelevant for the small bins, which all contain
340        the same-sized chunks, but facilitates best-fit allocation for
341        larger chunks. (These lists are just sequential. Keeping them in
342        order almost never requires enough traversal to warrant using
343        fancier ordered data structures.)  Chunks of the same size are
344        linked with the most recently freed at the front, and allocations
345        are taken from the back.  This results in LRU or FIFO allocation
346        order, which tends to give each chunk an equal opportunity to be
347        consolidated with adjacent freed chunks, resulting in larger free
348        chunks and less fragmentation.
349
350     * `top': The top-most available chunk (i.e., the one bordering the
351        end of available memory) is treated specially. It is never
352        included in any bin, is used only if no other chunk is
353        available, and is released back to the system if it is very
354        large (see M_TRIM_THRESHOLD).
355
356     * `last_remainder': A bin holding only the remainder of the
357        most recently split (non-top) chunk. This bin is checked
358        before other non-fitting chunks, so as to provide better
359        locality for runs of sequentially allocated chunks.
360
361     *  Implicitly, through the host system's memory mapping tables.
362        If supported, requests greater than a threshold are usually
363        serviced via calls to mmap, and then later released via munmap.
364
365 */
366
367 /*  sizes, alignments */
368
369 #define SIZE_SZ                (sizeof(INTERNAL_SIZE_T))
370 #define MALLOC_ALIGNMENT       (SIZE_SZ + SIZE_SZ)
371 #define MALLOC_ALIGN_MASK      (MALLOC_ALIGNMENT - 1)
372 #define MINSIZE                (sizeof(struct malloc_chunk))
373
374 /* conversion from malloc headers to user pointers, and back */
375
376 #define chunk2mem(p)   ((Void_t*)((char*)(p) + 2*SIZE_SZ))
377 #define mem2chunk(mem) ((mchunkptr)((char*)(mem) - 2*SIZE_SZ))
378
379 /* pad request bytes into a usable size */
380
381 #define request2size(req) \
382  (((long)((req) + (SIZE_SZ + MALLOC_ALIGN_MASK)) < \
383   (long)(MINSIZE + MALLOC_ALIGN_MASK)) ? MINSIZE : \
384    (((req) + (SIZE_SZ + MALLOC_ALIGN_MASK)) & ~(MALLOC_ALIGN_MASK)))
385
386 /* Check if m has acceptable alignment */
387
388 #define aligned_OK(m)    (((unsigned long)((m)) & (MALLOC_ALIGN_MASK)) == 0)
389
390
391
392
393 /*
394   Physical chunk operations
395 */
396
397
398 /* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */
399
400 #define PREV_INUSE 0x1
401
402 /* size field is or'ed with IS_MMAPPED if the chunk was obtained with mmap() */
403
404 #define IS_MMAPPED 0x2
405
406 /* Bits to mask off when extracting size */
407
408 #define SIZE_BITS (PREV_INUSE|IS_MMAPPED)
409
410
411 /* Ptr to next physical malloc_chunk. */
412
413 #define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->size & ~PREV_INUSE) ))
414
415 /* Ptr to previous physical malloc_chunk */
416
417 #define prev_chunk(p)\
418    ((mchunkptr)( ((char*)(p)) - ((p)->prev_size) ))
419
420
421 /* Treat space at ptr + offset as a chunk */
422
423 #define chunk_at_offset(p, s)  ((mchunkptr)(((char*)(p)) + (s)))
424
425
426
427
428 /*
429   Dealing with use bits
430 */
431
432 /* extract p's inuse bit */
433
434 #define inuse(p)\
435 ((((mchunkptr)(((char*)(p))+((p)->size & ~PREV_INUSE)))->size) & PREV_INUSE)
436
437 /* extract inuse bit of previous chunk */
438
439 #define prev_inuse(p)  ((p)->size & PREV_INUSE)
440
441 /* check for mmap()'ed chunk */
442
443 #define chunk_is_mmapped(p) ((p)->size & IS_MMAPPED)
444
445 /* set/clear chunk as in use without otherwise disturbing */
446
447 #define set_inuse(p)\
448 ((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size |= PREV_INUSE
449
450 #define clear_inuse(p)\
451 ((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size &= ~(PREV_INUSE)
452
453 /* check/set/clear inuse bits in known places */
454
455 #define inuse_bit_at_offset(p, s)\
456  (((mchunkptr)(((char*)(p)) + (s)))->size & PREV_INUSE)
457
458 #define set_inuse_bit_at_offset(p, s)\
459  (((mchunkptr)(((char*)(p)) + (s)))->size |= PREV_INUSE)
460
461 #define clear_inuse_bit_at_offset(p, s)\
462  (((mchunkptr)(((char*)(p)) + (s)))->size &= ~(PREV_INUSE))
463
464
465
466
467 /*
468   Dealing with size fields
469 */
470
471 /* Get size, ignoring use bits */
472
473 #define chunksize(p)          ((p)->size & ~(SIZE_BITS))
474
475 /* Set size at head, without disturbing its use bit */
476
477 #define set_head_size(p, s)   ((p)->size = (((p)->size & PREV_INUSE) | (s)))
478
479 /* Set size/use ignoring previous bits in header */
480
481 #define set_head(p, s)        ((p)->size = (s))
482
483 /* Set size at footer (only when chunk is not in use) */
484
485 #define set_foot(p, s)   (((mchunkptr)((char*)(p) + (s)))->prev_size = (s))
486
487
488
489
490
491 /*
492    Bins
493
494     The bins, `av_' are an array of pairs of pointers serving as the
495     heads of (initially empty) doubly-linked lists of chunks, laid out
496     in a way so that each pair can be treated as if it were in a
497     malloc_chunk. (This way, the fd/bk offsets for linking bin heads
498     and chunks are the same).
499
500     Bins for sizes < 512 bytes contain chunks of all the same size, spaced
501     8 bytes apart. Larger bins are approximately logarithmically
502     spaced. (See the table below.) The `av_' array is never mentioned
503     directly in the code, but instead via bin access macros.
504
505     Bin layout:
506
507     64 bins of size       8
508     32 bins of size      64
509     16 bins of size     512
510      8 bins of size    4096
511      4 bins of size   32768
512      2 bins of size  262144
513      1 bin  of size what's left
514
515     There is actually a little bit of slop in the numbers in bin_index
516     for the sake of speed. This makes no difference elsewhere.
517
518     The special chunks `top' and `last_remainder' get their own bins,
519     (this is implemented via yet more trickery with the av_ array),
520     although `top' is never properly linked to its bin since it is
521     always handled specially.
522
523 */
524
525 #define NAV             128   /* number of bins */
526
527 typedef struct malloc_chunk* mbinptr;
528
529 /* access macros */
530
531 #define bin_at(i)      ((mbinptr)((char*)&(av_[2*(i) + 2]) - 2*SIZE_SZ))
532 #define next_bin(b)    ((mbinptr)((char*)(b) + 2 * sizeof(mbinptr)))
533 #define prev_bin(b)    ((mbinptr)((char*)(b) - 2 * sizeof(mbinptr)))
534
535 /*
536    The first 2 bins are never indexed. The corresponding av_ cells are instead
537    used for bookkeeping. This is not to save space, but to simplify
538    indexing, maintain locality, and avoid some initialization tests.
539 */
540
541 #define top            (av_[2])          /* The topmost chunk */
542 #define last_remainder (bin_at(1))       /* remainder from last split */
543
544
545 /*
546    Because top initially points to its own bin with initial
547    zero size, thus forcing extension on the first malloc request,
548    we avoid having any special code in malloc to check whether
549    it even exists yet. But we still need to in malloc_extend_top.
550 */
551
552 #define initial_top    ((mchunkptr)(bin_at(0)))
553
554 /* Helper macro to initialize bins */
555
556 #define IAV(i)  bin_at(i), bin_at(i)
557
558 static mbinptr av_[NAV * 2 + 2] = {
559  NULL, NULL,
560  IAV(0),   IAV(1),   IAV(2),   IAV(3),   IAV(4),   IAV(5),   IAV(6),   IAV(7),
561  IAV(8),   IAV(9),   IAV(10),  IAV(11),  IAV(12),  IAV(13),  IAV(14),  IAV(15),
562  IAV(16),  IAV(17),  IAV(18),  IAV(19),  IAV(20),  IAV(21),  IAV(22),  IAV(23),
563  IAV(24),  IAV(25),  IAV(26),  IAV(27),  IAV(28),  IAV(29),  IAV(30),  IAV(31),
564  IAV(32),  IAV(33),  IAV(34),  IAV(35),  IAV(36),  IAV(37),  IAV(38),  IAV(39),
565  IAV(40),  IAV(41),  IAV(42),  IAV(43),  IAV(44),  IAV(45),  IAV(46),  IAV(47),
566  IAV(48),  IAV(49),  IAV(50),  IAV(51),  IAV(52),  IAV(53),  IAV(54),  IAV(55),
567  IAV(56),  IAV(57),  IAV(58),  IAV(59),  IAV(60),  IAV(61),  IAV(62),  IAV(63),
568  IAV(64),  IAV(65),  IAV(66),  IAV(67),  IAV(68),  IAV(69),  IAV(70),  IAV(71),
569  IAV(72),  IAV(73),  IAV(74),  IAV(75),  IAV(76),  IAV(77),  IAV(78),  IAV(79),
570  IAV(80),  IAV(81),  IAV(82),  IAV(83),  IAV(84),  IAV(85),  IAV(86),  IAV(87),
571  IAV(88),  IAV(89),  IAV(90),  IAV(91),  IAV(92),  IAV(93),  IAV(94),  IAV(95),
572  IAV(96),  IAV(97),  IAV(98),  IAV(99),  IAV(100), IAV(101), IAV(102), IAV(103),
573  IAV(104), IAV(105), IAV(106), IAV(107), IAV(108), IAV(109), IAV(110), IAV(111),
574  IAV(112), IAV(113), IAV(114), IAV(115), IAV(116), IAV(117), IAV(118), IAV(119),
575  IAV(120), IAV(121), IAV(122), IAV(123), IAV(124), IAV(125), IAV(126), IAV(127)
576 };
577
578 #ifdef CONFIG_NEEDS_MANUAL_RELOC
579 static void malloc_bin_reloc(void)
580 {
581         mbinptr *p = &av_[2];
582         size_t i;
583
584         for (i = 2; i < ARRAY_SIZE(av_); ++i, ++p)
585                 *p = (mbinptr)((ulong)*p + gd->reloc_off);
586 }
587 #else
588 static inline void malloc_bin_reloc(void) {}
589 #endif
590
591 #ifdef CONFIG_SYS_MALLOC_DEFAULT_TO_INIT
592 static void malloc_init(void);
593 #endif
594
595 ulong mem_malloc_start = 0;
596 ulong mem_malloc_end = 0;
597 ulong mem_malloc_brk = 0;
598
599 static bool malloc_testing;     /* enable test mode */
600 static int malloc_max_allocs;   /* return NULL after this many calls to malloc() */
601
602 void *sbrk(ptrdiff_t increment)
603 {
604         ulong old = mem_malloc_brk;
605         ulong new = old + increment;
606
607         /*
608          * if we are giving memory back make sure we clear it out since
609          * we set MORECORE_CLEARS to 1
610          */
611         if (increment < 0)
612                 memset((void *)new, 0, -increment);
613
614         if ((new < mem_malloc_start) || (new > mem_malloc_end))
615                 return (void *)MORECORE_FAILURE;
616
617         mem_malloc_brk = new;
618
619         return (void *)old;
620 }
621
622 void mem_malloc_init(ulong start, ulong size)
623 {
624         mem_malloc_start = start;
625         mem_malloc_end = start + size;
626         mem_malloc_brk = start;
627
628 #ifdef CONFIG_SYS_MALLOC_DEFAULT_TO_INIT
629         malloc_init();
630 #endif
631
632         debug("using memory %#lx-%#lx for malloc()\n", mem_malloc_start,
633               mem_malloc_end);
634 #if CONFIG_IS_ENABLED(SYS_MALLOC_CLEAR_ON_INIT)
635         memset((void *)mem_malloc_start, 0x0, size);
636 #endif
637         malloc_bin_reloc();
638 }
639
640 /* field-extraction macros */
641
642 #define first(b) ((b)->fd)
643 #define last(b)  ((b)->bk)
644
645 /*
646   Indexing into bins
647 */
648
649 #define bin_index(sz)                                                          \
650 (((((unsigned long)(sz)) >> 9) ==    0) ?       (((unsigned long)(sz)) >>  3): \
651  ((((unsigned long)(sz)) >> 9) <=    4) ?  56 + (((unsigned long)(sz)) >>  6): \
652  ((((unsigned long)(sz)) >> 9) <=   20) ?  91 + (((unsigned long)(sz)) >>  9): \
653  ((((unsigned long)(sz)) >> 9) <=   84) ? 110 + (((unsigned long)(sz)) >> 12): \
654  ((((unsigned long)(sz)) >> 9) <=  340) ? 119 + (((unsigned long)(sz)) >> 15): \
655  ((((unsigned long)(sz)) >> 9) <= 1364) ? 124 + (((unsigned long)(sz)) >> 18): \
656                                           126)
657 /*
658   bins for chunks < 512 are all spaced 8 bytes apart, and hold
659   identically sized chunks. This is exploited in malloc.
660 */
661
662 #define MAX_SMALLBIN         63
663 #define MAX_SMALLBIN_SIZE   512
664 #define SMALLBIN_WIDTH        8
665
666 #define smallbin_index(sz)  (((unsigned long)(sz)) >> 3)
667
668 /*
669    Requests are `small' if both the corresponding and the next bin are small
670 */
671
672 #define is_small_request(nb) (nb < MAX_SMALLBIN_SIZE - SMALLBIN_WIDTH)
673
674
675
676 /*
677     To help compensate for the large number of bins, a one-level index
678     structure is used for bin-by-bin searching.  `binblocks' is a
679     one-word bitvector recording whether groups of BINBLOCKWIDTH bins
680     have any (possibly) non-empty bins, so they can be skipped over
681     all at once during during traversals. The bits are NOT always
682     cleared as soon as all bins in a block are empty, but instead only
683     when all are noticed to be empty during traversal in malloc.
684 */
685
686 #define BINBLOCKWIDTH     4   /* bins per block */
687
688 #define binblocks_r     ((INTERNAL_SIZE_T)av_[1]) /* bitvector of nonempty blocks */
689 #define binblocks_w     (av_[1])
690
691 /* bin<->block macros */
692
693 #define idx2binblock(ix)    ((unsigned)1 << (ix / BINBLOCKWIDTH))
694 #define mark_binblock(ii)   (binblocks_w = (mbinptr)(binblocks_r | idx2binblock(ii)))
695 #define clear_binblock(ii)  (binblocks_w = (mbinptr)(binblocks_r & ~(idx2binblock(ii))))
696
697
698
699
700
701 /*  Other static bookkeeping data */
702
703 /* variables holding tunable values */
704
705 static unsigned long trim_threshold   = DEFAULT_TRIM_THRESHOLD;
706 static unsigned long top_pad          = DEFAULT_TOP_PAD;
707 static unsigned int  n_mmaps_max      = DEFAULT_MMAP_MAX;
708 static unsigned long mmap_threshold   = DEFAULT_MMAP_THRESHOLD;
709
710 /* The first value returned from sbrk */
711 static char* sbrk_base = (char*)(-1);
712
713 /* The maximum memory obtained from system via sbrk */
714 static unsigned long max_sbrked_mem = 0;
715
716 /* The maximum via either sbrk or mmap */
717 static unsigned long max_total_mem = 0;
718
719 /* internal working copy of mallinfo */
720 static struct mallinfo current_mallinfo = {  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
721
722 /* The total memory obtained from system via sbrk */
723 #define sbrked_mem  (current_mallinfo.arena)
724
725 /* Tracking mmaps */
726
727 #ifdef DEBUG
728 static unsigned int n_mmaps = 0;
729 #endif  /* DEBUG */
730 static unsigned long mmapped_mem = 0;
731 #if HAVE_MMAP
732 static unsigned int max_n_mmaps = 0;
733 static unsigned long max_mmapped_mem = 0;
734 #endif
735
736 #ifdef CONFIG_SYS_MALLOC_DEFAULT_TO_INIT
737 static void malloc_init(void)
738 {
739         int i, j;
740
741         debug("bins (av_ array) are at %p\n", (void *)av_);
742
743         av_[0] = NULL; av_[1] = NULL;
744         for (i = 2, j = 2; i < NAV * 2 + 2; i += 2, j++) {
745                 av_[i] = bin_at(j - 2);
746                 av_[i + 1] = bin_at(j - 2);
747
748                 /* Just print the first few bins so that
749                  * we can see there are alright.
750                  */
751                 if (i < 10)
752                         debug("av_[%d]=%lx av_[%d]=%lx\n",
753                               i, (ulong)av_[i],
754                               i + 1, (ulong)av_[i + 1]);
755         }
756
757         /* Init the static bookkeeping as well */
758         sbrk_base = (char *)(-1);
759         max_sbrked_mem = 0;
760         max_total_mem = 0;
761 #ifdef DEBUG
762         memset((void *)&current_mallinfo, 0, sizeof(struct mallinfo));
763 #endif
764 }
765 #endif
766
767 /*
768   Debugging support
769 */
770
771 #ifdef DEBUG
772
773
774 /*
775   These routines make a number of assertions about the states
776   of data structures that should be true at all times. If any
777   are not true, it's very likely that a user program has somehow
778   trashed memory. (It's also possible that there is a coding error
779   in malloc. In which case, please report it!)
780 */
781
782 #if __STD_C
783 static void do_check_chunk(mchunkptr p)
784 #else
785 static void do_check_chunk(p) mchunkptr p;
786 #endif
787 {
788   INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE;
789
790   /* No checkable chunk is mmapped */
791   assert(!chunk_is_mmapped(p));
792
793   /* Check for legal address ... */
794   assert((char*)p >= sbrk_base);
795   if (p != top)
796     assert((char*)p + sz <= (char*)top);
797   else
798     assert((char*)p + sz <= sbrk_base + sbrked_mem);
799
800 }
801
802
803 #if __STD_C
804 static void do_check_free_chunk(mchunkptr p)
805 #else
806 static void do_check_free_chunk(p) mchunkptr p;
807 #endif
808 {
809   INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE;
810   mchunkptr next = chunk_at_offset(p, sz);
811
812   do_check_chunk(p);
813
814   /* Check whether it claims to be free ... */
815   assert(!inuse(p));
816
817   /* Unless a special marker, must have OK fields */
818   if ((long)sz >= (long)MINSIZE)
819   {
820     assert((sz & MALLOC_ALIGN_MASK) == 0);
821     assert(aligned_OK(chunk2mem(p)));
822     /* ... matching footer field */
823     assert(next->prev_size == sz);
824     /* ... and is fully consolidated */
825     assert(prev_inuse(p));
826     assert (next == top || inuse(next));
827
828     /* ... and has minimally sane links */
829     assert(p->fd->bk == p);
830     assert(p->bk->fd == p);
831   }
832   else /* markers are always of size SIZE_SZ */
833     assert(sz == SIZE_SZ);
834 }
835
836 #if __STD_C
837 static void do_check_inuse_chunk(mchunkptr p)
838 #else
839 static void do_check_inuse_chunk(p) mchunkptr p;
840 #endif
841 {
842   mchunkptr next = next_chunk(p);
843   do_check_chunk(p);
844
845   /* Check whether it claims to be in use ... */
846   assert(inuse(p));
847
848   /* ... and is surrounded by OK chunks.
849     Since more things can be checked with free chunks than inuse ones,
850     if an inuse chunk borders them and debug is on, it's worth doing them.
851   */
852   if (!prev_inuse(p))
853   {
854     mchunkptr prv = prev_chunk(p);
855     assert(next_chunk(prv) == p);
856     do_check_free_chunk(prv);
857   }
858   if (next == top)
859   {
860     assert(prev_inuse(next));
861     assert(chunksize(next) >= MINSIZE);
862   }
863   else if (!inuse(next))
864     do_check_free_chunk(next);
865
866 }
867
868 #if __STD_C
869 static void do_check_malloced_chunk(mchunkptr p, INTERNAL_SIZE_T s)
870 #else
871 static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s;
872 #endif
873 {
874   INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE;
875   long room = sz - s;
876
877   do_check_inuse_chunk(p);
878
879   /* Legal size ... */
880   assert((long)sz >= (long)MINSIZE);
881   assert((sz & MALLOC_ALIGN_MASK) == 0);
882   assert(room >= 0);
883   assert(room < (long)MINSIZE);
884
885   /* ... and alignment */
886   assert(aligned_OK(chunk2mem(p)));
887
888
889   /* ... and was allocated at front of an available chunk */
890   assert(prev_inuse(p));
891
892 }
893
894
895 #define check_free_chunk(P)  do_check_free_chunk(P)
896 #define check_inuse_chunk(P) do_check_inuse_chunk(P)
897 #define check_chunk(P) do_check_chunk(P)
898 #define check_malloced_chunk(P,N) do_check_malloced_chunk(P,N)
899 #else
900 #define check_free_chunk(P)
901 #define check_inuse_chunk(P)
902 #define check_chunk(P)
903 #define check_malloced_chunk(P,N)
904 #endif
905
906
907
908 /*
909   Macro-based internal utilities
910 */
911
912
913 /*
914   Linking chunks in bin lists.
915   Call these only with variables, not arbitrary expressions, as arguments.
916 */
917
918 /*
919   Place chunk p of size s in its bin, in size order,
920   putting it ahead of others of same size.
921 */
922
923
924 #define frontlink(P, S, IDX, BK, FD)                                          \
925 {                                                                             \
926   if (S < MAX_SMALLBIN_SIZE)                                                  \
927   {                                                                           \
928     IDX = smallbin_index(S);                                                  \
929     mark_binblock(IDX);                                                       \
930     BK = bin_at(IDX);                                                         \
931     FD = BK->fd;                                                              \
932     P->bk = BK;                                                               \
933     P->fd = FD;                                                               \
934     FD->bk = BK->fd = P;                                                      \
935   }                                                                           \
936   else                                                                        \
937   {                                                                           \
938     IDX = bin_index(S);                                                       \
939     BK = bin_at(IDX);                                                         \
940     FD = BK->fd;                                                              \
941     if (FD == BK) mark_binblock(IDX);                                         \
942     else                                                                      \
943     {                                                                         \
944       while (FD != BK && S < chunksize(FD)) FD = FD->fd;                      \
945       BK = FD->bk;                                                            \
946     }                                                                         \
947     P->bk = BK;                                                               \
948     P->fd = FD;                                                               \
949     FD->bk = BK->fd = P;                                                      \
950   }                                                                           \
951 }
952
953
954 /* take a chunk off a list */
955
956 #define unlink(P, BK, FD)                                                     \
957 {                                                                             \
958   BK = P->bk;                                                                 \
959   FD = P->fd;                                                                 \
960   FD->bk = BK;                                                                \
961   BK->fd = FD;                                                                \
962 }                                                                             \
963
964 /* Place p as the last remainder */
965
966 #define link_last_remainder(P)                                                \
967 {                                                                             \
968   last_remainder->fd = last_remainder->bk =  P;                               \
969   P->fd = P->bk = last_remainder;                                             \
970 }
971
972 /* Clear the last_remainder bin */
973
974 #define clear_last_remainder \
975   (last_remainder->fd = last_remainder->bk = last_remainder)
976
977
978
979
980
981 /* Routines dealing with mmap(). */
982
983 #if HAVE_MMAP
984
985 #if __STD_C
986 static mchunkptr mmap_chunk(size_t size)
987 #else
988 static mchunkptr mmap_chunk(size) size_t size;
989 #endif
990 {
991   size_t page_mask = malloc_getpagesize - 1;
992   mchunkptr p;
993
994 #ifndef MAP_ANONYMOUS
995   static int fd = -1;
996 #endif
997
998   if(n_mmaps >= n_mmaps_max) return 0; /* too many regions */
999
1000   /* For mmapped chunks, the overhead is one SIZE_SZ unit larger, because
1001    * there is no following chunk whose prev_size field could be used.
1002    */
1003   size = (size + SIZE_SZ + page_mask) & ~page_mask;
1004
1005 #ifdef MAP_ANONYMOUS
1006   p = (mchunkptr)mmap(0, size, PROT_READ|PROT_WRITE,
1007                       MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
1008 #else /* !MAP_ANONYMOUS */
1009   if (fd < 0)
1010   {
1011     fd = open("/dev/zero", O_RDWR);
1012     if(fd < 0) return 0;
1013   }
1014   p = (mchunkptr)mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
1015 #endif
1016
1017   if(p == (mchunkptr)-1) return 0;
1018
1019   n_mmaps++;
1020   if (n_mmaps > max_n_mmaps) max_n_mmaps = n_mmaps;
1021
1022   /* We demand that eight bytes into a page must be 8-byte aligned. */
1023   assert(aligned_OK(chunk2mem(p)));
1024
1025   /* The offset to the start of the mmapped region is stored
1026    * in the prev_size field of the chunk; normally it is zero,
1027    * but that can be changed in memalign().
1028    */
1029   p->prev_size = 0;
1030   set_head(p, size|IS_MMAPPED);
1031
1032   mmapped_mem += size;
1033   if ((unsigned long)mmapped_mem > (unsigned long)max_mmapped_mem)
1034     max_mmapped_mem = mmapped_mem;
1035   if ((unsigned long)(mmapped_mem + sbrked_mem) > (unsigned long)max_total_mem)
1036     max_total_mem = mmapped_mem + sbrked_mem;
1037   return p;
1038 }
1039
1040 #if __STD_C
1041 static void munmap_chunk(mchunkptr p)
1042 #else
1043 static void munmap_chunk(p) mchunkptr p;
1044 #endif
1045 {
1046   INTERNAL_SIZE_T size = chunksize(p);
1047   int ret;
1048
1049   assert (chunk_is_mmapped(p));
1050   assert(! ((char*)p >= sbrk_base && (char*)p < sbrk_base + sbrked_mem));
1051   assert((n_mmaps > 0));
1052   assert(((p->prev_size + size) & (malloc_getpagesize-1)) == 0);
1053
1054   n_mmaps--;
1055   mmapped_mem -= (size + p->prev_size);
1056
1057   ret = munmap((char *)p - p->prev_size, size + p->prev_size);
1058
1059   /* munmap returns non-zero on failure */
1060   assert(ret == 0);
1061 }
1062
1063 #if HAVE_MREMAP
1064
1065 #if __STD_C
1066 static mchunkptr mremap_chunk(mchunkptr p, size_t new_size)
1067 #else
1068 static mchunkptr mremap_chunk(p, new_size) mchunkptr p; size_t new_size;
1069 #endif
1070 {
1071   size_t page_mask = malloc_getpagesize - 1;
1072   INTERNAL_SIZE_T offset = p->prev_size;
1073   INTERNAL_SIZE_T size = chunksize(p);
1074   char *cp;
1075
1076   assert (chunk_is_mmapped(p));
1077   assert(! ((char*)p >= sbrk_base && (char*)p < sbrk_base + sbrked_mem));
1078   assert((n_mmaps > 0));
1079   assert(((size + offset) & (malloc_getpagesize-1)) == 0);
1080
1081   /* Note the extra SIZE_SZ overhead as in mmap_chunk(). */
1082   new_size = (new_size + offset + SIZE_SZ + page_mask) & ~page_mask;
1083
1084   cp = (char *)mremap((char *)p - offset, size + offset, new_size, 1);
1085
1086   if (cp == (char *)-1) return 0;
1087
1088   p = (mchunkptr)(cp + offset);
1089
1090   assert(aligned_OK(chunk2mem(p)));
1091
1092   assert((p->prev_size == offset));
1093   set_head(p, (new_size - offset)|IS_MMAPPED);
1094
1095   mmapped_mem -= size + offset;
1096   mmapped_mem += new_size;
1097   if ((unsigned long)mmapped_mem > (unsigned long)max_mmapped_mem)
1098     max_mmapped_mem = mmapped_mem;
1099   if ((unsigned long)(mmapped_mem + sbrked_mem) > (unsigned long)max_total_mem)
1100     max_total_mem = mmapped_mem + sbrked_mem;
1101   return p;
1102 }
1103
1104 #endif /* HAVE_MREMAP */
1105
1106 #endif /* HAVE_MMAP */
1107
1108 /*
1109   Extend the top-most chunk by obtaining memory from system.
1110   Main interface to sbrk (but see also malloc_trim).
1111 */
1112
1113 #if __STD_C
1114 static void malloc_extend_top(INTERNAL_SIZE_T nb)
1115 #else
1116 static void malloc_extend_top(nb) INTERNAL_SIZE_T nb;
1117 #endif
1118 {
1119   char*     brk;                  /* return value from sbrk */
1120   INTERNAL_SIZE_T front_misalign; /* unusable bytes at front of sbrked space */
1121   INTERNAL_SIZE_T correction;     /* bytes for 2nd sbrk call */
1122   char*     new_brk;              /* return of 2nd sbrk call */
1123   INTERNAL_SIZE_T top_size;       /* new size of top chunk */
1124
1125   mchunkptr old_top     = top;  /* Record state of old top */
1126   INTERNAL_SIZE_T old_top_size = chunksize(old_top);
1127   char*     old_end      = (char*)(chunk_at_offset(old_top, old_top_size));
1128
1129   /* Pad request with top_pad plus minimal overhead */
1130
1131   INTERNAL_SIZE_T    sbrk_size     = nb + top_pad + MINSIZE;
1132   unsigned long pagesz    = malloc_getpagesize;
1133
1134   /* If not the first time through, round to preserve page boundary */
1135   /* Otherwise, we need to correct to a page size below anyway. */
1136   /* (We also correct below if an intervening foreign sbrk call.) */
1137
1138   if (sbrk_base != (char*)(-1))
1139     sbrk_size = (sbrk_size + (pagesz - 1)) & ~(pagesz - 1);
1140
1141   brk = (char*)(MORECORE (sbrk_size));
1142
1143   /* Fail if sbrk failed or if a foreign sbrk call killed our space */
1144   if (brk == (char*)(MORECORE_FAILURE) ||
1145       (brk < old_end && old_top != initial_top))
1146     return;
1147
1148   sbrked_mem += sbrk_size;
1149
1150   if (brk == old_end) /* can just add bytes to current top */
1151   {
1152     top_size = sbrk_size + old_top_size;
1153     set_head(top, top_size | PREV_INUSE);
1154   }
1155   else
1156   {
1157     if (sbrk_base == (char*)(-1))  /* First time through. Record base */
1158       sbrk_base = brk;
1159     else  /* Someone else called sbrk().  Count those bytes as sbrked_mem. */
1160       sbrked_mem += brk - (char*)old_end;
1161
1162     /* Guarantee alignment of first new chunk made from this space */
1163     front_misalign = (unsigned long)chunk2mem(brk) & MALLOC_ALIGN_MASK;
1164     if (front_misalign > 0)
1165     {
1166       correction = (MALLOC_ALIGNMENT) - front_misalign;
1167       brk += correction;
1168     }
1169     else
1170       correction = 0;
1171
1172     /* Guarantee the next brk will be at a page boundary */
1173
1174     correction += ((((unsigned long)(brk + sbrk_size))+(pagesz-1)) &
1175                    ~(pagesz - 1)) - ((unsigned long)(brk + sbrk_size));
1176
1177     /* Allocate correction */
1178     new_brk = (char*)(MORECORE (correction));
1179     if (new_brk == (char*)(MORECORE_FAILURE)) return;
1180
1181     sbrked_mem += correction;
1182
1183     top = (mchunkptr)brk;
1184     top_size = new_brk - brk + correction;
1185     set_head(top, top_size | PREV_INUSE);
1186
1187     if (old_top != initial_top)
1188     {
1189
1190       /* There must have been an intervening foreign sbrk call. */
1191       /* A double fencepost is necessary to prevent consolidation */
1192
1193       /* If not enough space to do this, then user did something very wrong */
1194       if (old_top_size < MINSIZE)
1195       {
1196         set_head(top, PREV_INUSE); /* will force null return from malloc */
1197         return;
1198       }
1199
1200       /* Also keep size a multiple of MALLOC_ALIGNMENT */
1201       old_top_size = (old_top_size - 3*SIZE_SZ) & ~MALLOC_ALIGN_MASK;
1202       set_head_size(old_top, old_top_size);
1203       chunk_at_offset(old_top, old_top_size          )->size =
1204         SIZE_SZ|PREV_INUSE;
1205       chunk_at_offset(old_top, old_top_size + SIZE_SZ)->size =
1206         SIZE_SZ|PREV_INUSE;
1207       /* If possible, release the rest. */
1208       if (old_top_size >= MINSIZE)
1209         fREe(chunk2mem(old_top));
1210     }
1211   }
1212
1213   if ((unsigned long)sbrked_mem > (unsigned long)max_sbrked_mem)
1214     max_sbrked_mem = sbrked_mem;
1215   if ((unsigned long)(mmapped_mem + sbrked_mem) > (unsigned long)max_total_mem)
1216     max_total_mem = mmapped_mem + sbrked_mem;
1217
1218   /* We always land on a page boundary */
1219   assert(((unsigned long)((char*)top + top_size) & (pagesz - 1)) == 0);
1220 }
1221
1222
1223
1224
1225 /* Main public routines */
1226
1227
1228 /*
1229   Malloc Algorthim:
1230
1231     The requested size is first converted into a usable form, `nb'.
1232     This currently means to add 4 bytes overhead plus possibly more to
1233     obtain 8-byte alignment and/or to obtain a size of at least
1234     MINSIZE (currently 16 bytes), the smallest allocatable size.
1235     (All fits are considered `exact' if they are within MINSIZE bytes.)
1236
1237     From there, the first successful of the following steps is taken:
1238
1239       1. The bin corresponding to the request size is scanned, and if
1240          a chunk of exactly the right size is found, it is taken.
1241
1242       2. The most recently remaindered chunk is used if it is big
1243          enough.  This is a form of (roving) first fit, used only in
1244          the absence of exact fits. Runs of consecutive requests use
1245          the remainder of the chunk used for the previous such request
1246          whenever possible. This limited use of a first-fit style
1247          allocation strategy tends to give contiguous chunks
1248          coextensive lifetimes, which improves locality and can reduce
1249          fragmentation in the long run.
1250
1251       3. Other bins are scanned in increasing size order, using a
1252          chunk big enough to fulfill the request, and splitting off
1253          any remainder.  This search is strictly by best-fit; i.e.,
1254          the smallest (with ties going to approximately the least
1255          recently used) chunk that fits is selected.
1256
1257       4. If large enough, the chunk bordering the end of memory
1258          (`top') is split off. (This use of `top' is in accord with
1259          the best-fit search rule.  In effect, `top' is treated as
1260          larger (and thus less well fitting) than any other available
1261          chunk since it can be extended to be as large as necessary
1262          (up to system limitations).
1263
1264       5. If the request size meets the mmap threshold and the
1265          system supports mmap, and there are few enough currently
1266          allocated mmapped regions, and a call to mmap succeeds,
1267          the request is allocated via direct memory mapping.
1268
1269       6. Otherwise, the top of memory is extended by
1270          obtaining more space from the system (normally using sbrk,
1271          but definable to anything else via the MORECORE macro).
1272          Memory is gathered from the system (in system page-sized
1273          units) in a way that allows chunks obtained across different
1274          sbrk calls to be consolidated, but does not require
1275          contiguous memory. Thus, it should be safe to intersperse
1276          mallocs with other sbrk calls.
1277
1278
1279       All allocations are made from the the `lowest' part of any found
1280       chunk. (The implementation invariant is that prev_inuse is
1281       always true of any allocated chunk; i.e., that each allocated
1282       chunk borders either a previously allocated and still in-use chunk,
1283       or the base of its memory arena.)
1284
1285 */
1286
1287 #if __STD_C
1288 Void_t* mALLOc(size_t bytes)
1289 #else
1290 Void_t* mALLOc(bytes) size_t bytes;
1291 #endif
1292 {
1293   mchunkptr victim;                  /* inspected/selected chunk */
1294   INTERNAL_SIZE_T victim_size;       /* its size */
1295   int       idx;                     /* index for bin traversal */
1296   mbinptr   bin;                     /* associated bin */
1297   mchunkptr remainder;               /* remainder from a split */
1298   long      remainder_size;          /* its size */
1299   int       remainder_index;         /* its bin index */
1300   unsigned long block;               /* block traverser bit */
1301   int       startidx;                /* first bin of a traversed block */
1302   mchunkptr fwd;                     /* misc temp for linking */
1303   mchunkptr bck;                     /* misc temp for linking */
1304   mbinptr q;                         /* misc temp */
1305
1306   INTERNAL_SIZE_T nb;
1307
1308 #if CONFIG_VAL(SYS_MALLOC_F_LEN)
1309         if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT))
1310                 return malloc_simple(bytes);
1311 #endif
1312
1313   if (CONFIG_IS_ENABLED(UNIT_TEST) && malloc_testing) {
1314     if (--malloc_max_allocs < 0)
1315       return NULL;
1316   }
1317
1318   /* check if mem_malloc_init() was run */
1319   if ((mem_malloc_start == 0) && (mem_malloc_end == 0)) {
1320     /* not initialized yet */
1321     return NULL;
1322   }
1323
1324   if ((long)bytes < 0) return NULL;
1325
1326   nb = request2size(bytes);  /* padded request size; */
1327
1328   /* Check for exact match in a bin */
1329
1330   if (is_small_request(nb))  /* Faster version for small requests */
1331   {
1332     idx = smallbin_index(nb);
1333
1334     /* No traversal or size check necessary for small bins.  */
1335
1336     q = bin_at(idx);
1337     victim = last(q);
1338
1339     /* Also scan the next one, since it would have a remainder < MINSIZE */
1340     if (victim == q)
1341     {
1342       q = next_bin(q);
1343       victim = last(q);
1344     }
1345     if (victim != q)
1346     {
1347       victim_size = chunksize(victim);
1348       unlink(victim, bck, fwd);
1349       set_inuse_bit_at_offset(victim, victim_size);
1350       check_malloced_chunk(victim, nb);
1351       VALGRIND_MALLOCLIKE_BLOCK(chunk2mem(victim), bytes, SIZE_SZ, false);
1352       return chunk2mem(victim);
1353     }
1354
1355     idx += 2; /* Set for bin scan below. We've already scanned 2 bins. */
1356
1357   }
1358   else
1359   {
1360     idx = bin_index(nb);
1361     bin = bin_at(idx);
1362
1363     for (victim = last(bin); victim != bin; victim = victim->bk)
1364     {
1365       victim_size = chunksize(victim);
1366       remainder_size = victim_size - nb;
1367
1368       if (remainder_size >= (long)MINSIZE) /* too big */
1369       {
1370         --idx; /* adjust to rescan below after checking last remainder */
1371         break;
1372       }
1373
1374       else if (remainder_size >= 0) /* exact fit */
1375       {
1376         unlink(victim, bck, fwd);
1377         set_inuse_bit_at_offset(victim, victim_size);
1378         check_malloced_chunk(victim, nb);
1379         VALGRIND_MALLOCLIKE_BLOCK(chunk2mem(victim), bytes, SIZE_SZ, false);
1380         return chunk2mem(victim);
1381       }
1382     }
1383
1384     ++idx;
1385
1386   }
1387
1388   /* Try to use the last split-off remainder */
1389
1390   if ( (victim = last_remainder->fd) != last_remainder)
1391   {
1392     victim_size = chunksize(victim);
1393     remainder_size = victim_size - nb;
1394
1395     if (remainder_size >= (long)MINSIZE) /* re-split */
1396     {
1397       remainder = chunk_at_offset(victim, nb);
1398       set_head(victim, nb | PREV_INUSE);
1399       link_last_remainder(remainder);
1400       set_head(remainder, remainder_size | PREV_INUSE);
1401       set_foot(remainder, remainder_size);
1402       check_malloced_chunk(victim, nb);
1403       VALGRIND_MALLOCLIKE_BLOCK(chunk2mem(victim), bytes, SIZE_SZ, false);
1404       return chunk2mem(victim);
1405     }
1406
1407     clear_last_remainder;
1408
1409     if (remainder_size >= 0)  /* exhaust */
1410     {
1411       set_inuse_bit_at_offset(victim, victim_size);
1412       check_malloced_chunk(victim, nb);
1413       VALGRIND_MALLOCLIKE_BLOCK(chunk2mem(victim), bytes, SIZE_SZ, false);
1414       return chunk2mem(victim);
1415     }
1416
1417     /* Else place in bin */
1418
1419     frontlink(victim, victim_size, remainder_index, bck, fwd);
1420   }
1421
1422   /*
1423      If there are any possibly nonempty big-enough blocks,
1424      search for best fitting chunk by scanning bins in blockwidth units.
1425   */
1426
1427   if ( (block = idx2binblock(idx)) <= binblocks_r)
1428   {
1429
1430     /* Get to the first marked block */
1431
1432     if ( (block & binblocks_r) == 0)
1433     {
1434       /* force to an even block boundary */
1435       idx = (idx & ~(BINBLOCKWIDTH - 1)) + BINBLOCKWIDTH;
1436       block <<= 1;
1437       while ((block & binblocks_r) == 0)
1438       {
1439         idx += BINBLOCKWIDTH;
1440         block <<= 1;
1441       }
1442     }
1443
1444     /* For each possibly nonempty block ... */
1445     for (;;)
1446     {
1447       startidx = idx;          /* (track incomplete blocks) */
1448       q = bin = bin_at(idx);
1449
1450       /* For each bin in this block ... */
1451       do
1452       {
1453         /* Find and use first big enough chunk ... */
1454
1455         for (victim = last(bin); victim != bin; victim = victim->bk)
1456         {
1457           victim_size = chunksize(victim);
1458           remainder_size = victim_size - nb;
1459
1460           if (remainder_size >= (long)MINSIZE) /* split */
1461           {
1462             remainder = chunk_at_offset(victim, nb);
1463             set_head(victim, nb | PREV_INUSE);
1464             unlink(victim, bck, fwd);
1465             link_last_remainder(remainder);
1466             set_head(remainder, remainder_size | PREV_INUSE);
1467             set_foot(remainder, remainder_size);
1468             check_malloced_chunk(victim, nb);
1469             VALGRIND_MALLOCLIKE_BLOCK(chunk2mem(victim), bytes, SIZE_SZ, false);
1470             return chunk2mem(victim);
1471           }
1472
1473           else if (remainder_size >= 0)  /* take */
1474           {
1475             set_inuse_bit_at_offset(victim, victim_size);
1476             unlink(victim, bck, fwd);
1477             check_malloced_chunk(victim, nb);
1478             VALGRIND_MALLOCLIKE_BLOCK(chunk2mem(victim), bytes, SIZE_SZ, false);
1479             return chunk2mem(victim);
1480           }
1481
1482         }
1483
1484        bin = next_bin(bin);
1485
1486       } while ((++idx & (BINBLOCKWIDTH - 1)) != 0);
1487
1488       /* Clear out the block bit. */
1489
1490       do   /* Possibly backtrack to try to clear a partial block */
1491       {
1492         if ((startidx & (BINBLOCKWIDTH - 1)) == 0)
1493         {
1494           av_[1] = (mbinptr)(binblocks_r & ~block);
1495           break;
1496         }
1497         --startidx;
1498        q = prev_bin(q);
1499       } while (first(q) == q);
1500
1501       /* Get to the next possibly nonempty block */
1502
1503       if ( (block <<= 1) <= binblocks_r && (block != 0) )
1504       {
1505         while ((block & binblocks_r) == 0)
1506         {
1507           idx += BINBLOCKWIDTH;
1508           block <<= 1;
1509         }
1510       }
1511       else
1512         break;
1513     }
1514   }
1515
1516
1517   /* Try to use top chunk */
1518
1519   /* Require that there be a remainder, ensuring top always exists  */
1520   if ( (remainder_size = chunksize(top) - nb) < (long)MINSIZE)
1521   {
1522
1523 #if HAVE_MMAP
1524     /* If big and would otherwise need to extend, try to use mmap instead */
1525     if ((unsigned long)nb >= (unsigned long)mmap_threshold &&
1526         (victim = mmap_chunk(nb)))
1527       VALGRIND_MALLOCLIKE_BLOCK(chunk2mem(victim), bytes, SIZE_SZ, false);
1528       return chunk2mem(victim);
1529 #endif
1530
1531     /* Try to extend */
1532     malloc_extend_top(nb);
1533     if ( (remainder_size = chunksize(top) - nb) < (long)MINSIZE)
1534       return NULL; /* propagate failure */
1535   }
1536
1537   victim = top;
1538   set_head(victim, nb | PREV_INUSE);
1539   top = chunk_at_offset(victim, nb);
1540   set_head(top, remainder_size | PREV_INUSE);
1541   check_malloced_chunk(victim, nb);
1542   VALGRIND_MALLOCLIKE_BLOCK(chunk2mem(victim), bytes, SIZE_SZ, false);
1543   return chunk2mem(victim);
1544
1545 }
1546
1547
1548
1549
1550 /*
1551
1552   free() algorithm :
1553
1554     cases:
1555
1556        1. free(0) has no effect.
1557
1558        2. If the chunk was allocated via mmap, it is release via munmap().
1559
1560        3. If a returned chunk borders the current high end of memory,
1561           it is consolidated into the top, and if the total unused
1562           topmost memory exceeds the trim threshold, malloc_trim is
1563           called.
1564
1565        4. Other chunks are consolidated as they arrive, and
1566           placed in corresponding bins. (This includes the case of
1567           consolidating with the current `last_remainder').
1568
1569 */
1570
1571
1572 #if __STD_C
1573 void fREe(Void_t* mem)
1574 #else
1575 void fREe(mem) Void_t* mem;
1576 #endif
1577 {
1578   mchunkptr p;         /* chunk corresponding to mem */
1579   INTERNAL_SIZE_T hd;  /* its head field */
1580   INTERNAL_SIZE_T sz;  /* its size */
1581   int       idx;       /* its bin index */
1582   mchunkptr next;      /* next contiguous chunk */
1583   INTERNAL_SIZE_T nextsz; /* its size */
1584   INTERNAL_SIZE_T prevsz; /* size of previous contiguous chunk */
1585   mchunkptr bck;       /* misc temp for linking */
1586   mchunkptr fwd;       /* misc temp for linking */
1587   int       islr;      /* track whether merging with last_remainder */
1588
1589 #if CONFIG_VAL(SYS_MALLOC_F_LEN)
1590         /* free() is a no-op - all the memory will be freed on relocation */
1591         if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
1592                 VALGRIND_FREELIKE_BLOCK(mem, SIZE_SZ);
1593                 return;
1594         }
1595 #endif
1596
1597   if (mem == NULL)                              /* free(0) has no effect */
1598     return;
1599
1600   p = mem2chunk(mem);
1601   hd = p->size;
1602
1603 #if HAVE_MMAP
1604   if (hd & IS_MMAPPED)                       /* release mmapped memory. */
1605   {
1606     munmap_chunk(p);
1607     return;
1608   }
1609 #endif
1610
1611   check_inuse_chunk(p);
1612
1613   sz = hd & ~PREV_INUSE;
1614   next = chunk_at_offset(p, sz);
1615   nextsz = chunksize(next);
1616   VALGRIND_FREELIKE_BLOCK(mem, SIZE_SZ);
1617
1618   if (next == top)                            /* merge with top */
1619   {
1620     sz += nextsz;
1621
1622     if (!(hd & PREV_INUSE))                    /* consolidate backward */
1623     {
1624       prevsz = p->prev_size;
1625       p = chunk_at_offset(p, -((long) prevsz));
1626       sz += prevsz;
1627       unlink(p, bck, fwd);
1628     }
1629
1630     set_head(p, sz | PREV_INUSE);
1631     top = p;
1632     if ((unsigned long)(sz) >= (unsigned long)trim_threshold)
1633       malloc_trim(top_pad);
1634     return;
1635   }
1636
1637   set_head(next, nextsz);                    /* clear inuse bit */
1638
1639   islr = 0;
1640
1641   if (!(hd & PREV_INUSE))                    /* consolidate backward */
1642   {
1643     prevsz = p->prev_size;
1644     p = chunk_at_offset(p, -((long) prevsz));
1645     sz += prevsz;
1646
1647     if (p->fd == last_remainder)             /* keep as last_remainder */
1648       islr = 1;
1649     else
1650       unlink(p, bck, fwd);
1651   }
1652
1653   if (!(inuse_bit_at_offset(next, nextsz)))   /* consolidate forward */
1654   {
1655     sz += nextsz;
1656
1657     if (!islr && next->fd == last_remainder)  /* re-insert last_remainder */
1658     {
1659       islr = 1;
1660       link_last_remainder(p);
1661     }
1662     else
1663       unlink(next, bck, fwd);
1664   }
1665
1666
1667   set_head(p, sz | PREV_INUSE);
1668   set_foot(p, sz);
1669   if (!islr)
1670     frontlink(p, sz, idx, bck, fwd);
1671 }
1672
1673
1674
1675
1676
1677 /*
1678
1679   Realloc algorithm:
1680
1681     Chunks that were obtained via mmap cannot be extended or shrunk
1682     unless HAVE_MREMAP is defined, in which case mremap is used.
1683     Otherwise, if their reallocation is for additional space, they are
1684     copied.  If for less, they are just left alone.
1685
1686     Otherwise, if the reallocation is for additional space, and the
1687     chunk can be extended, it is, else a malloc-copy-free sequence is
1688     taken.  There are several different ways that a chunk could be
1689     extended. All are tried:
1690
1691        * Extending forward into following adjacent free chunk.
1692        * Shifting backwards, joining preceding adjacent space
1693        * Both shifting backwards and extending forward.
1694        * Extending into newly sbrked space
1695
1696     Unless the #define REALLOC_ZERO_BYTES_FREES is set, realloc with a
1697     size argument of zero (re)allocates a minimum-sized chunk.
1698
1699     If the reallocation is for less space, and the new request is for
1700     a `small' (<512 bytes) size, then the newly unused space is lopped
1701     off and freed.
1702
1703     The old unix realloc convention of allowing the last-free'd chunk
1704     to be used as an argument to realloc is no longer supported.
1705     I don't know of any programs still relying on this feature,
1706     and allowing it would also allow too many other incorrect
1707     usages of realloc to be sensible.
1708
1709
1710 */
1711
1712
1713 #if __STD_C
1714 Void_t* rEALLOc(Void_t* oldmem, size_t bytes)
1715 #else
1716 Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
1717 #endif
1718 {
1719   INTERNAL_SIZE_T    nb;      /* padded request size */
1720
1721   mchunkptr oldp;             /* chunk corresponding to oldmem */
1722   INTERNAL_SIZE_T    oldsize; /* its size */
1723
1724   mchunkptr newp;             /* chunk to return */
1725   INTERNAL_SIZE_T    newsize; /* its size */
1726   Void_t*   newmem;           /* corresponding user mem */
1727
1728   mchunkptr next;             /* next contiguous chunk after oldp */
1729   INTERNAL_SIZE_T  nextsize;  /* its size */
1730
1731   mchunkptr prev;             /* previous contiguous chunk before oldp */
1732   INTERNAL_SIZE_T  prevsize;  /* its size */
1733
1734   mchunkptr remainder;        /* holds split off extra space from newp */
1735   INTERNAL_SIZE_T  remainder_size;   /* its size */
1736
1737   mchunkptr bck;              /* misc temp for linking */
1738   mchunkptr fwd;              /* misc temp for linking */
1739
1740 #ifdef REALLOC_ZERO_BYTES_FREES
1741   if (!bytes) {
1742         fREe(oldmem);
1743         return NULL;
1744   }
1745 #endif
1746
1747   if ((long)bytes < 0) return NULL;
1748
1749   /* realloc of null is supposed to be same as malloc */
1750   if (oldmem == NULL) return mALLOc(bytes);
1751
1752 #if CONFIG_VAL(SYS_MALLOC_F_LEN)
1753         if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
1754                 /* This is harder to support and should not be needed */
1755                 panic("pre-reloc realloc() is not supported");
1756         }
1757 #endif
1758
1759   newp    = oldp    = mem2chunk(oldmem);
1760   newsize = oldsize = chunksize(oldp);
1761
1762
1763   nb = request2size(bytes);
1764
1765 #if HAVE_MMAP
1766   if (chunk_is_mmapped(oldp))
1767   {
1768 #if HAVE_MREMAP
1769     newp = mremap_chunk(oldp, nb);
1770     if(newp) return chunk2mem(newp);
1771 #endif
1772     /* Note the extra SIZE_SZ overhead. */
1773     if(oldsize - SIZE_SZ >= nb) return oldmem; /* do nothing */
1774     /* Must alloc, copy, free. */
1775     newmem = mALLOc(bytes);
1776     if (!newmem)
1777         return NULL; /* propagate failure */
1778     MALLOC_COPY(newmem, oldmem, oldsize - 2*SIZE_SZ);
1779     munmap_chunk(oldp);
1780     return newmem;
1781   }
1782 #endif
1783
1784   check_inuse_chunk(oldp);
1785
1786   if ((long)(oldsize) < (long)(nb))
1787   {
1788
1789     /* Try expanding forward */
1790
1791     next = chunk_at_offset(oldp, oldsize);
1792     if (next == top || !inuse(next))
1793     {
1794       nextsize = chunksize(next);
1795
1796       /* Forward into top only if a remainder */
1797       if (next == top)
1798       {
1799         if ((long)(nextsize + newsize) >= (long)(nb + MINSIZE))
1800         {
1801           newsize += nextsize;
1802           top = chunk_at_offset(oldp, nb);
1803           set_head(top, (newsize - nb) | PREV_INUSE);
1804           set_head_size(oldp, nb);
1805           VALGRIND_RESIZEINPLACE_BLOCK(chunk2mem(oldp), 0, bytes, SIZE_SZ);
1806           VALGRIND_MAKE_MEM_DEFINED(chunk2mem(oldp), bytes);
1807           return chunk2mem(oldp);
1808         }
1809       }
1810
1811       /* Forward into next chunk */
1812       else if (((long)(nextsize + newsize) >= (long)(nb)))
1813       {
1814         unlink(next, bck, fwd);
1815         newsize  += nextsize;
1816         VALGRIND_RESIZEINPLACE_BLOCK(chunk2mem(oldp), 0, bytes, SIZE_SZ);
1817         VALGRIND_MAKE_MEM_DEFINED(chunk2mem(oldp), bytes);
1818         goto split;
1819       }
1820     }
1821     else
1822     {
1823       next = NULL;
1824       nextsize = 0;
1825     }
1826
1827     /* Try shifting backwards. */
1828
1829     if (!prev_inuse(oldp))
1830     {
1831       prev = prev_chunk(oldp);
1832       prevsize = chunksize(prev);
1833
1834       /* try forward + backward first to save a later consolidation */
1835
1836       if (next != NULL)
1837       {
1838         /* into top */
1839         if (next == top)
1840         {
1841           if ((long)(nextsize + prevsize + newsize) >= (long)(nb + MINSIZE))
1842           {
1843             unlink(prev, bck, fwd);
1844             newp = prev;
1845             newsize += prevsize + nextsize;
1846             newmem = chunk2mem(newp);
1847             VALGRIND_MALLOCLIKE_BLOCK(newmem, bytes, SIZE_SZ, false);
1848             MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
1849             top = chunk_at_offset(newp, nb);
1850             set_head(top, (newsize - nb) | PREV_INUSE);
1851             set_head_size(newp, nb);
1852             VALGRIND_FREELIKE_BLOCK(oldmem, SIZE_SZ);
1853             return newmem;
1854           }
1855         }
1856
1857         /* into next chunk */
1858         else if (((long)(nextsize + prevsize + newsize) >= (long)(nb)))
1859         {
1860           unlink(next, bck, fwd);
1861           unlink(prev, bck, fwd);
1862           newp = prev;
1863           newsize += nextsize + prevsize;
1864           newmem = chunk2mem(newp);
1865           VALGRIND_MALLOCLIKE_BLOCK(newmem, bytes, SIZE_SZ, false);
1866           MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
1867           goto split;
1868         }
1869       }
1870
1871       /* backward only */
1872       if (prev != NULL && (long)(prevsize + newsize) >= (long)nb)
1873       {
1874         unlink(prev, bck, fwd);
1875         newp = prev;
1876         newsize += prevsize;
1877         newmem = chunk2mem(newp);
1878         VALGRIND_MALLOCLIKE_BLOCK(newmem, bytes, SIZE_SZ, false);
1879         MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
1880         goto split;
1881       }
1882     }
1883
1884     /* Must allocate */
1885
1886     newmem = mALLOc (bytes);
1887
1888     if (newmem == NULL)  /* propagate failure */
1889       return NULL;
1890
1891     /* Avoid copy if newp is next chunk after oldp. */
1892     /* (This can only happen when new chunk is sbrk'ed.) */
1893
1894     if ( (newp = mem2chunk(newmem)) == next_chunk(oldp))
1895     {
1896       newsize += chunksize(newp);
1897       newp = oldp;
1898       goto split;
1899     }
1900
1901     /* Otherwise copy, free, and exit */
1902     MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
1903     fREe(oldmem);
1904     return newmem;
1905   } else {
1906     VALGRIND_RESIZEINPLACE_BLOCK(oldmem, 0, bytes, SIZE_SZ);
1907     VALGRIND_MAKE_MEM_DEFINED(oldmem, bytes);
1908   }
1909
1910
1911  split:  /* split off extra room in old or expanded chunk */
1912
1913   if (newsize - nb >= MINSIZE) /* split off remainder */
1914   {
1915     remainder = chunk_at_offset(newp, nb);
1916     remainder_size = newsize - nb;
1917     set_head_size(newp, nb);
1918     set_head(remainder, remainder_size | PREV_INUSE);
1919     set_inuse_bit_at_offset(remainder, remainder_size);
1920     VALGRIND_MALLOCLIKE_BLOCK(chunk2mem(remainder), remainder_size, SIZE_SZ,
1921                               false);
1922     fREe(chunk2mem(remainder)); /* let free() deal with it */
1923   }
1924   else
1925   {
1926     set_head_size(newp, newsize);
1927     set_inuse_bit_at_offset(newp, newsize);
1928   }
1929
1930   check_inuse_chunk(newp);
1931   return chunk2mem(newp);
1932 }
1933
1934
1935
1936
1937 /*
1938
1939   memalign algorithm:
1940
1941     memalign requests more than enough space from malloc, finds a spot
1942     within that chunk that meets the alignment request, and then
1943     possibly frees the leading and trailing space.
1944
1945     The alignment argument must be a power of two. This property is not
1946     checked by memalign, so misuse may result in random runtime errors.
1947
1948     8-byte alignment is guaranteed by normal malloc calls, so don't
1949     bother calling memalign with an argument of 8 or less.
1950
1951     Overreliance on memalign is a sure way to fragment space.
1952
1953 */
1954
1955
1956 #if __STD_C
1957 Void_t* mEMALIGn(size_t alignment, size_t bytes)
1958 #else
1959 Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
1960 #endif
1961 {
1962   INTERNAL_SIZE_T    nb;      /* padded  request size */
1963   char*     m;                /* memory returned by malloc call */
1964   mchunkptr p;                /* corresponding chunk */
1965   char*     brk;              /* alignment point within p */
1966   mchunkptr newp;             /* chunk to return */
1967   INTERNAL_SIZE_T  newsize;   /* its size */
1968   INTERNAL_SIZE_T  leadsize;  /* leading space befor alignment point */
1969   mchunkptr remainder;        /* spare room at end to split off */
1970   long      remainder_size;   /* its size */
1971
1972   if ((long)bytes < 0) return NULL;
1973
1974 #if CONFIG_VAL(SYS_MALLOC_F_LEN)
1975         if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
1976                 return memalign_simple(alignment, bytes);
1977         }
1978 #endif
1979
1980   /* If need less alignment than we give anyway, just relay to malloc */
1981
1982   if (alignment <= MALLOC_ALIGNMENT) return mALLOc(bytes);
1983
1984   /* Otherwise, ensure that it is at least a minimum chunk size */
1985
1986   if (alignment <  MINSIZE) alignment = MINSIZE;
1987
1988   /* Call malloc with worst case padding to hit alignment. */
1989
1990   nb = request2size(bytes);
1991   m  = (char*)(mALLOc(nb + alignment + MINSIZE));
1992
1993   /*
1994   * The attempt to over-allocate (with a size large enough to guarantee the
1995   * ability to find an aligned region within allocated memory) failed.
1996   *
1997   * Try again, this time only allocating exactly the size the user wants. If
1998   * the allocation now succeeds and just happens to be aligned, we can still
1999   * fulfill the user's request.
2000   */
2001   if (m == NULL) {
2002     size_t extra, extra2;
2003     /*
2004      * Use bytes not nb, since mALLOc internally calls request2size too, and
2005      * each call increases the size to allocate, to account for the header.
2006      */
2007     m  = (char*)(mALLOc(bytes));
2008     /* Aligned -> return it */
2009     if ((((unsigned long)(m)) % alignment) == 0)
2010       return m;
2011     /*
2012      * Otherwise, try again, requesting enough extra space to be able to
2013      * acquire alignment.
2014      */
2015     fREe(m);
2016     /* Add in extra bytes to match misalignment of unexpanded allocation */
2017     extra = alignment - (((unsigned long)(m)) % alignment);
2018     m  = (char*)(mALLOc(bytes + extra));
2019     /*
2020      * m might not be the same as before. Validate that the previous value of
2021      * extra still works for the current value of m.
2022      * If (!m), extra2=alignment so 
2023      */
2024     if (m) {
2025       extra2 = alignment - (((unsigned long)(m)) % alignment);
2026       if (extra2 > extra) {
2027         fREe(m);
2028         m = NULL;
2029       }
2030     }
2031     /* Fall through to original NULL check and chunk splitting logic */
2032   }
2033
2034   if (m == NULL) return NULL; /* propagate failure */
2035
2036   p = mem2chunk(m);
2037
2038   if ((((unsigned long)(m)) % alignment) == 0) /* aligned */
2039   {
2040 #if HAVE_MMAP
2041     if(chunk_is_mmapped(p))
2042       return chunk2mem(p); /* nothing more to do */
2043 #endif
2044   }
2045   else /* misaligned */
2046   {
2047     /*
2048       Find an aligned spot inside chunk.
2049       Since we need to give back leading space in a chunk of at
2050       least MINSIZE, if the first calculation places us at
2051       a spot with less than MINSIZE leader, we can move to the
2052       next aligned spot -- we've allocated enough total room so that
2053       this is always possible.
2054     */
2055
2056     brk = (char*)mem2chunk(((unsigned long)(m + alignment - 1)) & -((signed) alignment));
2057     if ((long)(brk - (char*)(p)) < MINSIZE) brk = brk + alignment;
2058
2059     newp = (mchunkptr)brk;
2060     leadsize = brk - (char*)(p);
2061     newsize = chunksize(p) - leadsize;
2062
2063 #if HAVE_MMAP
2064     if(chunk_is_mmapped(p))
2065     {
2066       newp->prev_size = p->prev_size + leadsize;
2067       set_head(newp, newsize|IS_MMAPPED);
2068       return chunk2mem(newp);
2069     }
2070 #endif
2071
2072     /* give back leader, use the rest */
2073
2074     set_head(newp, newsize | PREV_INUSE);
2075     set_inuse_bit_at_offset(newp, newsize);
2076     set_head_size(p, leadsize);
2077     fREe(chunk2mem(p));
2078     p = newp;
2079     VALGRIND_MALLOCLIKE_BLOCK(chunk2mem(p), bytes, SIZE_SZ, false);
2080
2081     assert (newsize >= nb && (((unsigned long)(chunk2mem(p))) % alignment) == 0);
2082   }
2083
2084   /* Also give back spare room at the end */
2085
2086   remainder_size = chunksize(p) - nb;
2087
2088   if (remainder_size >= (long)MINSIZE)
2089   {
2090     remainder = chunk_at_offset(p, nb);
2091     set_head(remainder, remainder_size | PREV_INUSE);
2092     set_head_size(p, nb);
2093     VALGRIND_MALLOCLIKE_BLOCK(chunk2mem(remainder), remainder_size, SIZE_SZ,
2094                               false);
2095     fREe(chunk2mem(remainder));
2096   }
2097
2098   check_inuse_chunk(p);
2099   return chunk2mem(p);
2100
2101 }
2102
2103
2104
2105
2106 /*
2107     valloc just invokes memalign with alignment argument equal
2108     to the page size of the system (or as near to this as can
2109     be figured out from all the includes/defines above.)
2110 */
2111
2112 #if __STD_C
2113 Void_t* vALLOc(size_t bytes)
2114 #else
2115 Void_t* vALLOc(bytes) size_t bytes;
2116 #endif
2117 {
2118   return mEMALIGn (malloc_getpagesize, bytes);
2119 }
2120
2121 /*
2122   pvalloc just invokes valloc for the nearest pagesize
2123   that will accommodate request
2124 */
2125
2126
2127 #if __STD_C
2128 Void_t* pvALLOc(size_t bytes)
2129 #else
2130 Void_t* pvALLOc(bytes) size_t bytes;
2131 #endif
2132 {
2133   size_t pagesize = malloc_getpagesize;
2134   return mEMALIGn (pagesize, (bytes + pagesize - 1) & ~(pagesize - 1));
2135 }
2136
2137 /*
2138
2139   calloc calls malloc, then zeroes out the allocated chunk.
2140
2141 */
2142
2143 #if __STD_C
2144 Void_t* cALLOc(size_t n, size_t elem_size)
2145 #else
2146 Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
2147 #endif
2148 {
2149   mchunkptr p;
2150   INTERNAL_SIZE_T csz;
2151
2152   INTERNAL_SIZE_T sz = n * elem_size;
2153
2154
2155   /* check if expand_top called, in which case don't need to clear */
2156 #if CONFIG_IS_ENABLED(SYS_MALLOC_CLEAR_ON_INIT)
2157 #if MORECORE_CLEARS
2158   mchunkptr oldtop = top;
2159   INTERNAL_SIZE_T oldtopsize = chunksize(top);
2160 #endif
2161 #endif
2162   Void_t* mem = mALLOc (sz);
2163
2164   if ((long)n < 0) return NULL;
2165
2166   if (mem == NULL)
2167     return NULL;
2168   else
2169   {
2170 #if CONFIG_VAL(SYS_MALLOC_F_LEN)
2171         if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
2172                 memset(mem, 0, sz);
2173                 return mem;
2174         }
2175 #endif
2176     p = mem2chunk(mem);
2177
2178     /* Two optional cases in which clearing not necessary */
2179
2180
2181 #if HAVE_MMAP
2182     if (chunk_is_mmapped(p)) return mem;
2183 #endif
2184
2185     csz = chunksize(p);
2186
2187 #if CONFIG_IS_ENABLED(SYS_MALLOC_CLEAR_ON_INIT)
2188 #if MORECORE_CLEARS
2189     if (p == oldtop && csz > oldtopsize)
2190     {
2191       /* clear only the bytes from non-freshly-sbrked memory */
2192       csz = oldtopsize;
2193     }
2194 #endif
2195 #endif
2196
2197     MALLOC_ZERO(mem, csz - SIZE_SZ);
2198     VALGRIND_MAKE_MEM_DEFINED(mem, sz);
2199     return mem;
2200   }
2201 }
2202
2203 /*
2204
2205   cfree just calls free. It is needed/defined on some systems
2206   that pair it with calloc, presumably for odd historical reasons.
2207
2208 */
2209
2210 #if !defined(INTERNAL_LINUX_C_LIB) || !defined(__ELF__)
2211 #if __STD_C
2212 void cfree(Void_t *mem)
2213 #else
2214 void cfree(mem) Void_t *mem;
2215 #endif
2216 {
2217   fREe(mem);
2218 }
2219 #endif
2220
2221
2222
2223 /*
2224
2225     Malloc_trim gives memory back to the system (via negative
2226     arguments to sbrk) if there is unused memory at the `high' end of
2227     the malloc pool. You can call this after freeing large blocks of
2228     memory to potentially reduce the system-level memory requirements
2229     of a program. However, it cannot guarantee to reduce memory. Under
2230     some allocation patterns, some large free blocks of memory will be
2231     locked between two used chunks, so they cannot be given back to
2232     the system.
2233
2234     The `pad' argument to malloc_trim represents the amount of free
2235     trailing space to leave untrimmed. If this argument is zero,
2236     only the minimum amount of memory to maintain internal data
2237     structures will be left (one page or less). Non-zero arguments
2238     can be supplied to maintain enough trailing space to service
2239     future expected allocations without having to re-obtain memory
2240     from the system.
2241
2242     Malloc_trim returns 1 if it actually released any memory, else 0.
2243
2244 */
2245
2246 #if __STD_C
2247 int malloc_trim(size_t pad)
2248 #else
2249 int malloc_trim(pad) size_t pad;
2250 #endif
2251 {
2252   long  top_size;        /* Amount of top-most memory */
2253   long  extra;           /* Amount to release */
2254   char* current_brk;     /* address returned by pre-check sbrk call */
2255   char* new_brk;         /* address returned by negative sbrk call */
2256
2257   unsigned long pagesz = malloc_getpagesize;
2258
2259   top_size = chunksize(top);
2260   extra = ((top_size - pad - MINSIZE + (pagesz-1)) / pagesz - 1) * pagesz;
2261
2262   if (extra < (long)pagesz)  /* Not enough memory to release */
2263     return 0;
2264
2265   else
2266   {
2267     /* Test to make sure no one else called sbrk */
2268     current_brk = (char*)(MORECORE (0));
2269     if (current_brk != (char*)(top) + top_size)
2270       return 0;     /* Apparently we don't own memory; must fail */
2271
2272     else
2273     {
2274       new_brk = (char*)(MORECORE (-extra));
2275
2276       if (new_brk == (char*)(MORECORE_FAILURE)) /* sbrk failed? */
2277       {
2278         /* Try to figure out what we have */
2279         current_brk = (char*)(MORECORE (0));
2280         top_size = current_brk - (char*)top;
2281         if (top_size >= (long)MINSIZE) /* if not, we are very very dead! */
2282         {
2283           sbrked_mem = current_brk - sbrk_base;
2284           set_head(top, top_size | PREV_INUSE);
2285         }
2286         check_chunk(top);
2287         return 0;
2288       }
2289
2290       else
2291       {
2292         /* Success. Adjust top accordingly. */
2293         set_head(top, (top_size - extra) | PREV_INUSE);
2294         sbrked_mem -= extra;
2295         check_chunk(top);
2296         return 1;
2297       }
2298     }
2299   }
2300 }
2301
2302
2303
2304 /*
2305   malloc_usable_size:
2306
2307     This routine tells you how many bytes you can actually use in an
2308     allocated chunk, which may be more than you requested (although
2309     often not). You can use this many bytes without worrying about
2310     overwriting other allocated objects. Not a particularly great
2311     programming practice, but still sometimes useful.
2312
2313 */
2314
2315 #if __STD_C
2316 size_t malloc_usable_size(Void_t* mem)
2317 #else
2318 size_t malloc_usable_size(mem) Void_t* mem;
2319 #endif
2320 {
2321   mchunkptr p;
2322   if (mem == NULL)
2323     return 0;
2324   else
2325   {
2326     p = mem2chunk(mem);
2327     if(!chunk_is_mmapped(p))
2328     {
2329       if (!inuse(p)) return 0;
2330       check_inuse_chunk(p);
2331       return chunksize(p) - SIZE_SZ;
2332     }
2333     return chunksize(p) - 2*SIZE_SZ;
2334   }
2335 }
2336
2337
2338
2339
2340 /* Utility to update current_mallinfo for malloc_stats and mallinfo() */
2341
2342 #ifdef DEBUG
2343 static void malloc_update_mallinfo(void)
2344 {
2345   int i;
2346   mbinptr b;
2347   mchunkptr p;
2348 #ifdef DEBUG
2349   mchunkptr q;
2350 #endif
2351
2352   INTERNAL_SIZE_T avail = chunksize(top);
2353   int   navail = ((long)(avail) >= (long)MINSIZE)? 1 : 0;
2354
2355   for (i = 1; i < NAV; ++i)
2356   {
2357     b = bin_at(i);
2358     for (p = last(b); p != b; p = p->bk)
2359     {
2360 #ifdef DEBUG
2361       check_free_chunk(p);
2362       for (q = next_chunk(p);
2363            q < top && inuse(q) && (long)(chunksize(q)) >= (long)MINSIZE;
2364            q = next_chunk(q))
2365         check_inuse_chunk(q);
2366 #endif
2367       avail += chunksize(p);
2368       navail++;
2369     }
2370   }
2371
2372   current_mallinfo.ordblks = navail;
2373   current_mallinfo.uordblks = sbrked_mem - avail;
2374   current_mallinfo.fordblks = avail;
2375   current_mallinfo.hblks = n_mmaps;
2376   current_mallinfo.hblkhd = mmapped_mem;
2377   current_mallinfo.keepcost = chunksize(top);
2378
2379 }
2380 #endif  /* DEBUG */
2381
2382
2383
2384 /*
2385
2386   malloc_stats:
2387
2388     Prints on the amount of space obtain from the system (both
2389     via sbrk and mmap), the maximum amount (which may be more than
2390     current if malloc_trim and/or munmap got called), the maximum
2391     number of simultaneous mmap regions used, and the current number
2392     of bytes allocated via malloc (or realloc, etc) but not yet
2393     freed. (Note that this is the number of bytes allocated, not the
2394     number requested. It will be larger than the number requested
2395     because of alignment and bookkeeping overhead.)
2396
2397 */
2398
2399 #ifdef DEBUG
2400 void malloc_stats(void)
2401 {
2402   malloc_update_mallinfo();
2403   printf("max system bytes = %10u\n",
2404           (unsigned int)(max_total_mem));
2405   printf("system bytes     = %10u\n",
2406           (unsigned int)(sbrked_mem + mmapped_mem));
2407   printf("in use bytes     = %10u\n",
2408           (unsigned int)(current_mallinfo.uordblks + mmapped_mem));
2409 #if HAVE_MMAP
2410   printf("max mmap regions = %10u\n",
2411           (unsigned int)max_n_mmaps);
2412 #endif
2413 }
2414 #endif  /* DEBUG */
2415
2416 /*
2417   mallinfo returns a copy of updated current mallinfo.
2418 */
2419
2420 #ifdef DEBUG
2421 struct mallinfo mALLINFo(void)
2422 {
2423   malloc_update_mallinfo();
2424   return current_mallinfo;
2425 }
2426 #endif  /* DEBUG */
2427
2428
2429
2430
2431 /*
2432   mallopt:
2433
2434     mallopt is the general SVID/XPG interface to tunable parameters.
2435     The format is to provide a (parameter-number, parameter-value) pair.
2436     mallopt then sets the corresponding parameter to the argument
2437     value if it can (i.e., so long as the value is meaningful),
2438     and returns 1 if successful else 0.
2439
2440     See descriptions of tunable parameters above.
2441
2442 */
2443
2444 #if __STD_C
2445 int mALLOPt(int param_number, int value)
2446 #else
2447 int mALLOPt(param_number, value) int param_number; int value;
2448 #endif
2449 {
2450   switch(param_number)
2451   {
2452     case M_TRIM_THRESHOLD:
2453       trim_threshold = value; return 1;
2454     case M_TOP_PAD:
2455       top_pad = value; return 1;
2456     case M_MMAP_THRESHOLD:
2457       mmap_threshold = value; return 1;
2458     case M_MMAP_MAX:
2459 #if HAVE_MMAP
2460       n_mmaps_max = value; return 1;
2461 #else
2462       if (value != 0) return 0; else  n_mmaps_max = value; return 1;
2463 #endif
2464
2465     default:
2466       return 0;
2467   }
2468 }
2469
2470 int initf_malloc(void)
2471 {
2472 #if CONFIG_VAL(SYS_MALLOC_F_LEN)
2473         assert(gd->malloc_base);        /* Set up by crt0.S */
2474         gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN);
2475         gd->malloc_ptr = 0;
2476 #endif
2477
2478         return 0;
2479 }
2480
2481 void malloc_enable_testing(int max_allocs)
2482 {
2483         malloc_testing = true;
2484         malloc_max_allocs = max_allocs;
2485 }
2486
2487 void malloc_disable_testing(void)
2488 {
2489         malloc_testing = false;
2490 }
2491
2492 /*
2493
2494 History:
2495
2496     V2.6.6 Sun Dec  5 07:42:19 1999  Doug Lea  (dl at gee)
2497       * return null for negative arguments
2498       * Added Several WIN32 cleanups from Martin C. Fong <mcfong@yahoo.com>
2499          * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h'
2500           (e.g. WIN32 platforms)
2501          * Cleanup up header file inclusion for WIN32 platforms
2502          * Cleanup code to avoid Microsoft Visual C++ compiler complaints
2503          * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing
2504            memory allocation routines
2505          * Set 'malloc_getpagesize' for WIN32 platforms (needs more work)
2506          * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to
2507            usage of 'assert' in non-WIN32 code
2508          * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to
2509            avoid infinite loop
2510       * Always call 'fREe()' rather than 'free()'
2511
2512     V2.6.5 Wed Jun 17 15:57:31 1998  Doug Lea  (dl at gee)
2513       * Fixed ordering problem with boundary-stamping
2514
2515     V2.6.3 Sun May 19 08:17:58 1996  Doug Lea  (dl at gee)
2516       * Added pvalloc, as recommended by H.J. Liu
2517       * Added 64bit pointer support mainly from Wolfram Gloger
2518       * Added anonymously donated WIN32 sbrk emulation
2519       * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen
2520       * malloc_extend_top: fix mask error that caused wastage after
2521         foreign sbrks
2522       * Add linux mremap support code from HJ Liu
2523
2524     V2.6.2 Tue Dec  5 06:52:55 1995  Doug Lea  (dl at gee)
2525       * Integrated most documentation with the code.
2526       * Add support for mmap, with help from
2527         Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
2528       * Use last_remainder in more cases.
2529       * Pack bins using idea from  colin@nyx10.cs.du.edu
2530       * Use ordered bins instead of best-fit threshhold
2531       * Eliminate block-local decls to simplify tracing and debugging.
2532       * Support another case of realloc via move into top
2533       * Fix error occuring when initial sbrk_base not word-aligned.
2534       * Rely on page size for units instead of SBRK_UNIT to
2535         avoid surprises about sbrk alignment conventions.
2536       * Add mallinfo, mallopt. Thanks to Raymond Nijssen
2537         (raymond@es.ele.tue.nl) for the suggestion.
2538       * Add `pad' argument to malloc_trim and top_pad mallopt parameter.
2539       * More precautions for cases where other routines call sbrk,
2540         courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
2541       * Added macros etc., allowing use in linux libc from
2542         H.J. Lu (hjl@gnu.ai.mit.edu)
2543       * Inverted this history list
2544
2545     V2.6.1 Sat Dec  2 14:10:57 1995  Doug Lea  (dl at gee)
2546       * Re-tuned and fixed to behave more nicely with V2.6.0 changes.
2547       * Removed all preallocation code since under current scheme
2548         the work required to undo bad preallocations exceeds
2549         the work saved in good cases for most test programs.
2550       * No longer use return list or unconsolidated bins since
2551         no scheme using them consistently outperforms those that don't
2552         given above changes.
2553       * Use best fit for very large chunks to prevent some worst-cases.
2554       * Added some support for debugging
2555
2556     V2.6.0 Sat Nov  4 07:05:23 1995  Doug Lea  (dl at gee)
2557       * Removed footers when chunks are in use. Thanks to
2558         Paul Wilson (wilson@cs.texas.edu) for the suggestion.
2559
2560     V2.5.4 Wed Nov  1 07:54:51 1995  Doug Lea  (dl at gee)
2561       * Added malloc_trim, with help from Wolfram Gloger
2562         (wmglo@Dent.MED.Uni-Muenchen.DE).
2563
2564     V2.5.3 Tue Apr 26 10:16:01 1994  Doug Lea  (dl at g)
2565
2566     V2.5.2 Tue Apr  5 16:20:40 1994  Doug Lea  (dl at g)
2567       * realloc: try to expand in both directions
2568       * malloc: swap order of clean-bin strategy;
2569       * realloc: only conditionally expand backwards
2570       * Try not to scavenge used bins
2571       * Use bin counts as a guide to preallocation
2572       * Occasionally bin return list chunks in first scan
2573       * Add a few optimizations from colin@nyx10.cs.du.edu
2574
2575     V2.5.1 Sat Aug 14 15:40:43 1993  Doug Lea  (dl at g)
2576       * faster bin computation & slightly different binning
2577       * merged all consolidations to one part of malloc proper
2578          (eliminating old malloc_find_space & malloc_clean_bin)
2579       * Scan 2 returns chunks (not just 1)
2580       * Propagate failure in realloc if malloc returns 0
2581       * Add stuff to allow compilation on non-ANSI compilers
2582           from kpv@research.att.com
2583
2584     V2.5 Sat Aug  7 07:41:59 1993  Doug Lea  (dl at g.oswego.edu)
2585       * removed potential for odd address access in prev_chunk
2586       * removed dependency on getpagesize.h
2587       * misc cosmetics and a bit more internal documentation
2588       * anticosmetics: mangled names in macros to evade debugger strangeness
2589       * tested on sparc, hp-700, dec-mips, rs6000
2590           with gcc & native cc (hp, dec only) allowing
2591           Detlefs & Zorn comparison study (in SIGPLAN Notices.)
2592
2593     Trial version Fri Aug 28 13:14:29 1992  Doug Lea  (dl at g.oswego.edu)
2594       * Based loosely on libg++-1.2X malloc. (It retains some of the overall
2595          structure of old version,  but most details differ.)
2596
2597 */