I have a requirement where I need to create a duplicate/copy section of .data section.
I've tried creating a dummy section with same size of data section in linker script and copy the contents of data section to the dummy section in the init functions of my ELF image, but that doesn't suit my requirement, as I want the copy/duplicate section to be created along with final ELF image not during the execution of it.
Below is what I wanted in my linker script,
SECTIONS {
.data : { <data section contents> }
.dummydata : { <copy of .data section> }
}
Can anyone help to write the linker script to match above requirement?
I don't think this can be done with just ld and a linker script. Given this line from here:
If a file name matches more than one wildcard pattern, or if a file
name appears explicitly and is also matched by a wildcard pattern, the
linker will use the first match in the linker script.
It sounds like the linker script will only put the data (or anything) in one section.
However all hope is not lost. You can copy the section using objcopy and then add the section using objcopy again
objcopy -O binary --only-section=.data your-file temp.bin
objcopy --add-section .dummydata=temp.bin your-file
This will append the section to be the last section with a VMA/LMA of 0. You can then use objcopy to move the section to the desired location.
objcopy --change-section-address .dummydata=desired-address your-file
Of course if there is something already there that would be problematic. Luckily you can create a hole right after your first .data with something like:
data_start = .;
.data : { *(.data) }
data_end = .;
. += (data_end - data_start);
This should create a hole right after your first data, big enough to put another copy of data right after it. If this isn't exactly where you want it to be just add (data_end - data_start) where you want the hole.
Finally you can change the section flags, again with objcopy
objcopy --set-section-flags .dummydata=the-flags-you-want your-file
Not as clean as just duplicating something in the linker script but it should work.
Related
My application calls some functions which are placed in an external static library. I link the external static library to my application and everything works (in this case I'm using GCC).
Nevertheless, the locations (addresses) of text, .data and .bss sections of the library are chosen by the linker. I can choose/change their locations by modifying the linker script, but it's tedious as I have to specify all the functions, variables, etc. of the library. What I mean it's something like:
. = 0x1000; /* new location */
KEEP(*(.text.library_function1));
KEEP(*(.text.library_function2));
[...]
An alternative solution is to build the external library by placing a section attribute for each function/variable, and then modifying the linker by re-locating the whole section. Something like:
/* C source file */
unsigned char __attribute__((section (".myLibrarySection"))) variable1[10];
unsigned char __attribute__((section (".myLibrarySection"))) variable2[10];
/* Linker script */
. = 0x1000;
KEEP(*(.myLibrarySection))
However, I'd like to be able to relocate entire .text, .data and .bss segments of an external static library without the need of using these tricks.
I'd like something like this (in linker script):
. = 0x1000;
KEEP(*(.text.library_file_name))
Is it possible using GCC toolchain?
Is it possible using other toolchains (IAR, Keil, etc.)?
You can use the archive:filename syntax in ld.
First place all the .o files from your external library into a static library .a file, if they aren't already. That is the normal way static library binaries are distributed.
Then in the linker script, specify:
.text.special : {
. = 0x1000;
*libspecial.a:*(.text .text.*)
}
.text {
*(.text .text.*)
}
The wildcard will pick all the files coming from libspecial.a and place them in the first section. The later wildcard will then pick anything left over. If there is a need to place the .text.special section after the normal section, you can use EXCLUDE_FILE directive in a similar way.
Can you just postprocess your lib to rename sections?
# Untested!
TMP=`mktemp -d`
trap "rm -rf $TMP" EXIT
cd $TMP
ar x path/to/your/lib.a
for o in *.o; do
for s in text data bss; do
objcopy --rename-section .$s=.mynew$s $o
done
done
ar rcs path/to/your/lib.a *.o
I have to relocate an elf at runtime and so I want to have access to all the relocations emitted by the linker: hence the use of the --emit-relocs ld option. The thing is I want to group all the .rela.* sections into one .rela.dyn section in the linker script and then go through this only section to relocate all the symbols.
But I can't get my linker script to achieve this, I still see a lot of .rela.* sections in the final elf and not the output section .rela.dyn. The following is what I used in the linker script and actually is simply copied from another architecture linker script that works but that does not use --emit-relocs:
.rela.dyn : ALIGN(8) {
*(.rela .rela*)
}
Does the --emit-relocs option 'bypass' the linker script ? Or did I simply miss something ?
Thanks,
Alex
My application calls some functions which are placed in an external static library. I link the external static library to my application and everything works (in this case I'm using GCC).
Nevertheless, the locations (addresses) of text, .data and .bss sections of the library are chosen by the linker. I can choose/change their locations by modifying the linker script, but it's tedious as I have to specify all the functions, variables, etc. of the library. What I mean it's something like:
. = 0x1000; /* new location */
KEEP(*(.text.library_function1));
KEEP(*(.text.library_function2));
[...]
An alternative solution is to build the external library by placing a section attribute for each function/variable, and then modifying the linker by re-locating the whole section. Something like:
/* C source file */
unsigned char __attribute__((section (".myLibrarySection"))) variable1[10];
unsigned char __attribute__((section (".myLibrarySection"))) variable2[10];
/* Linker script */
. = 0x1000;
KEEP(*(.myLibrarySection))
However, I'd like to be able to relocate entire .text, .data and .bss segments of an external static library without the need of using these tricks.
I'd like something like this (in linker script):
. = 0x1000;
KEEP(*(.text.library_file_name))
Is it possible using GCC toolchain?
Is it possible using other toolchains (IAR, Keil, etc.)?
You can use the archive:filename syntax in ld.
First place all the .o files from your external library into a static library .a file, if they aren't already. That is the normal way static library binaries are distributed.
Then in the linker script, specify:
.text.special : {
. = 0x1000;
*libspecial.a:*(.text .text.*)
}
.text {
*(.text .text.*)
}
The wildcard will pick all the files coming from libspecial.a and place them in the first section. The later wildcard will then pick anything left over. If there is a need to place the .text.special section after the normal section, you can use EXCLUDE_FILE directive in a similar way.
Can you just postprocess your lib to rename sections?
# Untested!
TMP=`mktemp -d`
trap "rm -rf $TMP" EXIT
cd $TMP
ar x path/to/your/lib.a
for o in *.o; do
for s in text data bss; do
objcopy --rename-section .$s=.mynew$s $o
done
done
ar rcs path/to/your/lib.a *.o
I compiled a Hello World C file and need just one section (only the hello world function) of it.
The compiled file has the format elf32-i386 and contains 4 sections: .rodata, .text.hello, .comment, .eh_frame.
I tried to use objcopy to extract only the .text.hello section: http://www.thegeekstuff.com/2013/01/objcopy-examples/ example 3.
It fails, reporting:
BFD: hello_new: symbol `.rodata' required but not present
objcopy:hello_new: No symbols
How to solve it?
First, you mentioned you need only the the .text section - for the purpose of runtime execution? That is not right: if that hello functions has strings hardcoded inside, all these strings will be located inside .rodata section, so are u going to ignore this section?
.eh_frame is for debugger, and .comment i think is not needed, but .data is also needed.
Another thing is the relocation table - if the fucntion is to be dynamically loaded into some arbitrary memory region, then lots of area INSIDE the function may need to be patched.....check objdump -r of your ELF to find out if there is any relocation entries. if not, u are safe.
Also, anything inside your function declared as "const" will also go into the .rodata section - global data of course. Variables or constants local to the function are on the stack. And all global data are located inside .data section.
But coming back to the original error, the reason is because the example 3 in the original URL does not have cross-referencing (the .interp section) and therefore objdump -s will not have error. Your case, .text does have cross-referencing to .rodata section, but is not available after you have extracted just the .text section out.
I'm working on a toy operating system and bootloader. I'm trying to write the kernel in C, and then convert it to binary for direct jumping to from the bootloader (i.e., I'm not loading an ELF or anything like that).
I've got the linker file setup with the proper origin (I'm loading the kernel to address 0xC0000000) and confirm with objdump that it's using it correctly. However, it's not placing my entry point at the start (0xC0000000) like I wanted. I guess that's not what the ENTRY directive is for.
My problem is simply that I want to place a particular function, kernel_main at address 0xC0000000. Is there a way I can accomplish this using gcc for compiling and linking?
Here is what the relevant parts of my linker file look like:
ENTRY(kernel_main)
SECTIONS
{
/* Origin */
. = 0xC0000000;
.text BLOCK(4K) : ALIGN(4K)
{
*(.text)
}
/* etc. */
}
The ENTRY linker command tells the linker which symbol the loader should jump to when it loads the program. If you're making your own operating system it's really not used since there is no loader.
Instead, as you know, the program simply starts at the first code address.
To make place a special segment of code first, you could place it in a special code segment, and put it first in the list:
.text BLOCK(4K) : ALIGN(4K)
{
*(.text.boot) *(.text)
}
The segments in the list is placed in the order they are given.
The ENTRY directive is only useful for output formats that support an entrypoint. Since you're using a binary output, this won't work. What you can do is write a small stub in a separate source file (i.e. entry.c or entry.asm or whatever). Then, in the ld script, before the *(.text) line, you can put entry.o(.text). This instructs ld to load the symbols from a specific object file (whereas * denotes all object files). So the new ld script would look like this:
ENTRY(kernel_main)
SECTIONS
{
/* Origin */
. = 0xC0000000;
.text BLOCK(4K) : ALIGN(4K)
{
entry.o(.text)
*(.text)
}
/* etc. */
}
As long as entry.o contains just one function (that simply calls your kernel main), this should work.