Skip to content

Commit

Permalink
Merge pull request #1782 from benpicco/fix_malloc
Browse files Browse the repository at this point in the history
check if the requested memory is really available in _sbrk_r
  • Loading branch information
benpicco committed Nov 5, 2014
2 parents 8ab6e69 + 39d73d7 commit cedc588
Show file tree
Hide file tree
Showing 18 changed files with 222 additions and 69 deletions.
4 changes: 3 additions & 1 deletion cpu/cc2538/cc2538_linkerscript.ld
Expand Up @@ -130,8 +130,10 @@ SECTIONS
_estack = .;
} > ram

/* heap section */
. = ALIGN(4);
_end = . ;
_sheap = . ;
_eheap = ORIGIN(ram) + LENGTH(ram);

.flashcca :
{
Expand Down
37 changes: 16 additions & 21 deletions cpu/cc2538/syscalls.c
Expand Up @@ -39,18 +39,12 @@
#ifdef MODULE_UART0
#include "board_uart0.h"
#endif

#ifdef CPU_MODEL_CC2538NF11
#define SRAM_LENGTH (16 * 1024) /**< The CC2538NF11 has 16 Kb of RAM */
#else
#define SRAM_LENGTH (32 * 1024) /**< All other existing models of the CC2538 have 32 Kb of RAM */
#endif

/**
* manage the heap
*/
extern uint32_t _end; /* address of last used memory cell */
caddr_t heap_top = (caddr_t) &_end + 4;
extern char _sheap; /* start of the heap */
extern char _eheap; /* end of the heap */
caddr_t heap_top = (caddr_t)&_sheap + 4;

#ifndef MODULE_UART0
/**
Expand Down Expand Up @@ -120,25 +114,26 @@ void _exit(int n)
* @brief Allocate memory from the heap.
*
* The current heap implementation is very rudimentary, it is only able to allocate
* memory. It does not have any means to free memory again.
* memory. But it does not
* - have any means to free memory again
*
* @return a pointer to the successfully allocated memory
* @return -1 on error, and errno is set to ENOMEM
* @return [description]
*/
caddr_t _sbrk_r(struct _reent *r, size_t incr)
caddr_t _sbrk_r(struct _reent *r, ptrdiff_t incr)
{
unsigned int state = disableIRQ();
if ((uintptr_t)heap_top + incr > SRAM_BASE + SRAM_LENGTH) {
restoreIRQ(state);
caddr_t res = heap_top;

if (((incr > 0) && ((heap_top + incr > &_eheap) || (heap_top + incr < res))) ||
((incr < 0) && ((heap_top + incr < &_sheap) || (heap_top + incr > res)))) {
r->_errno = ENOMEM;
return (caddr_t)-1;
}
else {
caddr_t res = heap_top;
res = (void *) -1;
} else {
heap_top += incr;
restoreIRQ(state);
return res;
}

restoreIRQ(state);
return res;
}

/**
Expand Down
4 changes: 3 additions & 1 deletion cpu/nrf51822/nrf51822qfaa_linkerscript.ld
Expand Up @@ -138,6 +138,8 @@ SECTIONS
_estack = .;
} > ram

/* heap section */
. = ALIGN(4);
_end = . ;
_sheap = . ;
_eheap = ORIGIN(ram) + LENGTH(ram);
}
19 changes: 13 additions & 6 deletions cpu/nrf51822/syscalls.c
Expand Up @@ -41,8 +41,9 @@
/**
* manage the heap
*/
extern uint32_t _end; /* address of last used memory cell */
caddr_t heap_top = (caddr_t)&_end + 4;
extern char _sheap; /* start of the heap */
extern char _eheap; /* end of the heap */
caddr_t heap_top = (caddr_t)&_sheap + 4;

/**
* @brief use mutex for waiting on incoming UART chars
Expand Down Expand Up @@ -111,18 +112,24 @@ void _exit(int n)
*
* The current heap implementation is very rudimentary, it is only able to allocate
* memory. But it does not
* - check if the returned address is valid (no check if the memory very exists)
* - have any means to free memory again
*
* TODO: check if the requested memory is really available
*
* @return [description]
*/
caddr_t _sbrk_r(struct _reent *r, ptrdiff_t incr)
{
unsigned int state = disableIRQ();
caddr_t res = heap_top;
heap_top += incr;

if (((incr > 0) && ((heap_top + incr > &_eheap) || (heap_top + incr < res))) ||
((incr < 0) && ((heap_top + incr < &_sheap) || (heap_top + incr > res)))) {
r->_errno = ENOMEM;
res = (void *) -1;
}
else {
heap_top += incr;
}

restoreIRQ(state);
return res;
}
Expand Down
6 changes: 4 additions & 2 deletions cpu/sam3x8e/sam3x8e_linkerscript.ld
Expand Up @@ -139,6 +139,8 @@ SECTIONS
_estack = .;
} > ram

/* heap section */
. = ALIGN(4);
_end = . ;
}
_sheap = . ;
_eheap = ORIGIN(ram) + LENGTH(ram);
}
21 changes: 13 additions & 8 deletions cpu/sam3x8e/syscalls.c
Expand Up @@ -37,10 +37,9 @@
/**
* manage the heap
*/
extern uint32_t _end; /* address of last used memory cell */
caddr_t heap_top = (caddr_t)&_end + 4;


extern char _sheap; /* start of the heap */
extern char _eheap; /* end of the heap */
caddr_t heap_top = (caddr_t)&_sheap + 4;
/**
* @brief Initialize NewLib, called by __libc_init_array() from the startup script
*/
Expand Down Expand Up @@ -77,18 +76,24 @@ void _exit(int n)
*
* The current heap implementation is very rudimentary, it is only able to allocate
* memory. But it does not
* - check if the returned address is valid (no check if the memory very exists)
* - have any means to free memory again
*
* TODO: check if the requested memory is really available
*
* @return [description]
*/
caddr_t _sbrk_r(struct _reent *r, ptrdiff_t incr)
{
unsigned int state = disableIRQ();
caddr_t res = heap_top;
heap_top += incr;

if (((incr > 0) && ((heap_top + incr > &_eheap) || (heap_top + incr < res))) ||
((incr < 0) && ((heap_top + incr < &_sheap) || (heap_top + incr > res)))) {
r->_errno = ENOMEM;
res = (void *) -1;
}
else {
heap_top += incr;
}

restoreIRQ(state);
return res;
}
Expand Down
4 changes: 3 additions & 1 deletion cpu/stm32f0/stm32f051r8_linkerscript.ld
Expand Up @@ -137,6 +137,8 @@ SECTIONS
_estack = .;
} > ram

/* heap section */
. = ALIGN(4);
_end = . ;
_sheap = . ;
_eheap = ORIGIN(ram) + LENGTH(ram);
}
19 changes: 13 additions & 6 deletions cpu/stm32f0/syscalls.c
Expand Up @@ -43,8 +43,9 @@
/**
* manage the heap
*/
extern uint32_t _end; /* address of last used memory cell */
caddr_t heap_top = (caddr_t)&_end + 4;
extern char _sheap; /* start of the heap */
extern char _eheap; /* end of the heap */
caddr_t heap_top = (caddr_t)&_sheap + 4;

#ifndef MODULE_UART0
/**
Expand Down Expand Up @@ -114,18 +115,24 @@ void _exit(int n)
*
* The current heap implementation is very rudimentary, it is only able to allocate
* memory. But it does not
* - check if the returned address is valid (no check if the memory very exists)
* - have any means to free memory again
*
* TODO: check if the requested memory is really available
*
* @return [description]
*/
caddr_t _sbrk_r(struct _reent *r, ptrdiff_t incr)
{
unsigned int state = disableIRQ();
caddr_t res = heap_top;
heap_top += incr;

if (((incr > 0) && ((heap_top + incr > &_eheap) || (heap_top + incr < res))) ||
((incr < 0) && ((heap_top + incr < &_sheap) || (heap_top + incr > res)))) {
r->_errno = ENOMEM;
res = (void *) -1;
}
else {
heap_top += incr;
}

restoreIRQ(state);
return res;
}
Expand Down
4 changes: 3 additions & 1 deletion cpu/stm32f1/stm32f103cb_linkerscript.ld
Expand Up @@ -137,6 +137,8 @@ SECTIONS
_estack = .;
} > ram

/* heap section */
. = ALIGN(4);
_end = . ;
_sheap = . ;
_eheap = ORIGIN(ram) + LENGTH(ram);
}
4 changes: 3 additions & 1 deletion cpu/stm32f1/stm32f103re_linkerscript.ld
Expand Up @@ -137,6 +137,8 @@ SECTIONS
_estack = .;
} > ram

/* heap section */
. = ALIGN(4);
_end = . ;
_sheap = . ;
_eheap = ORIGIN(ram) + LENGTH(ram);
}
19 changes: 13 additions & 6 deletions cpu/stm32f1/syscalls.c
Expand Up @@ -43,8 +43,9 @@
/**
* manage the heap
*/
extern uint32_t _end; /* address of last used memory cell */
caddr_t heap_top = (caddr_t)&_end + 4;
extern char _sheap; /* start of the heap */
extern char _eheap; /* end of the heap */
caddr_t heap_top = (caddr_t)&_sheap + 4;

#ifndef MODULE_UART0
/**
Expand Down Expand Up @@ -114,18 +115,24 @@ void _exit(int n)
*
* The current heap implementation is very rudimentary, it is only able to allocate
* memory. But it does not
* - check if the returned address is valid (no check if the memory very exists)
* - have any means to free memory again
*
* TODO: check if the requested memory is really available
*
* @return [description]
*/
caddr_t _sbrk_r(struct _reent *r, ptrdiff_t incr)
{
unsigned int state = disableIRQ();
caddr_t res = heap_top;
heap_top += incr;

if (((incr > 0) && ((heap_top + incr > &_eheap) || (heap_top + incr < res))) ||
((incr < 0) && ((heap_top + incr < &_sheap) || (heap_top + incr > res)))) {
r->_errno = ENOMEM;
res = (void *) -1;
}
else {
heap_top += incr;
}

restoreIRQ(state);
return res;
}
Expand Down
4 changes: 3 additions & 1 deletion cpu/stm32f3/stm32f303vc_linkerscript.ld
Expand Up @@ -138,6 +138,8 @@ SECTIONS
_estack = .;
} > ram

/* heap section */
. = ALIGN(4);
_end = . ;
_sheap = . ;
_eheap = ORIGIN(ram) + LENGTH(ram);
}
19 changes: 13 additions & 6 deletions cpu/stm32f3/syscalls.c
Expand Up @@ -44,8 +44,9 @@
/**
* @brief manage the heap
*/
extern uint32_t _end; /* address of last used memory cell */
caddr_t heap_top = (caddr_t)&_end + 4;
extern char _sheap; /* start of the heap */
extern char _eheap; /* end of the heap */
caddr_t heap_top = (caddr_t)&_sheap + 4;

#ifndef MODULE_UART0
/**
Expand Down Expand Up @@ -114,18 +115,24 @@ void _exit(int n)
*
* The current heap implementation is very rudimentary, it is only able to allocate
* memory. But it does not
* - check if the returned address is valid (no check if the memory very exists)
* - have any means to free memory again
*
* TODO: check if the requested memory is really available
*
* @return [description]
*/
caddr_t _sbrk_r(struct _reent *r, ptrdiff_t incr)
{
unsigned int state = disableIRQ();
caddr_t res = heap_top;
heap_top += incr;

if (((incr > 0) && ((heap_top + incr > &_eheap) || (heap_top + incr < res))) ||
((incr < 0) && ((heap_top + incr < &_sheap) || (heap_top + incr > res)))) {
r->_errno = ENOMEM;
res = (void *) -1;
}
else {
heap_top += incr;
}

restoreIRQ(state);
return res;
}
Expand Down
4 changes: 3 additions & 1 deletion cpu/stm32f4/stm32f407vg_linkerscript.ld
Expand Up @@ -139,6 +139,8 @@ SECTIONS
_estack = .;
} > ram

/* heap section */
. = ALIGN(4);
_end = . ;
_sheap = . ;
_eheap = ORIGIN(ram) + LENGTH(ram);
}
4 changes: 3 additions & 1 deletion cpu/stm32f4/stm32f415rg_linkerscript.ld
Expand Up @@ -139,6 +139,8 @@ SECTIONS
_estack = .;
} > ram

/* heap section */
. = ALIGN(4);
_end = . ;
_sheap = . ;
_eheap = ORIGIN(ram) + LENGTH(ram);
}

0 comments on commit cedc588

Please sign in to comment.