我正在使用 GCC,并尝试让链接器从自定义部分中的不同文件创建数据对象数组。我已将此部分添加到链接描述文件中:
.mydata :
{
__mydata_start = .;
KEEP (*(.mydata))
__mydata_end = .;
}
这是我的数据结构:
struct my_type_t {
unsigned char a;
size_t b;
void *c;
const void *d;
const void *e;
const char *f;
};
我使用的是 64 位平台,sizeof(struct my_type_t)
给出 48。但是,链接器似乎希望将这些结构与 64 字节对齐。
我的声明:
struct my_type_t a1 __attribute__((section(".mydata"))) = {
1, 2, (void *)3, (void *)4, (void *)5, (void *)6,
};
struct my_type_t a2 __attribute__((section(".mydata"))) = {
7, 8, (void *)9, (void *)10, (void *)11, (void *)12,
};
链接器输出:
$ gcc -o ldtest ldtest.c -Wl,-Tlink.ld
$ objcopy -Obinary -j .mydata ldtest mydata
$ hd mydata
00000000 01 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 |................|
00000010 03 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 |................|
00000020 05 00 00 00 00 00 00 00 06 00 00 00 00 00 00 00 |................|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000040 07 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 |................|
00000050 09 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 |................|
00000060 0b 00 00 00 00 00 00 00 0c 00 00 00 00 00 00 00 |................|
如果我将其声明为数组:
struct my_type_t a1[2] __attribute__((section(".mydata"))) = {
{
1, 2, (void *)3, (void *)4, (void *)5, (void *)6,
},
{
7, 8, (void *)9, (void *)10, (void *)11, (void *)12,
},
};
正如预期的那样,没有填充:
00000000 01 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 |................|
00000010 03 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 |................|
00000020 05 00 00 00 00 00 00 00 06 00 00 00 00 00 00 00 |................|
00000030 07 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 |................|
00000040 09 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 |................|
00000050 0b 00 00 00 00 00 00 00 0c 00 00 00 00 00 00 00 |................|
为什么链接器添加超出编译器认为必要的额外填充,以及如何摆脱它?
最佳答案
我不知道为什么它要在 64 字节上对齐,但你可以这样做:
struct my_type_t {
unsigned char a;
size_t b;
void *c;
const void *d;
const void *e;
const char *f;
} __attribute__ ((aligned (64)));
为了使 gcc 自动将每个结构填充到最近的较高 64 字节地址,并使 sizeof(struct my_type_t) 也包含填充。这使得这样的操作可以正常工作:
struct my_type_t *s = &__mydata_start;
s++; // Jump to next entry
s[0]; // First entry
s[1]; // Second entry
关于c - 链接器在节中添加额外的填充?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39728871/