有没有一种方法可以影响、设置或定义函数的(相对)地址?也许链接描述文件有任何可能性来确保函数 abc() 始终位于 OFFSET+0x0034C0 (只是一个例子)。我想以某种方式“控制”内存中函数的位置,以使这些位置具有某种参数化。目前我正在寻找一种使用 gcc 在我的 x86 上的方法。但是,真正的应用程序应该在嵌入式设备上运行。
问候
您可能可以使用带有 gcc 的链接器脚本魔术来做到这一点,是的。查看如何定义部分放置,然后将指令放入源代码中以将函数放入您选择的部分中。
完全不确定这是否适用于 x86 机器,因为操作系统可能有……反对意见。这更适合直接嵌入式使用。
在完整的操作系统上控制代码位置有什么意义?
IMO,最好的方法是将函数放入用户定义的部分,就像上面提到的unwind一样。您可以在下面找到一个将函数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
现在这样做,您将看到一个名称为的部分,其中包含at address.my_section
的代码,而不是 atmyFunc
0x2000
0x12e8
Disassembly of section .my_section:
000012e8 <myFunc-0xd18>:
...
00002000 <myFunc>:
2000: b508 push {r3, lr}
...
此代码适用Codesourcey gcc
于 ARM-Cortex 套件。我不太确定x86 ...
一个典型的通用实现是向量表(我也听说过这称为补丁表)。
首先,在你的 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; }
现在您应该能够将所有函数作为基地址的偏移量。
如果您的所有函数都具有相同的调用签名,您可以通过使用函数指针数组而不是结构来简化这一点。但是,数组和结构都会保存指针,因此指针数学基本相同。
这还允许您使用链接器将补丁表定位在特定地址。