将符号从C文件导入链接描述文件

时间:2013-06-07 14:28:48

标签: c gcc linker ld

我在我的C文件中创建了一个名为.co_stack的部分,并有一个名为pulStack的数组来定义该区域。

#define STACK_SIZE       0x00003000      /*!< Stack size (in Words)           */
__attribute__ ((section(".co_stack")))
unsigned long pulStack[STACK_SIZE];

我定义堆栈部分的gcc链接器脚本如下所示

.co_stack : {
    _fstackptr = ORIGIN(ram) + LENGTH(ram) - 4;
    _fstacksize = 0x00003000 * 4;       
    . = (_fstackptr - _fstacksize);
    *(.co_stack .co_stack.*)
}

正如您所看到的,我最终在2个位置定义了堆栈大小。 一个是我的.c文件中的STACK_SIZE和我的.ld文件中的_fstacksize。

如何在一个地方定义它?

例如 我想创建一个变量pulStackSize,如下所示。

const unsigned long pulStackSize = sizeof(pulStack);

我想将.ld文件中的_fstacksize定义为

_fstacksize = STACK_SIZE * 4;

如果我这样做,我会收到错误,说堆栈溢出48K字节。

如何将.c中的符号导入我的.ld文件?

1 个答案:

答案 0 :(得分:10)

一些解决方案(对于更一般的问题“如何在C和LD脚本之间共享值?”):

1)(注意:对于此解决方案,我将假设您使用的是最新版本的GNU ld,文档:http://www.math.utah.edu/docs/info/ld_3.html

您可以将绝对值与脚本内的符号相关联,方法是在复合节之外定义它(例如,在脚本的最开头)。您可以通过将其定义为extern来导入C中的符号。请注意,C中所需的值是符号的地址:

脚本:

StackSize = 0x00003000 * 4; /* the size */
.co_stack : {  
    _fstackptr = ORIGIN(ram) + LENGTH(ram) - 4;
    _fstacksize = StackSize;       
    . = (_fstackptr - _fstacksize);
    *(.co_stack .co_stack.*)
}

C:

extern long StackSize;
#define STACK_SIZE (((size_t)&StackSize)/sizeof(long))

该解决方案可能对使用所获得的值施加限制,例如,大多数编译器都不接受这样的一行:

long my_stack[STACK_SIZE];

但您不再需要它,因为您可以在脚本中定义符号“my_stack”并将其导入为“extern long my_stack [];”。无论如何,我认为这是一个可接受的限制。

2)另一种方法是在脚本中定义两个位于开头和该部分的符号,并将它们导入为C中的“extern char”。该部分的大小(以字节为单位)是它们两者的差异地址。该解决方案具有与(1)

相同的限制

3)如果你的链接器不够智能,你可以使用C预处理器在编译时通过像C中那样展开宏STACK_SIZE来生成合适的脚本。你必须

a)创建包含

的文件“stacksize.h”
#define STACK_SIZE 0x3000

b)在脚本开头添加#include“stacksize.h”行,并在需要时使用STACK_SIZE。将脚本保存为“ldscript.c”。

c)在makefile(或等效的编译过程)中调用预处理器。如果您有GCC,则命令为:

gcc -P -E ldscript.c -o ldscript.ld

请注意,某些gcc版本对输入文件的扩展名有特殊含义。所以我建议使用“.c”,这是最安全的方式。

d)使用C预处理器生成的文件“ldscript.ld”作为链接脚本