How do I specify manual relocation for GCC code? - c

I am in a situation in an embedded system (an xtensa processor) where I need to manually override a symbol, but the symbol happens to be in the middle of another symbol. When I try using -Wl,--wrap=symbol it won't work, since the symbol isn't its own thing.
What I need to do is specify (preferably in a GCC .S, though .c is okay) where the code will end up. Though the actual symbol will be located somewhere random by the compiler, I will be memcpying the code into the correct place.
40101388 <replacement_user_vect>:
40101388: 13d100 wsr.excsave1 a0
4010138b: 002020 esync
4010138e: 011fc5 call0 4010258c <_UserExceptionVector_1>
My problem is GCC creates the assembly with relative jumps assuming the code will be located where it is in flash, while the eventual location will be fixed in an interrupt vector. How do I tell GCC / GNU as "put the code wherever you feel like, but, trust me it will actually execute from {here}"
Though my code is at 0x40101388 (GCC decided) it will eventually reside and execute from 0x40100050. How do I trick GCC by telling it "put the code HERE" but pretend it's located "HERE"
EDIT: I was able to get around this, as it turns out, the function I needed to modify was held in the linker script, individually. I was able to just switch it out in the linker script. Though I still would love to know the answer, I now have a work-around.

In the linker script each output section has two associated addresses: VMA and LMA -- the address for which the code is linked and the address where the code will be loaded.
Put the code that needs to be relocated into separate section, add an output section to your linker script with desired VMA and LMA and put an input section matching the name of the code section inside it.
E.g. the following C code
void f(void) __attribute__((section(".relocatable1.text")))
{
...
}
extern char _relocatable1_lma[];
extern char _relocatable1_vma_start[];
extern char _relocatable1_vma_end[];
void relocatable1_copy(void)
{
memcpy(_relocatable1_vma_start, _relocatable1_lma,
_relocatable1_vma_end - _relocatable1_vma_start);
}
Together with the following piece of ld script, with VMA substituted with the desired target code location
SECTIONS {
...
.some_section : { ... }
.relocatable1 VMA : AT(LOADADDR(.some_section) + SIZEOF(.some_section)) {
_relocatable1_vma_start = . ;
*(.relocatable1.literal .relocatable1.text) ;
_relocatable1_vma_end = . ;
}
_relocatable1_lma = LOADADDR(.relocatable1) ;
...
}
should do what you want.

Related

MPLAB X32 compiler and moving function to RAM causes linker error

I'm using Microchips XC32 C compiler and tools to build an executable for a SAM E70 processor.
I have to create a function that is executed from RAM and not ROM/Flash because this function uses special instructions to read a unique 128 bits at the beginning of Flash.
So I've defined the beginning of the function like this:
__ramfunc__ void ReadUniqueID(uint32_t *pdwUniqueID)
{
uint32_t status;
if (pdwUniqueID == NULL)
return;
printf("ReadUniqueID begin\r\n", pdwUniqueID[0]);
According to the documentation __ramfunc__ is supposed to ensure that the function is executed from ram.
However, when linking, the following errors occur.
c:\program files\microchip\xc32\v3.01\bin\bin\..\..\lib\gcc\pic32c\8.3.1\..\..\..\..\bin\bin/pic32c-ld.exe: Link Warning: attributes for input section '.RAMFUNC$.__stub' conflict with output section '.RAMFUNC$'
c:\program files\microchip\xc32\v3.01\bin\bin\..\..\lib\gcc\pic32c\8.3.1\..\..\..\..\bin\bin/pic32c-ld.exe: section .text.Reset_Handler%184 LMA [0044ba08,0044bb8b] overlaps section .text%180 LMA [0044b3bc,0044ba0f]
c:\program files\microchip\xc32\v3.01\bin\bin\..\..\lib\gcc\pic32c\8.3.1\..\..\..\..\bin\bin/pic32c-ld.exe: section .bss%44 VMA [2045fff4,2045ffff] overlaps section .RAMFUNC$ VMA [2045ff58,20460007]
Link Error: can't load section .RAMFUNC$ contents
Any help or pointers would be greatly appreciated.
Problem turned out to be that I was using printf() in the "ramfunc" function. Removed the printf()'s and all is working as expected.

how to use address defined in linkerscript in C source file?

In a C application, I want to place a big buffer at an address after the variables, stack and dma address ranges. Of course I can define a section in the wanted location in the linker script and declare a big array in C and give a section attribute to the array. But I want to do it without actually declaring the big array because it makes the executable too big. I want to use the array address to do the same.
I'm using gcc and try to use an address I define in the linker script inside the C source file.
Here is how I tried it.
in the linker script file (which is ldabtsm.lds.S in my case),
...
. = ALIGN(16777216);
.vimbuffs : {
*(.vimbuffs)
}
vimbuffs = .;
...
I tried using vimbuffs in the C source file.
So I did (if I can print, I can use it anyway..)
extern unsigned int vimbuffs; // from linker script
printf("vimbuffs = %x\n", vimbuffs);
From the map file, I can see the vimbufs is assigned to 0x3b3f6000 which is just right, I want it to be aligned. But when run the program and print the value, I see
vimbuffs = a07f233d
What is wrong?

How to write function at particular memory location in flash memory? Is there any directive for that?

How to write function at particular memory location in flash memory? Is there any directive for that? Do i need particular linker?
If you are using keil ide you can place a function at a specific address using .ARM.__at_address as the section name. To place the function add at 0x20000, specify:
int add(int n1,int n2) __attribute__((section(".ARM.__at_0x20000")));
int add(int n1,int n2)
{
return n1+n2;
}
Do you use the keil toolchain?
If yes, perhaps http://www.keil.com/support/docs/359.htm helps.
Edit:
The .obj file is generated by the compiler. I am not sure what you mean with 'how can i configure .obj file'.
The linker mentioned above takes the obj files, links them together and places code and variables.
You should start with a project which compiles and links without errors.
Then you have:
- Some c files. One of them with your function.
- A linkfile with the settings for the linker.
- A makefile or some kind of batchfile which calls compiler and linker with the necessary arguments.
If you have that, you can look into the m51 file for the name of the symbol for your function.
The m51 file is a textfile generated by the lx51 linker with interesting information about which symbols are there and what the linker has done with them.
The keil documentation for the linker I mentioned says: The compiler creates a symbol name for the function using the following format: ?PR?function_name?file_name.
This means: You will find the names of all functions of your project in the m51 file. If your function is in file file_x and named func_x. The symbol name will be PR?func_x?file_x
In http://www.keil.com/support/man/docs/lx51/lx51_segments.htm you can find some information about the usage of the SEGMENTS directive of the lx51 linker. According to that:
SEGMENTS (PR?func_x?file_x(C:0x1234))
should place your function to address 0x1234 in code memory.
Actually I have no keil toolchain. Therefore I cannot test all that myself.
But I am sure that you can manage that yourself if you start with a simple working example, change things step by step and check what happens.
Good Luck.
Helmut
Use ORG directive.
For example, for a function to start at location 2000H
ORG 2000H
MY_FUNC:
: YOUR CODE HERE
RET

Place a function at very start of binary

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.

How to write this ld script ?

If I want to link all .o files except z.o .All .o (no z.o) is relocated at 0xC0000000 while z.o is at 0xFFFF0000 but z.o is located at file offset 0x8000.
So.how to write this ld script ?
Here is my loader.lds
SECTIONS {
loader 0x00000000 : { start.o loader.o }
kloader 0x30100000 : AT(4096) { loaderk.o ../lib/klib.a }
vect 0xFFFF0000 : AT(0x4000) { high_vect.o }
}
Is this right ????
It is much easier if you use input sections. Just using filename is not the normal way to do this. The issue is that at some point the source modules will inter-act and you will have code and/or data from multiple location used in the same module. So, make sections loader, kloader and vect and use gcc attributes or pragmas to place code/data in sections.
Your question is answered in Gnu ld's Input section example. The output section list does not have to be in memory order. Place the wildcard { *.o(.text*) } last and input objects that aren't matched will be placed in this section.
An example annotated function might look like,
void data_abort(unsigned int fsr, void* fault) __attribute__ ((section ("vector)))
Often functions/data in different sections must co-operate, so being able to mix them in the same source file allows the compiler to perform optimizations on static items and keeps functionally similar items grouped together, even though they might reside in different sections.
I think this might generally follow what you requested.
SECTIONS {
loader 0x00000000 : { start.o loader.o }
kloader 0x30100000 : AT(4096) { loaderk.o ../lib/klib.a }
vect 0xFFFF0000 : AT(0x4000) { high_vect.o }
vect2 0xFFFF0000 : AT(0x8000) { z.o } /* overlay? */
text 0xC0000000 : { *.o }
}
I am not sure if you intend to over-lay the vectors or not. You can overlay init code with some data tables. Usually you want to separate at a minimum .text, .data and .bss.
Always generate a map file and double check the addresses there. This is much quicker than loading and instrumenting the code to determine that something has been placed at the wrong address.
See: Running code from RAM, Gnu Linker giving unexpected address, and the related links to this question.

Resources