作为我的问题的简单示例,假设我们将两个数据数组嵌入到要在C程序中使用的可执行文件中:chars
和shorts
。这些数据数组以chars.raw
和shorts.raw
的形式存储在磁盘上。
使用objcopy
,我可以创建包含数据的目标文件。
objcopy --input binary --output elf64-x86-64 chars.raw char_data.o
objcopy --input binary --output elf64-x86-64 shorts.raw short_data.o
[objdump
显示数据已正确存储和导出为_binary_chars_raw_start
,end
和size
。
$ objdump -x char_data.o
char_data.o: file format elf64-x86-64
char_data.o
architecture: i386:x86-64, flags 0x00000010:
HAS_SYMS
start address 0x0000000000000000
Sections:
Idx Name Size VMA LMA File off Algn
0 .data 0000000e 0000000000000000 0000000000000000 00000040 2**0
CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 g .data 0000000000000000 _binary_chars_raw_start
000000000000000e g .data 0000000000000000 _binary_chars_raw_end
000000000000000e g *ABS* 0000000000000000 _binary_chars_raw_size
(short_data.o
的类似输出
但是,当我将这些目标文件和代码链接到可执行文件时,会遇到问题。例如:
#include <stdio.h>
extern char _binary_chars_raw_start[];
extern char _binary_chars_raw_end[];
extern int _binary_chars_raw_size;
extern short _binary_shorts_raw_start[];
extern short _binary_shorts_raw_end[];
extern int _binary_shorts_raw_size;
int main(int argc, char **argv) {
printf("%ld == %ld\n", _binary_chars_raw_end - _binary_chars_raw_start, _binary_chars_raw_size / sizeof(char));
printf("%ld == %ld\n", _binary_shorts_raw_end - _binary_shorts_raw_start, _binary_shorts_raw_size / sizeof(short));
}
(gcc main.c char_data.o short_data.o -o main
编译)
14 == 196608
7 == 98304
在我的计算机上。 _binary_chars_raw_size
(和short
)的大小不正确,我也不知道为什么。
类似地,如果_start
或_end
用于初始化任何内容,则它们甚至可能不在可执行文件中彼此靠近(_end
-_start
不等于大小,并且甚至可能是负数。
我在做什么错?
extern char _binary_chars_raw_start[];
extern char _binary_chars_raw_end[];
extern int _binary_chars_raw_size;
extern short _binary_shorts_raw_start[];
extern short _binary_shorts_raw_end[];
extern int _binary_shorts_raw_size;
它们本身不是变量。它们是变量,它们自己放置在区域的开始和结尾。因此,这些变量的[[地址是区域的开始和结束。做:
#include <stdio.h>
extern char _binary_chars_raw_start;
extern char _binary_chars_raw_end;
extern char _binary_chars_raw_size;
// print ptrdiff_t with %td
printf("%td == %d\n",
// the __difference in addresses__ of these variables
&_binary_chars_raw_end - &_binary_chars_raw_start,
(int)&_binary_chars_raw_size);
// note: alsoo print size_t like result of `sizeof(..)` with %zu
@ edit _size
也是指针