我试图做的在C检查点/重新启动程序,我正在学习cryoPID的代码,看看进程如何重新启动。在它的代码中,cryoPID在使用某个全局变量的函数中创建要重新启动的进程的ELF头,这实际上令人困惑。cryoPID如何创建ELF头文件或者是否有一个简单的ELF生成方法?
我一直在寻找一种简单的方法来创建一个ELF可执行文件,甚至尝试libelf,但我发现大多数时候一些必要的信息在这些程序的文档中含糊不清,我无法理解去做吧。所以在这件事上任何帮助都会很大。
看到cryoPID的代码,我看到它在一个简单的方法在整个创作,不必将所有头字段等,但我似乎无法理解它使用的代码。 首先,在创建ELF下面的代码是相关的功能(这是在arch-x86_64的/ elfwriter.c):
Elf64_Ehdr *e;
Elf64_Shdr *s;
Elf64_Phdr *p;
char* strtab;
int i, j;
int got_it;
unsigned long cur_brk = 0;
e = (Elf64_Ehdr*)stub_start;
assert(e->e_shoff != 0);
assert(e->e_shentsize == sizeof(Elf64_Shdr));
assert(e->e_shstrndx != SHN_UNDEF);
s = (Elf64_Shdr*)(stub_start+(e->e_shoff+(e->e_shstrndx*e->e_shentsize)));
strtab = stub_start+s->sh_offset;
stub_start是在cryopid.h宏declare_writer定义一个全局变量:
#define declare_writer(s, x, desc) \
extern char *_binary_stub_##s##_start; \
extern int _binary_stub_##s##_size; \
struct stream_ops *stream_ops = &x; \
char *stub_start = (char*)&_binary_stub_##s##_start; \
long stub_size = (long)&_binary_stub_##s##_size
该宏用于writer _ *。c,它是实现文件编写器的文件。例如,在writer_buffered.c,宏调用此代码:
struct stream_ops buf_ops = {
.init = buf_init,
.read = buf_read,
.write = buf_write,
.finish = buf_finish,
.ftell = buf_ftell,
.dup2 = buf_dup2,
};
declare_writer(buffered, buf_ops, "Writes an output file with buffering");
所以stub_start被声明为一个未初始化的全局变量(上面的代码是不是在任何功能),而当看到在declare_writer所有的变量都没有在代码的任何其他部分设置,我假设stub_start只是指向.bss部分的一部分,但它似乎像cryoPID使用它,就像它指向它自己的ELF头部一样。
谁能帮我解决这个问题或帮助我反正轻松创建ELF头?
'_binary_stub_XXXXX_start'和'_size'可能来自使用[objcopy](http://sourceware.org/binutils/docs-2.16/binutils/objcopy.html)转换为目标文件的一些二进制数据。 – user786653