Until recently I thought that section names generally have to start with a dot .. However, When studying the sample linker file of my bare-metal-C-IDE, I noticed that there seems to be one exception: The section COMMON.
.text :
{
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > ROM
.bss (NOLOAD):
{
*(.bss*)
*(COMMON)
} > RAM
This led me to the conclusion that beginning the section names with . seems to merely be a convention rather than a requirement.
So, my questions are:
What is the reason for starting section names with a dot? I suppose there there was a (perhaps historical?) reason for this convention to be established.
Why was an exception made for COMMON?
Why do usually output sections have the same name as input sections? It was rather confusing for me that there is actually a non-.bss sections included in my .bss output section. Same goes with the .text section. There are plenty of non-.text sections included in my .text output section. Why isn't it common just to give them their own output section? Wouldn't that be much more logical?
Are there any real reasons behind this, or is it just the way it is?
Related
I have some memory gaps in my .srec file after building my code in GHS MULTI. I have tried =fill and FILL() commands but there was no change. Can anyone suggest a solution. I need a solution that can be used in linker script.
Also can anyone give some complete working examples of =fill and FILL() Section attributes.
I have tried as following,
SECTIONS
{
.text CLEAR : FILL(0xFF) >.
or
.text FILL(0xFF) : >.
or
FILL(0xFF)
.text : > .
or
.text = 0xFF : > .
or
.text : > . =0xFF
or
.text : =0xFF > .
}
I have tried all the mentioned scenarios but there was no memory filled at required loaction
and when using clear some memory is getting framented at end address( First it was S315 in .srec but when used CLEAR it became S309)
In an embedded environment i want to convey information about a special part
of memory (start address and length) from the build process to the program
loader. My idea is to let linker create an output section similar to .bss,
i.e. that section should not occupy space in the elf file and should have flags
like the .bss section. I came to this idea since i am already using a customized
linker script.
When processing the elf file, my costumized loader could recognize this section
by a magic name and use the sections size and VMA as the description for the
special part of memory.
When i say it should be similar to .bss, i mean the output of objdump -h
should be similar to this:
Sections:
Idx Name Size VMA LMA File off Algn
...
7 .bss 00000204 10204c9c 10204c9c 00005c40 2**2
ALLOC
...
I guess it is important that here only the flag ALLOC is present, but not LOAD
or CONTENTS.
Can this be achieved with some instructions in the linker script?
If so, what are those instructions?
Browsing through similar questions here at stackoverflow and the ld documentation showed that the solution is quite simple:
.special_start = 0x20000000;
.special_size = 0x10000000;
.special .special_start (NOLOAD) :
{
. = . + .special_size;
}
gives this ouput from objdump -h:
Sections:
Idx Name Size VMA LMA File off Algn
...
6 .sbss 0000005c 10204c40 10204c40 00005c40 2**2
ALLOC, SMALL_DATA
7 .bss 00000204 10204c9c 10204c9c 00005c40 2**2
ALLOC
8 .special 10000000 20000000 20000000 00006000 2**0
ALLOC
...
I'm trying to make a simple operating system kernel higher half. When using Grub as a bootloader as I am, there must also be some lower half (32 bit) code. Because I want to keep this 32 bit code as brief as possible, I do not want to write an ELF loader in it just to load the 64 bit code because that would be patently absurd (this is in fact the most common solution, but I would like to avoid it if possible).
I discovered that linker scripts allow load addresses that differ from virtual addresses. This is useful so that I can load the 64 bit sections to fit in a small binary and then use virtual memory to map the proper virtual addresses to the physical addresses they were loaded at. This works except that the low text section is not put in the text segment. The entry point, _start, is in this section.
I can't put the low text section (where _start resides) in the text segment unless I specify the text segment in a PHDRS command. Of course, using this command makes the linker decide to take a pass on generating the normally expected segments. When I do this too, the sections end up overlapping and I am not entirely sure why. I specify the segments in the order data, rodata, text, and the sections are the same, and yet their load memory addresses are assigned with rodata and data swapped and all three overlapping.
Here is my linker script:
ENTRY(_start)
PHDRS {
.low PT_LOAD FILEHDR PHDRS;
.data PT_LOAD;
.rodata PT_LOAD;
.text PT_LOAD;
}
SECTIONS {
. = 1M;
.data_low BLOCK(4K) : ALIGN(4K) {
*(.bss_low)
} : .low
.rodata_low BLOCK(4K) : ALIGN(4K) {
KEEP(*(.multiboot_low))
*(.rodata_low)
} : .low
.text_low BLOCK(4K) : ALIGN(4K) {
*(.text_low)
} : .low
.stack 0xC0000000 : AT(0x200000) ALIGN(4K) {
*(.bootstrap_stack)
} : .data
_LADD_ = LOADADDR(.stack) + SIZEOF(.stack);
.data BLOCK(4K) : AT(_LADD_) ALIGN(4K) {
*(COMMON)
*(.bss)
} : .data
_LADD_ += SIZEOF(.data);
.rodata BLOCK(4K) : AT(_LADD_) ALIGN(4K) {
*(.rodata)
} : .rodata
_LADD_ += SIZEOF(.rodata);
.text BLOCK(4K) : AT(_LADD_) ALIGN(4K) {
*(.text)
} : .text
}
I do not think the code is relevant to this error. When I link my object files using this linker script (additionally with -n --gc-sections), I get this error:
ld: section .data loaded at [0000000000200020,000000000020103f] overlaps section .rodata loaded at [0000000000200010,00000000002000d0]
ld: section .text loaded at [00000000002000d1,00000000002017ce] overlaps section .data loaded at [0000000000200020,000000000020103f]
The load memory addresses are in the order rodata, data, text, even though I expect they should be in the order data, rodata, text since the sections are specified in that order with AT specifiers with monotonically non decreasing positions (assuming the sections do not have negative size).
I should specify that I am using "segment" to mean one of the entries in the ELF program header (PHDRS in the linker script) and "section" to mean one of the entries in the ELF section header (SECTIONS in the linker script). I believe this to be correct terminology but acknowledge that I have an understanding of linker files and the ELF format that is limited at best. For whatever reason, Grub will not load an ELF file if its entry point is not in a segment.
Why indeed are the sections not in the order I expect them to be in, and how can I make them be? Thank you.
I'm trying to write an executable where the .text section is located in a specific location. I wrote the following linker script:
base_address = 0x123456789AB;
SECTIONS
{
ENTRY(_start)
. = base_address;
.text : { *(.text); }
}
However when I look at the memory mapping of the resulting executable, I see:
12345600000-12345679000 r-xp 00000000 08:01 1 /path/to/executable
It is obvious why the section would be aligned to 0x1000, that's page size, but where does 0x100000 come from?
Now the interesting part is that this only happens when I disable build ids with -Wl,--build-id=none, or when I enable them and try to stuff the .note.gnu.build-id section right after .text.
Have a look at the generated map file. It's possible that some of your input .text sections also have their own alignment requirements.
Using gcc arm-none-eabi 4_8 compiler, I'm getting a problem with my binary after linking. No errors but when I bring it up in debugger I never reach main. Tracing it through it appears the linker is not adding the epilog to the .init section for crt. This causes my code to run past .init into .rodata section and hitting hard fault on undefined instruction.
I'm stumped trying to figure out why this piece of code has this issue when very similar code using the same makefile doesn't. I know this is a broad question but what would be some reasons why the linker is not creating a good .init section?
Bad .map:
*(.init)
.init 0x00001cec 0x4 /usr/local/.../gcc/linux/4_8-2013q4/bin/../lib/gcc/arm-none-eabi/4.8.3/armv6-m/crti.o
0x00001cec _init
*(.fini)
.fini 0x00001cf0 0x4 /usr/local/.../gcc/linux/4_8-2013q4/bin/../lib/gcc/arm-none-eabi/4.8.3/armv6-m/crti.o
0x00001cf0 _fini
Good .map:
*(.init)
.init 0x00015c48 0x4 /usr/local/.../gcc/linux/4_6-2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/armv6-m/crti.o
0x00015c48 _init
.init 0x00015c4c 0x8 /usr/local/.../gcc/linux/4_6-2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/armv6-m/crtn.o
*(.fini)
.fini 0x00015c54 0x4 /usr/local/.../gcc/linux/4_6-2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/armv6-m/crti.o
0x00015c54 _fini
.fini 0x00015c58 0x8 /usr/local/.../gcc/linux/4_6-2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/armv6-m/crtn.o
Turns out the issue is an out of date linker command file.
Was missing:
KEEP(*(.init))
KEEP(*(.fini))