Discussion:
Bare-metal: how to specify the heap size in the linker script
Claudio Scordino
2018-08-08 10:05:22 UTC
Permalink
Hi all,

Using the Linaro aarch64 bare-metal toolchain (based on newlib), I need to specify the heap location in the linker script in order to be able of using C++ STL data structures with dynamic-memory (e.g. std::vector).

I've therefore defined the "end" symbol as shown below.

.data : {
*(.data)
}

. = ALIGN(8);
/* "end" is used by newlib's syscalls */
PROVIDE(end = .);

. = ALIGN(16);
stack_bottom = .;
. = ALIGN(4096);
. = . + 0x10000;
stack_top = .;

However, this way there is no way of checking if the heap has reached the maximum value (after which we get stack corruption).

I'd therefore like to know if newlib has some further symbol for specifying the maximum heap size in addition to the heap location.
Alternatively, is there any symbol for specifying the heap boundaries (i.e. beginning and end) ?

Many thanks,

Claudio
Nick Clifton
2018-08-08 10:58:10 UTC
Permalink
Hi Claudio,
Post by Claudio Scordino
However, this way there is no way of checking if the heap has reached the maximum value (after which we get stack corruption).
It sounds like you need to check the current heap top against the
current stack pointer. Take a look in newlib/libgloss/aarch64/syscalls.c
at the implementation of the _sbrk() system call. This uses a magic
asm("sp") statement to get hold of the stack pointer...

Cheers
Nick
Tamar Christina
2018-08-08 11:09:37 UTC
Permalink
Forwarding to list too. Sorry for the dup.
-----Original Message-----
From: Tamar Christina
Sent: Wednesday, August 8, 2018 12:09
Subject: RE: Bare-metal: how to specify the heap size in the linker script
Hi Claudio,
-----Original Message-----
On
Behalf Of Nick Clifton
Sent: Wednesday, August 8, 2018 11:58
Subject: Re: Bare-metal: how to specify the heap size in the linker
script
Hi Claudio,
Post by Claudio Scordino
However, this way there is no way of checking if the heap has
reached the
maximum value (after which we get stack corruption).
It sounds like you need to check the current heap top against the
current stack pointer. Take a look in
newlib/libgloss/aarch64/syscalls.c
at the implementation of the _sbrk() system call. This uses a magic
asm("sp") statement to get hold of the stack pointer...
You didn't say if you're using semihosting or not
If you're using semihosting you can specify the limits in the SYS_HEAPINFO
return values
https://developer.arm.com/docs/100863/latest/semihosting-
operations/sys_heapinfo-0x16
if you're not, then what Nick suggests is the way to go in your _sbrk
implementation.
Regards,
Tamar
Cheers
Nick
Claudio Scordino
2018-08-08 14:10:34 UTC
Permalink
Hi all,

thank you very much. A few comments inline.
Post by Claudio Scordino
-----Original Message-----
From: Tamar Christina
Sent: Wednesday, August 8, 2018 12:09
Subject: RE: Bare-metal: how to specify the heap size in the linker
script
Hi Claudio,
-----Original Message-----
On
Behalf Of Nick Clifton
Sent: Wednesday, August 8, 2018 11:58
Subject: Re: Bare-metal: how to specify the heap size in the linker
script
Hi Claudio,
Post by Claudio Scordino
However, this way there is no way of checking if the heap has
reached the
maximum value (after which we get stack corruption).
It sounds like you need to check the current heap top against the
current stack pointer. Take a look in
newlib/libgloss/aarch64/syscalls.c
at the implementation of the _sbrk() system call. This uses a magic
asm("sp") statement to get hold of the stack pointer...
You didn't say if you're using semihosting or not
If you're using semihosting you can specify the limits in the
SYS_HEAPINFO
return values
https://developer.arm.com/docs/100863/latest/semihosting-
operations/sys_heapinfo-0x16
if you're not, then what Nick suggests is the way to go in your _sbrk
implementation.
We are porting an RTOS (ERIKA Enterprise) on a bare-metal ARM core using
the Jailhouse hypervisor, and we'd like to link some C++ code using STL
stuff.
So, I'd say that we are NOT in the semihosting scenario.

From the link provided by Nick (thanks!) it seems that when using dynamic
allocation (e.g. malloc/new) newlib always checks if the heap is going to
overwrite the current stack.
However, it may happen that the stack then grows further and overwrites the
heap. Did I understood correctly ?

If so, in the linker script we have to reserve enough room for hosting the
maximum value that the sum (stack+heap) can assume, because there is no way
for imposing strong partitioning between these two areas.

Many thanks and best regards,

Claudio
Nick Clifton
2018-08-08 14:14:44 UTC
Permalink
Hi Claudio,
Post by Claudio Scordino
Post by Claudio Scordino
From the link provided by Nick (thanks!) it seems that when using dynamic
allocation (e.g. malloc/new) newlib always checks if the heap is going to
overwrite the current stack.
However, it may happen that the stack then grows further and overwrites the
heap. Did I understood correctly ?
Yes. Although you may be able to turn on stack checking, depending upon what
compiler you are using. If the stack check routines are written correctly
(you may have to do this...) then they can detect stack overflow before it
happens and so abort the program.

Cheers
Nick

Loading...