1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3  This code is based on a version of malloc/free/realloc written by Doug Lea and
4  released to the public domain. Send questions/comments/complaints/performance
5  data to dl@cs.oswego.edu
6
7* VERSION 2.6.6  Sun Mar  5 19:10:03 2000  Doug Lea  (dl at gee)
8
9   Note: There may be an updated version of this malloc obtainable at
10	   http://g.oswego.edu/pub/misc/malloc.c
11	 Check before installing!
12
13* Why use this malloc?
14
15  This is not the fastest, most space-conserving, most portable, or
16  most tunable malloc ever written. However it is among the fastest
17  while also being among the most space-conserving, portable and tunable.
18  Consistent balance across these factors results in a good general-purpose
19  allocator. For a high-level description, see
20     http://g.oswego.edu/dl/html/malloc.html
21
22* Synopsis of public routines
23
24  (Much fuller descriptions are contained in the program documentation below.)
25
26  malloc(size_t n);
27     Return a pointer to a newly allocated chunk of at least n bytes, or null
28     if no space is available.
29  free(Void_t* p);
30     Release the chunk of memory pointed to by p, or no effect if p is null.
31  realloc(Void_t* p, size_t n);
32     Return a pointer to a chunk of size n that contains the same data
33     as does chunk p up to the minimum of (n, p's size) bytes, or null
34     if no space is available. The returned pointer may or may not be
35     the same as p. If p is null, equivalent to malloc.  Unless the
36     #define REALLOC_ZERO_BYTES_FREES below is set, realloc with a
37     size argument of zero (re)allocates a minimum-sized chunk.
38  memalign(size_t alignment, size_t n);
39     Return a pointer to a newly allocated chunk of n bytes, aligned
40     in accord with the alignment argument, which must be a power of
41     two.
42  valloc(size_t n);
43     Equivalent to memalign(pagesize, n), where pagesize is the page
44     size of the system (or as near to this as can be figured out from
45     all the includes/defines below.)
46  pvalloc(size_t n);
47     Equivalent to valloc(minimum-page-that-holds(n)), that is,
48     round up n to nearest pagesize.
49  calloc(size_t unit, size_t quantity);
50     Returns a pointer to quantity * unit bytes, with all locations
51     set to zero.
52  cfree(Void_t* p);
53     Equivalent to free(p).
54  malloc_trim(size_t pad);
55     Release all but pad bytes of freed top-most memory back
56     to the system. Return 1 if successful, else 0.
57  malloc_usable_size(Void_t* p);
58     Report the number usable allocated bytes associated with allocated
59     chunk p. This may or may not report more bytes than were requested,
60     due to alignment and minimum size constraints.
61  malloc_stats();
62     Prints brief summary statistics on stderr.
63  mallinfo()
64     Returns (by copy) a struct containing various summary statistics.
65  mallopt(int parameter_number, int parameter_value)
66     Changes one of the tunable parameters described below. Returns
67     1 if successful in changing the parameter, else 0.
68
69* Vital statistics:
70
71  Alignment:                            8-byte
72       8 byte alignment is currently hardwired into the design.  This
73       seems to suffice for all current machines and C compilers.
74
75  Assumed pointer representation:       4 or 8 bytes
76       Code for 8-byte pointers is untested by me but has worked
77       reliably by Wolfram Gloger, who contributed most of the
78       changes supporting this.
79
80  Assumed size_t  representation:       4 or 8 bytes
81       Note that size_t is allowed to be 4 bytes even if pointers are 8.
82
83  Minimum overhead per allocated chunk: 4 or 8 bytes
84       Each malloced chunk has a hidden overhead of 4 bytes holding size
85       and status information.
86
87  Minimum allocated size: 4-byte ptrs:  16 bytes    (including 4 overhead)
88			  8-byte ptrs:  24/32 bytes (including, 4/8 overhead)
89
90       When a chunk is freed, 12 (for 4byte ptrs) or 20 (for 8 byte
91       ptrs but 4 byte size) or 24 (for 8/8) additional bytes are
92       needed; 4 (8) for a trailing size field
93       and 8 (16) bytes for free list pointers. Thus, the minimum
94       allocatable size is 16/24/32 bytes.
95
96       Even a request for zero bytes (i.e., malloc(0)) returns a
97       pointer to something of the minimum allocatable size.
98
99  Maximum allocated size: 4-byte size_t: 2^31 -  8 bytes
100			  8-byte size_t: 2^63 - 16 bytes
101
102       It is assumed that (possibly signed) size_t bit values suffice to
103       represent chunk sizes. `Possibly signed' is due to the fact
104       that `size_t' may be defined on a system as either a signed or
105       an unsigned type. To be conservative, values that would appear
106       as negative numbers are avoided.
107       Requests for sizes with a negative sign bit when the request
108       size is treaded as a long will return null.
109
110  Maximum overhead wastage per allocated chunk: normally 15 bytes
111
112       Alignnment demands, plus the minimum allocatable size restriction
113       make the normal worst-case wastage 15 bytes (i.e., up to 15
114       more bytes will be allocated than were requested in malloc), with
115       two exceptions:
116	 1. Because requests for zero bytes allocate non-zero space,
117	    the worst case wastage for a request of zero bytes is 24 bytes.
118	 2. For requests >= mmap_threshold that are serviced via
119	    mmap(), the worst case wastage is 8 bytes plus the remainder
120	    from a system page (the minimal mmap unit); typically 4096 bytes.
121
122* Limitations
123
124    Here are some features that are NOT currently supported
125
126    * No user-definable hooks for callbacks and the like.
127    * No automated mechanism for fully checking that all accesses
128      to malloced memory stay within their bounds.
129    * No support for compaction.
130
131* Synopsis of compile-time options:
132
133    People have reported using previous versions of this malloc on all
134    versions of Unix, sometimes by tweaking some of the defines
135    below. It has been tested most extensively on Solaris and
136    Linux. It is also reported to work on WIN32 platforms.
137    People have also reported adapting this malloc for use in
138    stand-alone embedded systems.
139
140    The implementation is in straight, hand-tuned ANSI C.  Among other
141    consequences, it uses a lot of macros.  Because of this, to be at
142    all usable, this code should be compiled using an optimizing compiler
143    (for example gcc -O2) that can simplify expressions and control
144    paths.
145
146  __STD_C                  (default: derived from C compiler defines)
147     Nonzero if using ANSI-standard C compiler, a C++ compiler, or
148     a C compiler sufficiently close to ANSI to get away with it.
149  DEBUG                    (default: NOT defined)
150     Define to enable debugging. Adds fairly extensive assertion-based
151     checking to help track down memory errors, but noticeably slows down
152     execution.
153  REALLOC_ZERO_BYTES_FREES (default: NOT defined)
154     Define this if you think that realloc(p, 0) should be equivalent
155     to free(p). Otherwise, since malloc returns a unique pointer for
156     malloc(0), so does realloc(p, 0).
157  HAVE_MEMCPY               (default: defined)
158     Define if you are not otherwise using ANSI STD C, but still
159     have memcpy and memset in your C library and want to use them.
160     Otherwise, simple internal versions are supplied.
161  USE_MEMCPY               (default: 1 if HAVE_MEMCPY is defined, 0 otherwise)
162     Define as 1 if you want the C library versions of memset and
163     memcpy called in realloc and calloc (otherwise macro versions are used).
164     At least on some platforms, the simple macro versions usually
165     outperform libc versions.
166  HAVE_MMAP                 (default: defined as 1)
167     Define to non-zero to optionally make malloc() use mmap() to
168     allocate very large blocks.
169  HAVE_MREMAP                 (default: defined as 0 unless Linux libc set)
170     Define to non-zero to optionally make realloc() use mremap() to
171     reallocate very large blocks.
172  malloc_getpagesize        (default: derived from system #includes)
173     Either a constant or routine call returning the system page size.
174  HAVE_USR_INCLUDE_MALLOC_H (default: NOT defined)
175     Optionally define if you are on a system with a /usr/include/malloc.h
176     that declares struct mallinfo. It is not at all necessary to
177     define this even if you do, but will ensure consistency.
178  INTERNAL_SIZE_T           (default: size_t)
179     Define to a 32-bit type (probably `unsigned int') if you are on a
180     64-bit machine, yet do not want or need to allow malloc requests of
181     greater than 2^31 to be handled. This saves space, especially for
182     very small chunks.
183  INTERNAL_LINUX_C_LIB      (default: NOT defined)
184     Defined only when compiled as part of Linux libc.
185     Also note that there is some odd internal name-mangling via defines
186     (for example, internally, `malloc' is named `mALLOc') needed
187     when compiling in this case. These look funny but don't otherwise
188     affect anything.
189  WIN32                     (default: undefined)
190     Define this on MS win (95, nt) platforms to compile in sbrk emulation.
191  LACKS_UNISTD_H            (default: undefined if not WIN32)
192     Define this if your system does not have a <unistd.h>.
193  LACKS_SYS_PARAM_H         (default: undefined if not WIN32)
194     Define this if your system does not have a <sys/param.h>.
195  MORECORE                  (default: sbrk)
196     The name of the routine to call to obtain more memory from the system.
197  MORECORE_FAILURE          (default: -1)
198     The value returned upon failure of MORECORE.
199  MORECORE_CLEARS           (default 1)
200     true (1) if the routine mapped to MORECORE zeroes out memory (which
201     holds for sbrk).
202  DEFAULT_TRIM_THRESHOLD
203  DEFAULT_TOP_PAD
204  DEFAULT_MMAP_THRESHOLD
205  DEFAULT_MMAP_MAX
206     Default values of tunable parameters (described in detail below)
207     controlling interaction with host system routines (sbrk, mmap, etc).
208     These values may also be changed dynamically via mallopt(). The
209     preset defaults are those that give best performance for typical
210     programs/systems.
211  USE_DL_PREFIX             (default: undefined)
212     Prefix all public routines with the string 'dl'.  Useful to
213     quickly avoid procedure declaration conflicts and linker symbol
214     conflicts with existing memory allocation routines.
215
216
217*/
218
219
220#ifndef __MALLOC_H__
221#define __MALLOC_H__
222
223/* Preliminaries */
224
225#ifndef __STD_C
226#ifdef __STDC__
227#define __STD_C     1
228#else
229#if __cplusplus
230#define __STD_C     1
231#else
232#define __STD_C     0
233#endif /*__cplusplus*/
234#endif /*__STDC__*/
235#endif /*__STD_C*/
236
237#ifndef Void_t
238#if (__STD_C || defined(WIN32))
239#define Void_t      void
240#else
241#define Void_t      char
242#endif
243#endif /*Void_t*/
244
245#if __STD_C
246#include <linux/stddef.h>	/* for size_t */
247#else
248#include <sys/types.h>
249#endif	/* __STD_C */
250
251#ifdef __cplusplus
252extern "C" {
253#endif
254
255#if 0	/* not for U-Boot */
256#include <stdio.h>	/* needed for malloc_stats */
257#endif
258
259
260/*
261  Compile-time options
262*/
263
264
265/*
266    Debugging:
267
268    Because freed chunks may be overwritten with link fields, this
269    malloc will often die when freed memory is overwritten by user
270    programs.  This can be very effective (albeit in an annoying way)
271    in helping track down dangling pointers.
272
273    If you compile with -DDEBUG, a number of assertion checks are
274    enabled that will catch more memory errors. You probably won't be
275    able to make much sense of the actual assertion errors, but they
276    should help you locate incorrectly overwritten memory.  The
277    checking is fairly extensive, and will slow down execution
278    noticeably. Calling malloc_stats or mallinfo with DEBUG set will
279    attempt to check every non-mmapped allocated and free chunk in the
280    course of computing the summmaries. (By nature, mmapped regions
281    cannot be checked very much automatically.)
282
283    Setting DEBUG may also be helpful if you are trying to modify
284    this code. The assertions in the check routines spell out in more
285    detail the assumptions and invariants underlying the algorithms.
286
287*/
288
289/*
290  INTERNAL_SIZE_T is the word-size used for internal bookkeeping
291  of chunk sizes. On a 64-bit machine, you can reduce malloc
292  overhead by defining INTERNAL_SIZE_T to be a 32 bit `unsigned int'
293  at the expense of not being able to handle requests greater than
294  2^31. This limitation is hardly ever a concern; you are encouraged
295  to set this. However, the default version is the same as size_t.
296*/
297
298#ifndef INTERNAL_SIZE_T
299#define INTERNAL_SIZE_T size_t
300#endif
301
302/*
303  REALLOC_ZERO_BYTES_FREES should be set if a call to
304  realloc with zero bytes should be the same as a call to free.
305  Some people think it should. Otherwise, since this malloc
306  returns a unique pointer for malloc(0), so does realloc(p, 0).
307*/
308
309
310/*   #define REALLOC_ZERO_BYTES_FREES */
311
312
313/*
314  WIN32 causes an emulation of sbrk to be compiled in
315  mmap-based options are not currently supported in WIN32.
316*/
317
318/* #define WIN32 */
319#ifdef WIN32
320#define MORECORE wsbrk
321#define HAVE_MMAP 0
322
323#define LACKS_UNISTD_H
324#define LACKS_SYS_PARAM_H
325
326/*
327  Include 'windows.h' to get the necessary declarations for the
328  Microsoft Visual C++ data structures and routines used in the 'sbrk'
329  emulation.
330
331  Define WIN32_LEAN_AND_MEAN so that only the essential Microsoft
332  Visual C++ header files are included.
333*/
334#define WIN32_LEAN_AND_MEAN
335#include <windows.h>
336#endif
337
338
339/*
340  HAVE_MEMCPY should be defined if you are not otherwise using
341  ANSI STD C, but still have memcpy and memset in your C library
342  and want to use them in calloc and realloc. Otherwise simple
343  macro versions are defined here.
344
345  USE_MEMCPY should be defined as 1 if you actually want to
346  have memset and memcpy called. People report that the macro
347  versions are often enough faster than libc versions on many
348  systems that it is better to use them.
349
350*/
351
352#define HAVE_MEMCPY
353
354#ifndef USE_MEMCPY
355#ifdef HAVE_MEMCPY
356#define USE_MEMCPY 1
357#else
358#define USE_MEMCPY 0
359#endif
360#endif
361
362#if (__STD_C || defined(HAVE_MEMCPY))
363
364#if __STD_C
365/* U-Boot defines memset() and memcpy in /include/linux/string.h
366void* memset(void*, int, size_t);
367void* memcpy(void*, const void*, size_t);
368*/
369#include <linux/string.h>
370#else
371#ifdef WIN32
372/* On Win32 platforms, 'memset()' and 'memcpy()' are already declared in */
373/* 'windows.h' */
374#else
375Void_t* memset();
376Void_t* memcpy();
377#endif
378#endif
379#endif
380
381#if USE_MEMCPY
382
383/* The following macros are only invoked with (2n+1)-multiples of
384   INTERNAL_SIZE_T units, with a positive integer n. This is exploited
385   for fast inline execution when n is small. */
386
387#define MALLOC_ZERO(charp, nbytes)                                            \
388do {                                                                          \
389  INTERNAL_SIZE_T mzsz = (nbytes);                                            \
390  if(mzsz <= 9*sizeof(mzsz)) {                                                \
391    INTERNAL_SIZE_T* mz = (INTERNAL_SIZE_T*) (charp);                         \
392    if(mzsz >= 5*sizeof(mzsz)) {     *mz++ = 0;                               \
393				     *mz++ = 0;                               \
394      if(mzsz >= 7*sizeof(mzsz)) {   *mz++ = 0;                               \
395				     *mz++ = 0;                               \
396	if(mzsz >= 9*sizeof(mzsz)) { *mz++ = 0;                               \
397				     *mz++ = 0; }}}                           \
398				     *mz++ = 0;                               \
399				     *mz++ = 0;                               \
400				     *mz   = 0;                               \
401  } else memset((charp), 0, mzsz);                                            \
402} while(0)
403
404#define MALLOC_COPY(dest,src,nbytes)                                          \
405do {                                                                          \
406  INTERNAL_SIZE_T mcsz = (nbytes);                                            \
407  if(mcsz <= 9*sizeof(mcsz)) {                                                \
408    INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) (src);                        \
409    INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) (dest);                       \
410    if(mcsz >= 5*sizeof(mcsz)) {     *mcdst++ = *mcsrc++;                     \
411				     *mcdst++ = *mcsrc++;                     \
412      if(mcsz >= 7*sizeof(mcsz)) {   *mcdst++ = *mcsrc++;                     \
413				     *mcdst++ = *mcsrc++;                     \
414	if(mcsz >= 9*sizeof(mcsz)) { *mcdst++ = *mcsrc++;                     \
415				     *mcdst++ = *mcsrc++; }}}                 \
416				     *mcdst++ = *mcsrc++;                     \
417				     *mcdst++ = *mcsrc++;                     \
418				     *mcdst   = *mcsrc  ;                     \
419  } else memcpy(dest, src, mcsz);                                             \
420} while(0)
421
422#else /* !USE_MEMCPY */
423
424/* Use Duff's device for good zeroing/copying performance. */
425
426#define MALLOC_ZERO(charp, nbytes)                                            \
427do {                                                                          \
428  INTERNAL_SIZE_T* mzp = (INTERNAL_SIZE_T*)(charp);                           \
429  long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T), mcn;                         \
430  if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; }             \
431  switch (mctmp) {                                                            \
432    case 0: for(;;) { *mzp++ = 0;                                             \
433    case 7:           *mzp++ = 0;                                             \
434    case 6:           *mzp++ = 0;                                             \
435    case 5:           *mzp++ = 0;                                             \
436    case 4:           *mzp++ = 0;                                             \
437    case 3:           *mzp++ = 0;                                             \
438    case 2:           *mzp++ = 0;                                             \
439    case 1:           *mzp++ = 0; if(mcn <= 0) break; mcn--; }                \
440  }                                                                           \
441} while(0)
442
443#define MALLOC_COPY(dest,src,nbytes)                                          \
444do {                                                                          \
445  INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) src;                            \
446  INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) dest;                           \
447  long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T), mcn;                         \
448  if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; }             \
449  switch (mctmp) {                                                            \
450    case 0: for(;;) { *mcdst++ = *mcsrc++;                                    \
451    case 7:           *mcdst++ = *mcsrc++;                                    \
452    case 6:           *mcdst++ = *mcsrc++;                                    \
453    case 5:           *mcdst++ = *mcsrc++;                                    \
454    case 4:           *mcdst++ = *mcsrc++;                                    \
455    case 3:           *mcdst++ = *mcsrc++;                                    \
456    case 2:           *mcdst++ = *mcsrc++;                                    \
457    case 1:           *mcdst++ = *mcsrc++; if(mcn <= 0) break; mcn--; }       \
458  }                                                                           \
459} while(0)
460
461#endif
462
463
464/*
465  Define HAVE_MMAP to optionally make malloc() use mmap() to
466  allocate very large blocks.  These will be returned to the
467  operating system immediately after a free().
468*/
469
470/***
471#ifndef HAVE_MMAP
472#define HAVE_MMAP 1
473#endif
474***/
475#undef	HAVE_MMAP	/* Not available for U-Boot */
476
477/*
478  Define HAVE_MREMAP to make realloc() use mremap() to re-allocate
479  large blocks.  This is currently only possible on Linux with
480  kernel versions newer than 1.3.77.
481*/
482
483/***
484#ifndef HAVE_MREMAP
485#ifdef INTERNAL_LINUX_C_LIB
486#define HAVE_MREMAP 1
487#else
488#define HAVE_MREMAP 0
489#endif
490#endif
491***/
492#undef	HAVE_MREMAP	/* Not available for U-Boot */
493
494#ifdef HAVE_MMAP
495
496#include <unistd.h>
497#include <fcntl.h>
498#include <sys/mman.h>
499
500#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
501#define MAP_ANONYMOUS MAP_ANON
502#endif
503
504#endif /* HAVE_MMAP */
505
506/*
507  Access to system page size. To the extent possible, this malloc
508  manages memory from the system in page-size units.
509
510  The following mechanics for getpagesize were adapted from
511  bsd/gnu getpagesize.h
512*/
513
514#define	LACKS_UNISTD_H	/* Shortcut for U-Boot */
515#define	malloc_getpagesize	4096
516
517#ifndef LACKS_UNISTD_H
518#  include <unistd.h>
519#endif
520
521#ifndef malloc_getpagesize
522#  ifdef _SC_PAGESIZE         /* some SVR4 systems omit an underscore */
523#    ifndef _SC_PAGE_SIZE
524#      define _SC_PAGE_SIZE _SC_PAGESIZE
525#    endif
526#  endif
527#  ifdef _SC_PAGE_SIZE
528#    define malloc_getpagesize sysconf(_SC_PAGE_SIZE)
529#  else
530#    if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
531       extern size_t getpagesize();
532#      define malloc_getpagesize getpagesize()
533#    else
534#      ifdef WIN32
535#        define malloc_getpagesize (4096) /* TBD: Use 'GetSystemInfo' instead */
536#      else
537#        ifndef LACKS_SYS_PARAM_H
538#          include <sys/param.h>
539#        endif
540#        ifdef EXEC_PAGESIZE
541#          define malloc_getpagesize EXEC_PAGESIZE
542#        else
543#          ifdef NBPG
544#            ifndef CLSIZE
545#              define malloc_getpagesize NBPG
546#            else
547#              define malloc_getpagesize (NBPG * CLSIZE)
548#            endif
549#          else
550#            ifdef NBPC
551#              define malloc_getpagesize NBPC
552#            else
553#              ifdef PAGESIZE
554#                define malloc_getpagesize PAGESIZE
555#              else
556#                define malloc_getpagesize (4096) /* just guess */
557#              endif
558#            endif
559#          endif
560#        endif
561#      endif
562#    endif
563#  endif
564#endif
565
566
567/*
568
569  This version of malloc supports the standard SVID/XPG mallinfo
570  routine that returns a struct containing the same kind of
571  information you can get from malloc_stats. It should work on
572  any SVID/XPG compliant system that has a /usr/include/malloc.h
573  defining struct mallinfo. (If you'd like to install such a thing
574  yourself, cut out the preliminary declarations as described above
575  and below and save them in a malloc.h file. But there's no
576  compelling reason to bother to do this.)
577
578  The main declaration needed is the mallinfo struct that is returned
579  (by-copy) by mallinfo().  The SVID/XPG malloinfo struct contains a
580  bunch of fields, most of which are not even meaningful in this
581  version of malloc. Some of these fields are are instead filled by
582  mallinfo() with other numbers that might possibly be of interest.
583
584  HAVE_USR_INCLUDE_MALLOC_H should be set if you have a
585  /usr/include/malloc.h file that includes a declaration of struct
586  mallinfo.  If so, it is included; else an SVID2/XPG2 compliant
587  version is declared below.  These must be precisely the same for
588  mallinfo() to work.
589
590*/
591
592/* #define HAVE_USR_INCLUDE_MALLOC_H */
593
594#ifdef HAVE_USR_INCLUDE_MALLOC_H
595#include "/usr/include/malloc.h"
596#else
597
598/* SVID2/XPG mallinfo structure */
599
600struct mallinfo {
601  int arena;    /* total space allocated from system */
602  int ordblks;  /* number of non-inuse chunks */
603  int smblks;   /* unused -- always zero */
604  int hblks;    /* number of mmapped regions */
605  int hblkhd;   /* total space in mmapped regions */
606  int usmblks;  /* unused -- always zero */
607  int fsmblks;  /* unused -- always zero */
608  int uordblks; /* total allocated space */
609  int fordblks; /* total non-inuse space */
610  int keepcost; /* top-most, releasable (via malloc_trim) space */
611};
612
613/* SVID2/XPG mallopt options */
614
615#define M_MXFAST  1    /* UNUSED in this malloc */
616#define M_NLBLKS  2    /* UNUSED in this malloc */
617#define M_GRAIN   3    /* UNUSED in this malloc */
618#define M_KEEP    4    /* UNUSED in this malloc */
619
620#endif
621
622/* mallopt options that actually do something */
623
624#define M_TRIM_THRESHOLD    -1
625#define M_TOP_PAD           -2
626#define M_MMAP_THRESHOLD    -3
627#define M_MMAP_MAX          -4
628
629
630#ifndef DEFAULT_TRIM_THRESHOLD
631#define DEFAULT_TRIM_THRESHOLD (128 * 1024)
632#endif
633
634/*
635    M_TRIM_THRESHOLD is the maximum amount of unused top-most memory
636      to keep before releasing via malloc_trim in free().
637
638      Automatic trimming is mainly useful in long-lived programs.
639      Because trimming via sbrk can be slow on some systems, and can
640      sometimes be wasteful (in cases where programs immediately
641      afterward allocate more large chunks) the value should be high
642      enough so that your overall system performance would improve by
643      releasing.
644
645      The trim threshold and the mmap control parameters (see below)
646      can be traded off with one another. Trimming and mmapping are
647      two different ways of releasing unused memory back to the
648      system. Between these two, it is often possible to keep
649      system-level demands of a long-lived program down to a bare
650      minimum. For example, in one test suite of sessions measuring
651      the XF86 X server on Linux, using a trim threshold of 128K and a
652      mmap threshold of 192K led to near-minimal long term resource
653      consumption.
654
655      If you are using this malloc in a long-lived program, it should
656      pay to experiment with these values.  As a rough guide, you
657      might set to a value close to the average size of a process
658      (program) running on your system.  Releasing this much memory
659      would allow such a process to run in memory.  Generally, it's
660      worth it to tune for trimming rather tham memory mapping when a
661      program undergoes phases where several large chunks are
662      allocated and released in ways that can reuse each other's
663      storage, perhaps mixed with phases where there are no such
664      chunks at all.  And in well-behaved long-lived programs,
665      controlling release of large blocks via trimming versus mapping
666      is usually faster.
667
668      However, in most programs, these parameters serve mainly as
669      protection against the system-level effects of carrying around
670      massive amounts of unneeded memory. Since frequent calls to
671      sbrk, mmap, and munmap otherwise degrade performance, the default
672      parameters are set to relatively high values that serve only as
673      safeguards.
674
675      The default trim value is high enough to cause trimming only in
676      fairly extreme (by current memory consumption standards) cases.
677      It must be greater than page size to have any useful effect.  To
678      disable trimming completely, you can set to (unsigned long)(-1);
679
680
681*/
682
683
684#ifndef DEFAULT_TOP_PAD
685#define DEFAULT_TOP_PAD        (0)
686#endif
687
688/*
689    M_TOP_PAD is the amount of extra `padding' space to allocate or
690      retain whenever sbrk is called. It is used in two ways internally:
691
692      * When sbrk is called to extend the top of the arena to satisfy
693	a new malloc request, this much padding is added to the sbrk
694	request.
695
696      * When malloc_trim is called automatically from free(),
697	it is used as the `pad' argument.
698
699      In both cases, the actual amount of padding is rounded
700      so that the end of the arena is always a system page boundary.
701
702      The main reason for using padding is to avoid calling sbrk so
703      often. Having even a small pad greatly reduces the likelihood
704      that nearly every malloc request during program start-up (or
705      after trimming) will invoke sbrk, which needlessly wastes
706      time.
707
708      Automatic rounding-up to page-size units is normally sufficient
709      to avoid measurable overhead, so the default is 0.  However, in
710      systems where sbrk is relatively slow, it can pay to increase
711      this value, at the expense of carrying around more memory than
712      the program needs.
713
714*/
715
716
717#ifndef DEFAULT_MMAP_THRESHOLD
718#define DEFAULT_MMAP_THRESHOLD (128 * 1024)
719#endif
720
721/*
722
723    M_MMAP_THRESHOLD is the request size threshold for using mmap()
724      to service a request. Requests of at least this size that cannot
725      be allocated using already-existing space will be serviced via mmap.
726      (If enough normal freed space already exists it is used instead.)
727
728      Using mmap segregates relatively large chunks of memory so that
729      they can be individually obtained and released from the host
730      system. A request serviced through mmap is never reused by any
731      other request (at least not directly; the system may just so
732      happen to remap successive requests to the same locations).
733
734      Segregating space in this way has the benefit that mmapped space
735      can ALWAYS be individually released back to the system, which
736      helps keep the system level memory demands of a long-lived
737      program low. Mapped memory can never become `locked' between
738      other chunks, as can happen with normally allocated chunks, which
739      menas that even trimming via malloc_trim would not release them.
740
741      However, it has the disadvantages that:
742
743	 1. The space cannot be reclaimed, consolidated, and then
744	    used to service later requests, as happens with normal chunks.
745	 2. It can lead to more wastage because of mmap page alignment
746	    requirements
747	 3. It causes malloc performance to be more dependent on host
748	    system memory management support routines which may vary in
749	    implementation quality and may impose arbitrary
750	    limitations. Generally, servicing a request via normal
751	    malloc steps is faster than going through a system's mmap.
752
753      All together, these considerations should lead you to use mmap
754      only for relatively large requests.
755
756
757*/
758
759
760#ifndef DEFAULT_MMAP_MAX
761#ifdef HAVE_MMAP
762#define DEFAULT_MMAP_MAX       (64)
763#else
764#define DEFAULT_MMAP_MAX       (0)
765#endif
766#endif
767
768/*
769    M_MMAP_MAX is the maximum number of requests to simultaneously
770      service using mmap. This parameter exists because:
771
772	 1. Some systems have a limited number of internal tables for
773	    use by mmap.
774	 2. In most systems, overreliance on mmap can degrade overall
775	    performance.
776	 3. If a program allocates many large regions, it is probably
777	    better off using normal sbrk-based allocation routines that
778	    can reclaim and reallocate normal heap memory. Using a
779	    small value allows transition into this mode after the
780	    first few allocations.
781
782      Setting to 0 disables all use of mmap.  If HAVE_MMAP is not set,
783      the default value is 0, and attempts to set it to non-zero values
784      in mallopt will fail.
785*/
786
787
788/*
789    USE_DL_PREFIX will prefix all public routines with the string 'dl'.
790      Useful to quickly avoid procedure declaration conflicts and linker
791      symbol conflicts with existing memory allocation routines.
792
793*/
794
795/*
796 * Rename the U-Boot alloc functions so that sandbox can still use the system
797 * ones
798 */
799#ifdef CONFIG_SANDBOX
800#define USE_DL_PREFIX
801#endif
802
803/*
804
805  Special defines for linux libc
806
807  Except when compiled using these special defines for Linux libc
808  using weak aliases, this malloc is NOT designed to work in
809  multithreaded applications.  No semaphores or other concurrency
810  control are provided to ensure that multiple malloc or free calls
811  don't run at the same time, which could be disasterous. A single
812  semaphore could be used across malloc, realloc, and free (which is
813  essentially the effect of the linux weak alias approach). It would
814  be hard to obtain finer granularity.
815
816*/
817
818
819#ifdef INTERNAL_LINUX_C_LIB
820
821#if __STD_C
822
823Void_t * __default_morecore_init (ptrdiff_t);
824Void_t *(*__morecore)(ptrdiff_t) = __default_morecore_init;
825
826#else
827
828Void_t * __default_morecore_init ();
829Void_t *(*__morecore)() = __default_morecore_init;
830
831#endif
832
833#define MORECORE (*__morecore)
834#define MORECORE_FAILURE 0
835#define MORECORE_CLEARS 1
836
837#else /* INTERNAL_LINUX_C_LIB */
838
839#if __STD_C
840extern Void_t*     sbrk(ptrdiff_t);
841#else
842extern Void_t*     sbrk();
843#endif
844
845#ifndef MORECORE
846#define MORECORE sbrk
847#endif
848
849#ifndef MORECORE_FAILURE
850#define MORECORE_FAILURE -1
851#endif
852
853#ifndef MORECORE_CLEARS
854#define MORECORE_CLEARS 1
855#endif
856
857#endif /* INTERNAL_LINUX_C_LIB */
858
859#if defined(INTERNAL_LINUX_C_LIB) && defined(__ELF__)
860
861#define cALLOc		__libc_calloc
862#define fREe		__libc_free
863#define mALLOc		__libc_malloc
864#define mEMALIGn	__libc_memalign
865#define rEALLOc		__libc_realloc
866#define vALLOc		__libc_valloc
867#define pvALLOc		__libc_pvalloc
868#define mALLINFo	__libc_mallinfo
869#define mALLOPt		__libc_mallopt
870
871#pragma weak calloc = __libc_calloc
872#pragma weak free = __libc_free
873#pragma weak cfree = __libc_free
874#pragma weak malloc = __libc_malloc
875#pragma weak memalign = __libc_memalign
876#pragma weak realloc = __libc_realloc
877#pragma weak valloc = __libc_valloc
878#pragma weak pvalloc = __libc_pvalloc
879#pragma weak mallinfo = __libc_mallinfo
880#pragma weak mallopt = __libc_mallopt
881
882#else
883
884void malloc_simple_info(void);
885
886/**
887 * malloc_enable_testing() - Put malloc() into test mode
888 *
889 * This only works if UNIT_TESTING is enabled
890 *
891 * @max_allocs: return -ENOMEM after max_allocs calls to malloc()
892 */
893void malloc_enable_testing(int max_allocs);
894
895/** malloc_disable_testing() - Put malloc() into normal mode */
896void malloc_disable_testing(void);
897
898#if CONFIG_IS_ENABLED(SYS_MALLOC_SIMPLE)
899#define malloc malloc_simple
900#define realloc realloc_simple
901#define memalign memalign_simple
902#if IS_ENABLED(CONFIG_VALGRIND)
903#define free free_simple
904#else
905static inline void free(void *ptr) {}
906#endif
907void *calloc(size_t nmemb, size_t size);
908void *realloc_simple(void *ptr, size_t size);
909#else
910
911# ifdef USE_DL_PREFIX
912# define cALLOc		dlcalloc
913# define fREe		dlfree
914# define mALLOc		dlmalloc
915# define mEMALIGn	dlmemalign
916# define rEALLOc		dlrealloc
917# define vALLOc		dlvalloc
918# define pvALLOc		dlpvalloc
919# define mALLINFo	dlmallinfo
920# define mALLOPt		dlmallopt
921
922/* Ensure that U-Boot actually uses these too */
923#define calloc dlcalloc
924#define free(ptr) dlfree(ptr)
925#define malloc(x) dlmalloc(x)
926#define memalign dlmemalign
927#define realloc dlrealloc
928#define valloc dlvalloc
929#define pvalloc dlpvalloc
930#define mallinfo() dlmallinfo()
931#define mallopt dlmallopt
932#define malloc_trim dlmalloc_trim
933#define malloc_usable_size dlmalloc_usable_size
934#define malloc_stats dlmalloc_stats
935
936# else /* USE_DL_PREFIX */
937# define cALLOc		calloc
938# define fREe		free
939# define mALLOc		malloc
940# define mEMALIGn	memalign
941# define rEALLOc		realloc
942# define vALLOc		valloc
943# define pvALLOc		pvalloc
944# define mALLINFo	mallinfo
945# define mALLOPt		mallopt
946# endif /* USE_DL_PREFIX */
947
948#endif
949
950/* Set up pre-relocation malloc() ready for use */
951int initf_malloc(void);
952
953/* Public routines */
954
955/* Simple versions which can be used when space is tight */
956void *malloc_simple(size_t size);
957void *memalign_simple(size_t alignment, size_t bytes);
958
959#pragma GCC visibility push(hidden)
960# if __STD_C
961
962Void_t* mALLOc(size_t);
963void    fREe(Void_t*);
964Void_t* rEALLOc(Void_t*, size_t);
965Void_t* mEMALIGn(size_t, size_t);
966Void_t* vALLOc(size_t);
967Void_t* pvALLOc(size_t);
968Void_t* cALLOc(size_t, size_t);
969void    cfree(Void_t*);
970int     malloc_trim(size_t);
971size_t  malloc_usable_size(Void_t*);
972void    malloc_stats(void);
973int     mALLOPt(int, int);
974struct mallinfo mALLINFo(void);
975# else
976Void_t* mALLOc();
977void    fREe();
978Void_t* rEALLOc();
979Void_t* mEMALIGn();
980Void_t* vALLOc();
981Void_t* pvALLOc();
982Void_t* cALLOc();
983void    cfree();
984int     malloc_trim();
985size_t  malloc_usable_size();
986void    malloc_stats();
987int     mALLOPt();
988struct mallinfo mALLINFo();
989# endif
990#endif
991#pragma GCC visibility pop
992
993/*
994 * Begin and End of memory area for malloc(), and current "brk"
995 */
996extern ulong mem_malloc_start;
997extern ulong mem_malloc_end;
998extern ulong mem_malloc_brk;
999
1000void mem_malloc_init(ulong start, ulong size);
1001
1002#ifdef __cplusplus
1003};  /* end of extern "C" */
1004#endif
1005
1006#endif /* __MALLOC_H__ */
1007