在 Linux 上,我想将一些结构存储在自定义.note.foobar
部分中,并在运行时发现它们。
我编译和链接下面的程序一次有gold
一次没有:
$ gcc -o test-ld test.c
$ gcc -o test-gold -fuse-ld=gold test.c
您可以看到ld
-linked 版本找到了该部分,而gold
-linked 版本没有:
$ ./test-ld
note section at vaddr: 2c4
note section at vaddr: 2f0
found f00dface
note section at vaddr: 324
note section at vaddr: 7a8
note section at vaddr: 270
note section at vaddr: 1c8
$ ./test-gold
note section at vaddr: 254
note section at vaddr: 7a8
note section at vaddr: 270
note section at vaddr: 1c8
但是,该部分确实存在于两个二进制文件中:
$ readelf -x .note.foobar test-ld
Hex dump of section '.note.foobar':
0x000002f0 04000000 14000000 67452301 666f6f00 ........gE#.foo.
0x00000300 cefa0df0 00000000 00000000 00000000 ................
0x00000310 04000000 14000000 67452301 666f6f00 ........gE#.foo.
0x00000320 efbeadde ....
$ readelf -x .note.foobar test-gold
Hex dump of section '.note.foobar':
0x00000280 04000000 14000000 67452301 666f6f00 ........gE#.foo.
0x00000290 cefa0df0 00000000 00000000 00000000 ................
0x000002a0 04000000 14000000 67452301 666f6f00 ........gE#.foo.
0x000002b0 efbeadde ....
因此,您可能希望test-gold
程序报告 vaddr 280 处的部分,但事实并非如此。
为什么dl_iterate_phdr
找不到此部分,而readelf
可以,以及是gold
什么不同的原因导致此?
#define _GNU_SOURCE
#include <link.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct {
unsigned int elf_namesize;
unsigned int elf_datasize;
unsigned int elf_type;
unsigned int elf_name;
unsigned int bar;
} foo_t;
const foo_t __attribute__((used,section(".note.foobar,\"a\"#"))) foo1 = {
4,
20,
0x01234567,
0x6f6f66,
0xf00dface,
};
const foo_t __attribute__((used,section(".note.foobar,\"a\"#"))) foo2 = {
4,
20,
0x01234567,
0x6f6f66,
0xdeadbeef,
};
static int
callback(struct dl_phdr_info *info, size_t size, void *data)
{
for (int i = 0; i < info->dlpi_phnum; i++) {
const ElfW(Phdr)* phdr = &info->dlpi_phdr[i];
if (phdr->p_type == PT_NOTE) {
foo_t *payload = (foo_t*)(info->dlpi_addr + phdr->p_vaddr);
printf("note section at vaddr: %lx\n", phdr->p_vaddr);
if (phdr->p_memsz >= sizeof(foo_t) && payload->elf_type == 0x01234567 && payload->elf_name == 0x6f6f66) {
printf("found %x\n", payload->bar);
}
}
}
return 0;
}
int
main(int argc, char *argv[])
{
dl_iterate_phdr(callback, NULL);
return 0;
}