given:
SECTIONS
{
.text:
{
*(.text.start)
*(.text)
*(.text.*)
*(.text.end)
}
}
Is it possible to make gcc raise a link error if symbols text.start and text.end are not defined?
there is KEEP(*(.text.start)) but it just keeps the section empty if not found...
Related
How can I remove a section from ELF during linking stage? Is there any linker option or flag for this? I'm mostly interested on how it can be done with LLVM, but any information about GCC will be appreciated as well.
Thanks!
If you want anything different from the default ELF construction--copy everything--then you will need to write a linker script. files can specify what to include and where to put it. So you would remove this section by not copying it. LLD supports GNU LD style linker scripts. They will look something like:
SECTIONS
{
. = 0x10000;
.text : { *(.text) }
. = 0x8000000;
.data : { *(.data) }
.bss : { *(.bss) }
}
They are specified on the lld command line with something like:
ld.lld --script=../linker_script xxx.o -o xxx
this is the problem:
When I link my scripts in C, using ld, when I generate elf32-i386 files as output format in ld, putting it as OUTPUT_FORMAT() in the ld script, I dont have any error, but if I try to put in this last OUTPUT_FORMAT() "binary" or try to output a file with .bin extension, I get a mixture of errors like:
kernel.o: In function `k_main':
kernel.c:(.text+0xe): undefined reference to `_GLOBAL_OFFSET_TABLE_'
kernelutils.o: In function `k_clear_screen':
kernelutils.c:(.text+0xc): undefined reference to `_GLOBAL_OFFSET_TABLE_'
kernelutils.o: In function `k_clear_screen_front':
kernelutils.c:(.text+0x56): undefined reference to `_GLOBAL_OFFSET_TABLE_'
kernelutils.o: In function `k_printf':
kernelutils.c:(.text+0xa0): undefined reference to `_GLOBAL_OFFSET_TABLE_'
kernelutils.o: In function `k_sleep_3sec':
kernelutils.c:(.text+0x152): undefined reference to `_GLOBAL_OFFSET_TABLE_'
kernelmalloc.o:kernelmalloc.c:(.text+0xc): more undefined references to `_GLOBAL_OFFSET_TABLE_' follow
This not only happens when compiling specific scripts, all scripts that try to use ld to link, or gcc since this calls ld, die in the attempt of get a binary with .bin extension.
When showing the symbols of one of the executables (kernel.o in the output of above) I see that the symbol _GLOBAL_OFFSET_TABLE_ isnt defined, and the most scary part, all the functions that returned error in the error output of above have their symbols removed, this is the nm output:
cristian#mymethodman:~/Desktop/kernel/0.0.3/Archivos$ nm kernel.o
U _GLOBAL_OFFSET_TABLE_
U k_clear_screen
U k_clear_screen_front
00000000 T k_main
U k_malloc
U k_printf
U k_sleep_3sec
00000000 T __x86.get_pc_thunk.bx
How I can solve this? I will leave the linker script below to ensure it isn a problem of the .ld file, with both "to get elf" and "to get binary" versions. Thanks in advance!
Ld scripts:
To get binary:
ENTRY(loader)
OUTPUT_FORMAT(binary)
SECTIONS {
/* The kernel will live at 3GB + 1MB in the virtual
address space, which will be mapped to 1MB in the
physical address space. */
. = 0xC0100000;
.text : AT(ADDR(.text) - 0xC0000000) {
*(.text)
*(.rodata*)
}
.data ALIGN (0x1000) : AT(ADDR(.data) - 0xC0000000) {
*(.data)
}
.bss : AT(ADDR(.bss) - 0xC0000000) {
_sbss = .;
*(COMMON)
*(.bss)
_ebss = .;
}
}
To get ELF:
ENTRY(loader)
OUTPUT_FORMAT(elf32-i386)
SECTIONS {
/* The kernel will live at 3GB + 1MB in the virtual
address space, which will be mapped to 1MB in the
physical address space. */
. = 0xC0100000;
.text : AT(ADDR(.text) - 0xC0000000) {
*(.text)
*(.rodata*)
}
.data ALIGN (0x1000) : AT(ADDR(.data) - 0xC0000000) {
*(.data)
}
.bss : AT(ADDR(.bss) - 0xC0000000) {
_sbss = .;
*(COMMON)
*(.bss)
_ebss = .;
}
}
As yo ucan see between both only changes the OUTPUT_FORMAT() line.
Your toolchain probably defaults to generating position-independent executables (PIE). Try compiling with gcc -fno-pie.
If you want to keep PIE for security reasons, you'll need a more complicated linker script and something that performs the initial relocation (such as a dynamic linker, but simpler constructions are possible as well).
This is related to GNU linker.If I have a section which is other than .text , .data or .bss how do I tell linker not to include that section in any of those segments.
Ex:
SECTIONS {
.text {}
.data {}
.bss {}
.sec_var {}
}
Actually in my case sec_var has some global variable I dont want it to be part of data segment but by default linker has this concept of orphan section so it tries to put that section in .data. Due to this the final binary size is grown the same .
I read in the GCC linker :
You can use :NONE to tell the linker to not put the section in any segment at all.
Anybody has used it or has any other method so that , sec_var is not placed under .data section ?
something like this,
MEMORY
{
bob : ORIGIN = 0x8000, LENGTH = 0x1000
ted : ORIGIN = 0xA000, LENGTH = 0x1000
}
SECTIONS
{
.text : { *(.text*) } > bob
.rodata : { *(.rodata*) } > bob
.bss : { *(.bss*) } > ted
}
I assume you dont really mean that you want .rodata in .text actually but perhaps you want .text and .rodata to be in the same chunk of memory space together...
I've just started learning some ARM programming and I've got stuck in a slightly annoying problem. The toolchain I'm using to compile my sources is Sourcery CodeBench Lite 2013.05-23 (can be found here: https://sourcery.mentor.com/GNUToolchain/release2449)
What I would need is to tell GCC or LD or OBJCOPY to put the compiled bytecode of the 'main' function at the beginning of the .text section.
Is there any way to achieve this? (maybe through a linker script?)
Thank you
Solved the problem. For whoever faces it:
When compiling with GCC, add the -ffunction-sections option in the command-line. This will tell GCC to put each function in a separate section. The format of the section name will be .text.#function name#, without the # (that is, if the function belongs to the .text section [ which by default is true ]).
Secondly, use a linker script to order these "function-sections" into the final big .text section. As an example, putting the main function at the beginning of the .text section would result in an LD script that looks approximately like this:
ENTRY(main)
SECTIONS
{
.text :
{
*(.text.main);
*(.text*);
}
}
First, see how is the .text section defined in your gcc's default linker script (so you don't have to make your own), by calling it as:
gcc -Wl,-verbose
that will print out the default linker script. Mine shows this for the .text section:
/* text: Program code section */
.text :
{
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
}
So in order to have the "main" function be the first in the .text section (and the rest be contiguous), you have to set the "section" attribute for all other functions. For example:
void main(void);
void funct1(....) __attribute__ ((section (".text.A")));
void funct2(....) __attribute__ ((section (".text.A")));
void funct3(....) __attribute__ ((section (".text.A")));
It's enough with "attributing" the function prototypes. That way, when you compile now, the "main" function will be the first one in the ".text" section and all others will follow on the immediately consecutive addresses.
If you want to place the ".text" section (i.e. "main" function) at a specific address (for example 0x1000), remember to link with:
gcc .... -Wl,-Ttext=0x1000
You can also just put 'main' in its own section using an __attribute__:
int main (void) __attribute__ ((section ("entry")));
and then in the ld file:
ENTRY(main)
SECTIONS
{
.text :
{
*(main)
*(.text)
}
}
There are plenty of other interesting __attributes__, read more about them here: http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
I'm trying to switch to the GNU GCC compiler for our embedded system, but I'm having trouble linking the project as the memory layout of our chip is split:
RAM section 1: 0x10000-0x12FFF
RAM section 2: 0x18000-0x1BFFF
The data from our project can fit in section 1, but the data linked from the gcc libs doesn't. Map file extract:
.data 0x00012974 0x3c4 c:/tools/gnucr16_v1.1.3-elf/cr16-elf/bin/../lib/gcc/cr16-elf/4.5.1-GNUCR16_v1.1.3/../../../../cr16-elf/lib\libc.a(lib_a-impure.o)
0x00012974 _impure_ptr
.data 0x00012d7c 0x410 c:/tools/gnucr16_v1.1.3-elf/cr16-elf/bin/../lib/gcc/cr16-elf/4.5.1-GNUCR16_v1.1.3/../../../../cr16-elf/lib\libc.a(lib_a-mallocr.o)
0x00012d7c __malloc_av_
0x00013184 __malloc_trim_threshold
0x00013188 __malloc_sbrk_base
Is it possible to put the .data section from the libs in the 2nd section? I've tried different thing without success... Linker script extract:
MEMORY
{
SHARED1 : org = 0x10000, len = 0x3000
SHARED2 : org = 0x18000, len = 0x4000
}
SECTIONS
{
.data 0x12004 : { *(.data); } >SHARED1
.data2 0x19000 : { libc*(.data); } >SHARED2
}
SECTIONS
{
.section_name:
{
*lib_a-impure.o (.data); //That is the syntax to access sections of object files
} >SHARED1
}
More info here: http://www.embedded.com/design/mcus-processors-and-socs/4026080/Building-Bare-Metal-ARM-Systems-with-GNU-Part-3