我试图在Linux(64位)的链接时将二进制文件B
嵌入到可执行文件A
中。
B
是一个简单的文字文件......
Hi, I'm a text file in plain ASCII.
...使用ld -r -bbinary -oB.o B
将其转换为可重定位目标文件。它的symtab
报告了三个全局变量,其名称非常明显:
_binary_B_start
_binary_B_end
_binary_B_size
这是A.c
...
#include <stdio.h>
extern const size_t _binary_B_size;
int main(int argc, char * * argv)
{
printf("size: %zu\n", _binary_B_size);
return 0;
}
...与B.o
编译并关联:gcc -oA A.c B.o
。
不幸的是,只要可执行文件A
尝试访问_binary_B_size
,就会突然终止SIGSEGV
。
我做错了什么?
答案 0 :(得分:2)
显然你误解了_binary_B_size
的语义。它似乎不是size_t
左值,因为你似乎相信。它是零大小绝对定位的部分(标签),其地址等于二进制blob数据的大小。在您的文件上尝试objdump -t
,您会在相应的列中看到*ABS*
。
所以正确的用法是
extern unsigned char _binary_B_size[];
int main()
{
printf("size: %zu\n", (size_t) _binary_B_size);
}
您也可以使用end - start
方法获得相同的结果
extern unsigned char _binary_B_start[];
extern unsigned char _binary_B_end[];
int main()
{
printf("size: %zu\n", (size_t) (_binary_B_end - _binary_B_start));
}
基本上,这里的主要考虑因素是_binary_B_size
没有理由成为size_t
左值。它实际上是一个在编译时预先确定的值的常量。它没有理由占用存储空间。而你在上面看到的是在目标文件中编码这种常量值的一种方法。