define a program section in C code (GCC) - 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.

Related

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.

What's the pass in GCC handles const strings?

What's the pass name in GCC that handles building string array into .rodata section? Would like to write a plugin to intercept also strings in source code, I know there're a bunch of tools in binutils can achieve the same goal, but what if we want to do some postprocessing, for example verify words.
Read-only data section, also known as .rodata, generates after the last step of all rtl passes. You can see how it works in file varasm.c, which lays in /gcc folder. Look at section
section *
default_function_rodata_section (tree decl)
and below.
You can also easily add some functions to intercept data into asm file or some other output file here or write an external function.
varasm.c file handles the generation of all the assembler code
except the instructions of a function.
This includes declarations of variables and their initial values.

C code Optimization by compiler for atmel studio

I am using Atmel Studio 7 and in that, optimization level is -O1.
Can I check what portion of code is being optimized by the compiler itself?
If I am disabling the optimization, my binary file size is of 12KB and on using optimization level -O1, binary file size if 5.5KB.
Can I check what portion of code is being optimized by the compiler itself?
All the code is optimized by the compiler, i.e affected by optimization flags except
It's code that's dragged from libraries (libgcc.a, libc.a, libm.a, lib<device>.a).
Startup code (crt<device>.o) which also includes the vector table, or code from other objects that already exist and are not (re-)compiled in the current compilation. The latter can happen with Makefiles when you change flags therein: If the modules do not depend on the Makefile itself, make will not rebuild them.
Code from assembly modules (*.S, *.sx, *.s) provided preprocessed assembly code does not use conditional assemblation by means of #ifdef __OPTIMIZE__ or similar.
Code in inline assembly, provided the inline asm is not optimized away.
In order to determine whether anything of this is in effect, you can respectively:
Link with -Wl,-Map,file.map and inspect that map file (a text file). It will list which objects have been dragged from where due to which undefined symbol.
Startup code is linked except you -nostartfiles. Add -Wl,-v to the link stage, you'll see crt<device>.o being linked.
You know your compilation units, assembly modules, don't you?
Add -save-temps to the compilation. Inline asm will show in the intermediate *.s file as
/* #APP */
; <line> "<compilation-unit>"
<inline-asm-code>
/* #NOAPP */

GCC custom section length definition, out of range control

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

ELF modify section flags

I compiled a C code using gcc and when I check the sections of the ELF using readelf I can see that the flags for .data section are set to WA (Writable and Allocatable).
Is it possible to modify these flags? Can I make this section executable?
I am using gdb to debug this binary and I would like to set the flags for .data section as Executable at a certain point. So, can this be done using either gdb or gcc?
Is it possible to modify these flags? Can I make this section executable?
Yes. If you want to do this as a one-off, the simplest approach may be to compile source to assembly, and modify section attributes there, then compile assembly into object file and link as usual.
I am using gdb to debug this binary and I would like to set the flags for .data section as Executable at a certain point.
You also could call mprotect(addr, len, PROT_READ|PROT_WRITE|PROT_EXEC) from within GDB.
Note: modifying the flags in the .data section after the binary has been linked will have no effect whatsoever: the kernel doesn't look at sections, only at PT_LOAD segments.
how to mark the data section as executable in the assembly code? I think, something like this: .section .data,"awx",#progbits.
Yes, that looks correct. Did it not work?
mprotect() not found
Is your executable statically linked? If not, mprotect should be found (in libc.so), and you possibly have a GDB bug. It may help to nudge GDB into finding mprotect if you print &mprotect first.
Also note: mprotect(0x0804a020, 80, PROT_READ, PROT_WRITE, PROT_EXEC) is very different from what I suggested (mprotect takes 3 parameters, not 5). You also need to read man mprotect carefully -- it requires start address to be page-aligned.

Resources