Commit Graph

13 Commits

Author SHA1 Message Date
Keith Packard via Newlib 8a7ec55c53 libm/stdlib: Realloc when shrinking by 2* or more
This reduces memory usage when reallocating objects much smaller.

Signed-off-by: Keith Packard <keithp@keithp.com>
2020-08-17 11:43:55 +02:00
Keith Packard via Newlib ce4044adee libm/stdlib: don't read past source in nano_realloc
Save the computed block size and use it to avoid reading past
the end of the source block.

Signed-off-by: Keith Packard <keithp@keithp.com>
2020-08-17 11:43:55 +02:00
Craig Blackmore ab215e3dd1 libc/stdlib: Fix build failure in nano_calloc
commit 588a5e1dde added a non-reentrant
call to nano_malloc which causes a build failure if INTERNAL_NEWLIB is
defined.

Here is a snippet of the error:

In file included from .../newlib/newlib/libc/stdlib/nano-mallocr.c:38:
.../newlib/newlib/libc/include/malloc.h:42:25: note: expected 'struct _reent *' but argument is of type 'ptrdiff_t' {aka 'int'}
   42 | extern void *_malloc_r (struct _reent *, size_t);
      |                         ^~~~~~~~~~~~~~~
.../newlib/newlib/libc/stdlib/nano-mallocr.c:67:22: error: too few arguments to function '_malloc_r'
   67 | #define nano_malloc  _malloc_r
      |                      ^~~~~~~~~
.../newlib/newlib/libc/stdlib/nano-mallocr.c:456:11: note: in expansion of macro 'nano_malloc'
  456 |     mem = nano_malloc(bytes);
      |           ^~~~~~~~~~~
In file included from .../newlib/newlib/libc/stdlib/nano-mallocr.c:38:
.../newlib/newlib/libc/include/malloc.h:42:14: note: declared here
   42 | extern void *_malloc_r (struct _reent *, size_t);
      |              ^~~~~~~~~
.../newlib/newlib/libc/stdlib/nano-mallocr.c:43: warning: "assert" redefined
   43 | #define assert(x) ((void)0)
      |

This patch adds a missing RCALL to the args when calling nano_malloc
from nano_calloc, so that if the call is reentrant, reent_ptr is passed
as the first argument.

The variable `bytes` (also added in 588a5e1d) has been changed from a
`ptrdiff_t` to `malloc_size_t` as it does not need to be signed. It is
used to store the product of two unsigned malloc_size_t variables and
then iff there was no overflow is it passed to malloc and memset which
both expect size_t which is unsigned.

Signed-off-by: Craig Blackmore <craig.blackmore@embecosm.com>
2020-08-13 09:59:45 +02:00
Keith Packard via Newlib 588a5e1dde libc/stdlib: Use __builtin_mul_overflow for reallocarray and calloc
This built-in function (available in both gcc and clang) is more
efficient and generates shorter code than open-coding the test.

Signed-off-by: Keith Packard <keithp@keithp.com>
2020-08-12 10:09:56 +02:00
Jaap de Wolff 337cee51ca Add prototype to _malloc_lock() and *unlock() to malloc.h, and inlude this from nano-mallocr.c 2018-02-16 12:16:07 +01:00
Joe Seymour c0ac2ea2b3 Expand comments on padding used by nano_malloc
This patch adds further comments to nano-mallocr.c, to more comprehensively
explain how padding works in the malloc_chunk structure.

It was originally discussed in the following thread:
  https://sourceware.org/ml/newlib/2017/msg00031.html

2017-01-13  Joe Seymour  <joe.s@somniumtech.com>

        newlib/
        * libc/stdlib/nano-mallocr.c (malloc_chunk, get_chunk_from_ptr)
        (nano_malloc): Add comments.
2017-01-13 17:39:21 +01:00
Joe Seymour 83c39aedac Fix incorrect cast in nano malloc
As described in nano-mallocr.c, chunks of heap are represented in memory
as a size (of type long), followed by some optional padding containing a
negative offset to size, followed by the data area.

get_chunk_from_ptr is responsible for taking a pointer to the data area
(as returned by malloc) and finding the start of the chunk. It does this
by assuming there is no padding and trying to read the size, if the size
is negative then it uses that as an offset to find the true size.
Crucially, it reads the padding area as a long.

nano_malloc is responsible for populating the optional padding area. It
does so by casting a pointer to an (int *) and writing the negative
offset into it.

This means that padding is being written as an int but read as a long.

On msp430 an int is 2 bytes, while a long is 4 bytes. This means that 2
bytes are written to the padding, but 4 bytes are read from it: it has
only been partially initialised.

nano_malloc is the default malloc implementation for msp430.

This patch changes the cast from (int *) to (long *). The change to
nano_malloc has has been observed to fix a TI Energia project that
had been malfunctioning because malloc was returning invalid addresses.
The change to nano_memalign is based entirely on code inspection.

I've built and tested as follows:
  Configured (gcc+newlib) with: --target=msp430-elf --enable-languages=c
  gcc testsuite variations:
    msp430-sim/-mcpu=msp430
    msp430-sim/-mcpu=msp430x
    msp430-sim/-mcpu=msp430x/-mlarge/-mdata-region=either/-mcode-region=either
    msp430-sim/-mhwmult=none
    msp430-sim/-mhwmult=f5series
My testing has shown no regressions, however I don't know if the gcc
testsuite provides sufficient coverage for this patch?

I don't have write access, so if this patch is acceptable after review,
I would appreciate it if someone would commit it for me.

Thanks,

2017-01-XX  Joe Seymour  <joe.s@somniumtech.com>

	newlib/
	* libc/stdlib/nano-mallocr.c (nano_malloc): Fix incorrect cast.
	(nano_memalign): Likewise.
2017-01-09 16:16:12 +01:00
Andre Vieira (lists) 2665915cfc Re-enable malloc_lock for newlib-nano
Re-enable the use of __malloc_lock and __malloc_unlock newlib-nano, tied
the newlib-multithread.
2016-06-16 14:20:44 +02:00
Игорь Веневцев 352cdbb012 Newlib build is broken if configured with nano-malloc and non-reentrant system calls
Non-reentrant system calls version implies both MISSING_SYSCALL_NAMES
and REENTRANT_SYSCALL_PROVIDED macros to be defined.
Being coupled with --enable-newlib-nano-malloc knob it breaks the build:

bash-4.3$ ../newlib-2.3.0.20160104/configure CC_FOR_TARGET=gcc
AR_FOR_TARGET=ar RANLIB_FOR_TARGET=ranlib CFLAGS_FOR_TARGET="-m32
-DMISSING_SYSCALL_NAMES -DREENTRANT_SYSCALLS_PROVIDED"
--target=i386-elf --enable-newlib-nano-malloc && make

<...omitted output...>

../../../../../../newlib-2.3.0.20160104/newlib/libc/stdlib/nano-mallocr.c:
In function ‘_mallinfo_r’:
../../../../../../newlib-2.3.0.20160104/newlib/libc/stdlib/nano-mallocr.c:489:35:
error: macro "_sbrk_r" requires 2 arguments, but only 1 given
         sbrk_now = _sbrk_r(RCALL 0);
                                   ^
../../../../../../newlib-2.3.0.20160104/newlib/libc/stdlib/nano-mallocr.c:489:20:
error: ‘_sbrk_r’ undeclared (first use in this function)
         sbrk_now = _sbrk_r(RCALL 0);
                    ^
../../../../../../newlib-2.3.0.20160104/newlib/libc/stdlib/nano-mallocr.c:489:20:
note: each undeclared identifier is reported only once for each
function it appears in
Makefile:1512: recipe for target 'lib_a-nano-mallinfor.o' failed
make[8]: *** [lib_a-nano-mallinfor.o] Error 1

In case of non-reentrant system calls _sbrk_r became a macro with TWO
args (defined in reent.h):

#define _sbrk_r(__reent, __incr)  sbrk(__incr)

But in our case only one argument is present. (RCALL 0) is considered
as a single argument despite RCALL itself is a macro:)

So intermediate one-arg macro will be enough to expand args before
final _sbrk_r expansion:

#define _SBRK_R(X) _sbrk_r(X)

Here is a patch:
2016-02-08 10:33:07 +01:00
DJ Delorie ae4a2bd820 * libc/stdlib/nano-mallocr.c (ALIGN_TO): Do not assume that
integers are as big as pointers.
2014-12-16 20:46:25 +00:00
Corinna Vinschen 566fd12b68 Implement malloc_stats for nano.
* libc/stdlib/nano-mallocr.c (RONECALL): New parameter macro.
	(sbrk_start): New variable.
	(current_mallinfo, free_list): Forward declaration of data.
	(chunk): Define size as long type.
	(mallinfo): Synchronize with latest malloc.h.
	(nano_*): Forward declaration of functions.
	(get_chunk_from_ptr): Defined to static inline.
	(nano_mallinfo): Implement this function.
	(nano_malloc_stats): Implement this function.
2013-10-30 15:53:05 +00:00
Jeff Johnston 00fd23d50f 2013-09-13 Joey Ye <joey.ye@arm.com>
* libc/stdlib/nano-mallocr.c (nano_allopt): Typo fixed to ...
	(nano_mallopt): ... this.
2013-09-13 16:51:48 +00:00
Corinna Vinschen a83263b981 * configure.in (--enable-newlib-nano-malloc): New option.
* configure: Regenerated.
	* libc/configure.in (--enable-newlib-nano-malloc): New option.
	* libc/configure: Regenerated.
	* libc/stdlib/Makefile.am (NEWLIB_NANO_MALLOC): Use.
	* libc/stdlib/Makefile.in: Regenerated.
	* libc/stdlib/nano-mallocr.c: New file, implementing nano
	version malloc family functions.
2013-05-29 12:37:59 +00:00