通过运行可执行文件制作可执行文件

时间:2019-07-24 07:46:10

标签: c++ c elf brainfuck

我想写一个脑力激荡的编译器,但是当我去写一个编译器时,我陷入了这个问题

我想创建一个ELF可执行文件(使用C / C ++),该可执行文件从文件中读取“脑袋”代码并生成一个可执行文件。就像GCC / clang

我可以读取和解析代码,但是我不知道如何编写可以在同一系统(例如x86)上运行的可执行文件?

我想要这种行为:     my_bf_compiler ./source.bf -o bin.out     ./bin.out

编辑:我不想知道如何编写编译器。阅读此内容,编译器部分仅是关于我将在哪里使用它的上下文

我想创建一个二进制可执行文件(例如maker.out),运行时会创建一个可执行文件(例如foo.out)。为简单起见,让foo.out非常简单,执行时返回7;因此,这是预期的结果:

./maker.out # Creates the foo.out executable
./foo.out && echo $ # Runs the executable and prints return value, in this case 7;

那我怎么写maker.cpp?

2 个答案:

答案 0 :(得分:1)

您的最初信息是关于用脑力激荡的代码创建可执行文件,因此这是此答案的重点。您当前的问题过于广泛。

由于您已链接到上一篇文章中,因此已经有一个实现可以在此处执行:https://github.com/skeeto/bf-x86/blob/master/bf-x86.c

基本上执行3个步骤:

1)将BF代码解析为中间表示形式(此处为https://github.com/skeeto/bf-x86/blob/master/bf-x86.c#L55

2)将此中间表示形式编译为机器代码(可在此处https://github.com/skeeto/bf-x86/blob/master/bf-x86.c#L496中找到)

3)根据规范编写ELF二进制文件。示例程序在这里执行此操作。 https://github.com/skeeto/bf-x86/blob/master/bf-x86.c#L622

步骤1和2由您自己决定,找到一个好的实现,对于步骤3,最简单的方法是以这种方式编写ELF标头和程序标头,即它只将程序机器码作为内容并将其指向程序的入口到步骤2中生成的机器代码。

有关ELF格式的完整规范,请参见:https://refspecs.linuxfoundation.org/elf/elf.pdf

答案 1 :(得分:1)

@Yanick的答案包含有关ELF格式以及如何创建elf可执行文件的足够信息。

但是,在我看来,您的问题是关于如何打开/创建可执行文件的。有一个名为chmod/fchmod的函数可能会对您有所帮助。

以下文字摘自chmod的手册页(运行man 2 chmod会看到此页):

   #include <sys/stat.h>
   int chmod(const char *pathname, mode_t mode);
   int fchmod(int fd, mode_t mode);

   The new file mode is specified in mode, which is a bit mask created by ORing together zero or  more  of  the
   following:

   S_ISUID  (04000)  set-user-ID (set process effective user ID on execve(2))

   S_ISGID  (02000)  set-group-ID (set process effective group ID on execve(2); mandatory locking, as described
                     in fcntl(2); take a new file's group from parent directory, as described in  chown(2)  and
                     mkdir(2))

   S_ISVTX  (01000)  sticky bit (restricted deletion flag, as described in unlink(2))

   S_IRUSR  (00400)  read by owner

   S_IWUSR  (00200)  write by owner

   S_IXUSR  (00100)  execute/search  by  owner ("search" applies for directories, and means that entries within
                     the directory can be accessed)

   S_IRGRP  (00040)  read by group

   S_IWGRP  (00020)  write by group

   S_IXGRP  (00010)  execute/search by group

   S_IROTH  (00004)  read by others

   S_IWOTH  (00002)  write by others

   S_IXOTH  (00001)  execute/search by others

对于您而言,运行chmod("foo.out", S_IRUSR | S_IXUSR)应该为您(所有者)授予读取和执行foo.out的权限。假设您已将foo.out编写为适当的elf文件,这将使其可执行。