GCC custom section length definition, out of range control - gcc

I'm using GCC for and specific MCU target (to be accurate for AVR) I have a special external memory that I try to define a custom Section by using following command in linker options
-Wl,--section-start=.customsection=0x821000
and then using attribute inside the code just like this:
unsigned char X __attribute__((section (".customsection")));
everything is correct and works fine. But how can I define some limitation to this custom section that force the GCC linker to raise an error in case of overrun? By limitation I mean a way to define length of the section or end-address.

AFAIK, you can only specify the length in a linker file.
You would have to copy the linker file for your MCU and modify it.
For more information and examples see:
- https://www.avrfreaks.net/forum/create-new-section-ram
- https://www.avrfreaks.net/forum/custom-linker-script-atmega

Related

GCC Linker Script Ignore PHDR / PHDRS?

I'm trying to target a flat file for the output of my code, where I don't want PHDR. But it seems no matter how I set things up, in modern GCC versions, I can't avoid PHDR.
Either I get PHDR segment not covered by LOAD segment or if I define a PHDRS property as in my linker script as follows:
PHDRS
{
header PT_NULL FILEHDR;
text PT_NULL PHDRS;
data PT_NULL FILEHDR;
}
but throw it out, I get the error no sections assigned to phdrs
I can't seem to find any way to force GCC to just trust me and not emit the PHDRs. What can I put in my linker script to tell GCC that I really mean it.
EDIT
I found this: https://sourceware.org/bugzilla/show_bug.cgi?id=25585
If I add the following to my GCC invocation, it seems to output the binary anyway: -Wl,--noinhibit-exec
But, it now includes extra header data in the middle of the binary image.
If you want to generate a flat binary file, then you could just specify the output format to be “binary”.
Not sure it’s what you want
A long time a ago, when I was looking into bootloaders, I was generating the MBR using exactly that.
I found a solution!
Either have an empty PHDRS {...} definition at the top (or it seems maybe you don't need it).
Then, in your sections, be sure to discard phdr and contain all the troublesome sections.
/* If we're on a newer compiler */
/DISCARD/: {
*(.interp)
*(.dynsym)
*(.dynstr)
*(.hash)
*(.gnu.hash)
*(.header)
} : phdr

GCC __attribute__((used)) vs. linker file KEEP statement?

Using "Gnu Arm Embedded Toolchain", it seems that I need to have both this statement in my .c file:
__attribute__ ((section("section_name"),used))
and this statement in my .ld file:
KEEP(sectionname)
in order for that particular section to not get removed by linker garbage collection (--gc-sections).
Can anyone explain why or guide me to some documentation mentioning this?
Both compiler and linker may remove functions which they consider to be unused (which usually means not reachable from main) so to preserve a function you need to inform both of the tools.
In theory compiler could automatically generate KEEP statements based on used attributes but this isn't done for historical reasons.

__attribute__((io)), __attribute__((address)) in gcc for AVR don't seem to have any effect

I am trying to use variable attributes specifically provided by AVR flavor of gcc (https://gcc.gnu.org/onlinedocs/gcc/AVR-Variable-Attributes.html#AVR-Variable-Attributes).
The manual says that these special attributes should allow me to force the placement of a variable at the predetermined memory address. They even give an example:
volatile int porta __attribute__((address (0x600)));
But when I compile and debug this code example from the above mentioned document, the variable declared with such attribute is placed into a location in SRAM that compiler and linker determine, not at the address 0x600, as requested. Actually, if I remove the attribute entirely from the declaration, the end result does not change - the variable is placed at the same "whatever" address. Same thing happens when I use "io" and "io_low" attributes instead of "address".
I am using gcc toolchain packaged in the latest version Atmel Studio 7.0.19.31 targeted at 8-bit MCUs (ATMega64).
Hence the question: has anyone tried to use these special AVR-specific attributes with any success?
Important notes:
I am aware that in general to accomplish a placement of a variable at a fixed address in gcc you need to follow a two-step process (using section attribute and then modifying the linker script), but specificially for AVR it seems like these single-step attributes were provided, the question is how to make them work. A two-step process is not an option for me.
I am aware that in general one can always do this:
*(volatile int*)0x600 = your_data_here;
But this is not an option for me either, I need an actual variable declared (because I want to map it onto a bitwise structure to have access to individual bits without explicitly using the masks and logical operations.
So I am really looking for a way to make the provided attributes work, not for a workaround. What am I missing?
typedef struct {
uint8_t rx:4;
uint8_t tx:4;
} Pio_TXRXMUX_t;
#define Pio_TXRXMUX (*(volatile Pio_TXRXMUX_t *)(0x22)) //PORTA on ATMEGA1280

Do I have to include some header files in order to use GCC built_in function?

The motivation is that I want to tell the compiler that my float *U array is 64 bytes aligned so that the compiler can do the vectorizations.
If using Intel compiler, I can use the __assume_aligned(U,64);I googled and found that if I want to do the same thing using GCC, I have to define another float *U_tmp=__builtin_assume_aligned(U,64), and use U_tmp. However, when it goes to compilation with GCC, the compiler reports that
"error: ‘__builtin_assume_aligned’ was not declared in this scope"
I don't know if I have missed some libraries or header files containing this GCC built in function.
This is supposed to work out of the box, without any additional headers. However, this has been added only to GCC 4.7, maybe your compiler is older than that?

define a program section in C code (GCC)

In assembly language, it's easy to define a section like:
.section foo
How can this be done in C code? I want to put a piece of C code in a special section rather than .text, so I will be able to put that section in a special location in the linker script.
I'm using GCC.
The C standard doesn't say anything about "sections" in the sense that you mean, so you'll need to use extensions specific to your compiler.
With GCC, you will want to use the section attribute:
extern void foobar(void) __attribute__((section("bar")));
There is some limited documentation here, including a warning:
Some file formats do not support
arbitrary sections so the section
attribute is not available on all
platforms. If you need to map the
entire contents of a module to a
particular section, consider using the
facilities of the linker instead.

Resources