3

有没有一种方法可以影响、设置或定义函数的(相对)地址?也许链接描述文件有任何可能性来确保函数 abc() 始终位于 OFFSET+0x0034C0 (只是一个例子)。我想以某种方式“控制”内存中函数的位置,以使这些位置具有某种参数化。目前我正在寻找一种使用 gcc 在我的 x86 上的方法。但是,真正的应用程序应该在嵌入式设备上运行。

问候

4

3 回答 3

8

您可能可以使用带有 gcc 的链接器脚本魔术来做到这一点,是的。查看如何定义部分放置,然后将指令放入源代码中以将函数放入您选择的部分中。

完全不确定这是否适用于 x86 机器,因为操作系统可能有……反对意见。这更适合直接嵌入式使用。

在完整的操作系统上控制代码位置有什么意义

于 2013-02-06T13:40:14.017 回答
1

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的代码,而不是 atmyFunc0x20000x12e8

Disassembly of section .my_section:

000012e8 <myFunc-0xd18>:
        ...

00002000 <myFunc>:
    2000:       b508            push    {r3, lr}
    ...

此代码适用Codesourcey gcc于 ARM-Cortex 套件。我不太确定x86 ...

于 2013-02-06T14:22:44.920 回答
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; }

现在您应该能够将所有函数作为基地址的偏移量。

如果您的所有函数都具有相同的调用签名,您可以通过使用函数指针数组而不是结构来简化这一点。但是,数组和结构都会保存指针,因此指针数学基本相同。

这还允许您使用链接器将补丁表定位在特定地址。

于 2013-02-06T14:01:51.737 回答