我有一个与gcc链接器有关的问题。
我正在使用嵌入式内容(PIC32),但PIC32的编译器和链接器基于gcc,因此,“常规”gcc链接器和PIC32链接器的主要内容应该是常见的。
为了节省闪存空间(这在微控制器上通常是不够的)我需要在引导加载程序中放入几个大函数,应用程序应该只通过指针调用这些函数。
所以,我需要在生成的代码中创建向量表。
我正在尝试获取函数的绝对地址并将其写入生成的代码,但仍然会出错。
在下面的示例中,我试图获取函数_formatted_write
的地址。
代码:
.user_addr_table _USER_ADDR_TABLE_ADDR :
{
KEEP(*(.user_addr_table))
LONG((ABSOLUTE(_formatted_write))); /* _formatted_write is a name of my function */
} > user_addr_table
链接器返回错误:“unresolvable symbol '_formatted_write' referenced in expression
”。
我注意到如果我写了一些垃圾而不是_formatted_write
,那么它会返回错误“undefined symbol .....
”,因此链接器知道_formatted_write
。
这让我觉得我应该执行一些额外的步骤来使其“可解析”。但仍然不知道该怎么做。
答案 0 :(得分:1)
我在这周围找到的方法是使用函数指针,即
void (*formatted_write)( int a, char * b, struct mystruct c );
然后,在启动时的代码中设置该函数的地址,即
formatted_write = 0xa0000;
然后你可以使用普通约定调用你的函数。
此外,您可以在编译时使用-Wl, - just-symbols = symbols.txt标志。您可以按如下方式设置符号的地址:
formatted_write = 0xa0000;
答案 1 :(得分:1)
对于有人遇到同样问题的情况(比如我几个小时前),还有一个更好的解决方案:
让" bootloader.out"是bootloader-binary。然后我们可以用
生成nm -g bootloader.out | grep '^[0-9,a-e]\{8\} T' | awk '{printf "PROVIDE(%s = 0x%s);\n",$3,$1}' > bootloader.inc
我们可以使用
包含在应用程序的链接描述文件中的文件INCLUDE bootloader.inc
链接器现在知道所有引导加载程序函数的地址,我们可以链接它而不需要在应用程序中使用实际的功能代码。我们需要的只是我们想要执行的每个bootloader函数的声明。