Reputation: 1005
is there a method to influence, set or define the (relative) address of a function? Maybe there are any possibilities witin the linker script to make sure function abc() always resides at OFFSET+0x0034C0 (just an example). I want to somehow "control" the location of functions inside the memory to make those locations some kind of parametrized. At the moment I am looking for an approach on my x86 using gcc. However, the real application should run on an embedded device.
Regards
Upvotes: 3
Views: 645
Reputation: 1655
The best way to do this, IMO, is to place functions into user-defined sections as unwind has mentioned above. You can find a simple example that places a function myFunc
at a 4kByte boundary below:
Create a new section in your memory by modifying the Linker Script:
/* .my_section will be the name of the section in the final executable */
.my_section : ALIGN (8)
{
. = ALIGN (0x1000);
KEEP(*(.mysection)) /* The section will be called ".mysection" in the
compiled translation unit (.obj) */
. = ALIGN (8);
} >rom
Now, use gcc's attribute
feature to place the function into the section we just created:
void myFunc(void) __attribute__ ((section(".mysection"))); // The section name to use
// here is ".mysection",
// not ".my_section"
// Looks like you need to use __attribute__ along with function declaration, rather
// than with the function definition, though I'm not sure why
void myFunc(void)
{
// ...
}
If you do objdump
now, you'll see a section by the name .my_section
holding the code of myFunc
at address 0x2000
, rather than at 0x12e8
Disassembly of section .my_section:
000012e8 <myFunc-0xd18>:
...
00002000 <myFunc>:
2000: b508 push {r3, lr}
...
This code works with Codesourcey gcc
suite for ARM-Cortex. I'm not quite sure about x86...
Upvotes: 1
Reputation: 9579
A typical generalized implementation to this would be a vector table (I've also heard this called a patch table).
First, in your C file, write your functions:
void my_first_function(int){ /* do something */ }
void my_second_function(int){ /* do something */ }
Then, in your C file create a structure that defines the layout of the table:
struct MyVectorTable
{
void (*first_function)(int);
int (*second_function)(float, char);
// all the rest
};
Next, in your C file create a static table:
static struct MyVectorTable my_vector_table = {
my_first_function,
my_second_function,
};
Finally expose the address as a void*
void* get_table_base_address(void) { return &my_vector_table; }
Now you should be able to get to all the functions as an offset from the base address.
If all your functions have the same call signature you can simplify this by having an array of function pointers instead of the struct. However, both the array and the struct will hold pointers, so the pointer math is basically the same.
This also allows you to locate your patch table at a specific address using the linker.
Upvotes: 1
Reputation: 399753
You can probably do it using linker script magic with gcc, yes. Look at how to define section placement, then put directives in your source to put functions in the section(s) of your choice.
Not at all sure if that will work in the x86 machine though, since the operating system might have ... objections. This is more for embedded use directly.
What would be the point of controlling code location on a full operating system?
Upvotes: 8