是否有影响,设置或定义函数(相对)地址的方法?也许链接器脚本有任何可能性来确保函数abc()始终驻留在OFFSET + 0x0034C0(仅作为示例)。 我想以某种方式“控制”内存中函数的位置,使这些位置进行某种参数化。 目前我正在使用gcc在我的x86上寻找一种方法。但是,真正的应用程序应该在嵌入式设备上运行。
此致
答案 0 :(得分:8)
你可以用linker script magic和gcc一起做,是的。看看如何定义section placement,然后在你的源代码中放置指令,将函数放在你选择的部分中。
完全不确定这是否可以在x86机器上运行,因为操作系统可能有......反对意见。这更适合直接嵌入式使用。
在完整操作系统上控制代码位置的点是什么?
答案 1 :(得分:1)
这个典型的通用实现是一个向量表(我也听说过这个称为补丁表)。
首先,在你的C文件中,编写你的函数:
void my_first_function(int){ /* do something */ }
void my_second_function(int){ /* do something */ }
然后,在您的C文件中创建一个定义表格布局的结构:
struct MyVectorTable
{
void (*first_function)(int);
int (*second_function)(float, char);
// all the rest
};
接下来,在您的C文件中创建一个静态表:
static struct MyVectorTable my_vector_table = {
my_first_function,
my_second_function,
};
最后将地址公开为void *
void* get_table_base_address(void) { return &my_vector_table; }
现在你应该能够将所有函数作为基址的偏移量。
如果所有函数都具有相同的调用签名,则可以通过使用函数指针数组而不是结构来简化此操作。但是,数组和结构都将保存指针,因此指针数学基本相同。
这也允许您使用链接器在特定地址找到补丁表。
答案 2 :(得分:1)
执行此操作的最佳方法IMO是将函数放入用户定义的部分,如上面提到的展开。您可以找到一个将函数myFunc
置于下方4kByte边界的简单示例:
通过修改链接描述文件在内存中创建一个新部分:
/* .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
现在,使用gcc的attribute
功能将函数放入我们刚创建的部分:
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)
{
// ...
}
如果您现在objdump
,则会看到名称为.my_section
的部分,其中myFunc
代码位于地址0x2000
,而不是{{1} }}
0x12e8
此代码适用于ARM-Cortex的Disassembly of section .my_section:
000012e8 <myFunc-0xd18>:
...
00002000 <myFunc>:
2000: b508 push {r3, lr}
...
套件。我对x86不太确定......