Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

It is possible to get linker script symbols addresses as compile time constant values in C code?

I want to get the address of the end of my program and check at compilation/linker time if I have enough space, after the code, to place some random data in execution time.

But as the symbols provided by PROVIDE keyword are like normal variables in C code, I can not verify it in compilation time.

In the linker script I have the symbol :

PROVIDE (__data_end_rom   = _etext + SIZEOF (.data));

So I can use this symbol to get the address of the end of my code :

extern u16 __data_end_rom;

I can calculate the available memory if I suppose the end address to be 0xffff:

#define AVAILABLE_MEM (0Xffff - &__data_end_rom)

And I was thinking to check the available memory with _Static_assert(cond, message) provided in gcc 4.6

_Static_assert(SIZE_I_WANT_TO_ASSURE <= AVAILABLE_MEM, "NOT ENOUGH MEMORY!!!");

My problem is : The macro AVAILABLE_MEM is not calculated at compilation time, so I get the error:

error: expression in static assertion is not constant

Is there any way to provide the __data_end_rom address directly in a label or in another way ?

I know that I can't get it in compilation time because the symbol will just be linked in the linker time, so there is some way to make the linker fails ?

I could check this directly in the linker script but I prefer not doing so because the SIZE_I_WANT_TO_ASSURE is another macro calculated from others macros in a configuration header.

like image 812
Lilás Avatar asked May 30 '13 11:05

Lilás


People also ask

What is linker script in C?

A linker script is a file that tells the linker which sections to include in the output file, as well as which order to put them in, what type of file is to be produced, and what is to be the address of the first instruction.

What is the role of linker in script file?

The main purpose of the linker script is to describe how the sections in the input files should be mapped into the output file, and to control the memory layout of the output file.

What is a linker command?

Linker command files allow you to put linker options and directives in a file; this is useful when you invoke the linker often with the same options and directives. Linker command files are also useful because they allow you to use the MEMORY and SECTIONS directives to customize your application.

What is a linker script embedded?

The linker script makes a memory map of this memory allocation which is important to embedded systems because, having no OS, you have the ability then to manage the behavior of the chip. For G++, sets up the constructor and destructor tables. The actual section names vary depending on your object file format.


3 Answers

_Static_assert(SIZE_I_WANT_TO_ASSURE <= AVAILABLE_MEM, "NOT ENOUGH MEMORY!!!");

error: expression in static assertion is not constant

The problem here is that you are trying to compare a "constant" generated during the linking phase of the build, in an expression that requires a compile time constant (that is, something the COMPILER knows during compilation).

#define AVAILABLE_MEM (0Xffff - &__data_end_rom)

The compiler won't know the address of __data_end_rom, only the linker knows that.

Unfortunately, I don't think there is any way to do this at compile time, make the compiler tell you the data is too large. On the other hand, an additional script reading the binary file (e.g. using size yourprog in conjunction with a little bit of awk or something) should be able to provide the relevant information in the makefile or something similar.

like image 95
Mats Petersson Avatar answered Oct 19 '22 14:10

Mats Petersson


You can do it in the link script itself, something like this:

/* minimum amount of data required at end of .text */
_Min_Data_Left 0Xffff;

.text : 
{
... all the usual stuff ...
PROVIDE (__data_end_rom  = . );
. = . + _Min_Data_Left;
. = ALIGN(4);
} >FLASH

The linker will now tell you that FLASH has overflowed if you go over the limit - and compilation will fail, which I understand is what you want.

It's a commonly used method to ensure a minimum amount of stack and heap is available. Here's one version - look for _Min_Heap_Size and _Min_Stack_Size: https://github.com/pingdynasty/OwlWare/blob/master/Source/flash.ld

Out of curiosity, what will you do with the extra space in .text - I'm assuming this is in Flash?

like image 22
Martin Klang Avatar answered Oct 19 '22 16:10

Martin Klang


You can create a custom linker script that has assertions in it. see here

http://sourceware.org/binutils/docs/ld/Miscellaneous-Commands.html

you want to use the 'ASSERT' mechanism.

like image 21
John Meacham Avatar answered Oct 19 '22 15:10

John Meacham