通过 运行 使可执行文件成为可执行文件

Making an executable by running an executable

本来想写个脑残的编译器,但是写的时候卡在了这个问题上

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

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

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

编辑:我不想知道如何编写编译器。阅读本文,编译器部分只是为了说明我将在何处使用它

我想创建一个二进制可执行文件(比如 maker.out),当 运行 创建一个可执行文件(比如 foo.out)。为了简单起见,让我们保持 foo.out 非常简单,当执行它时 returns 7;所以,这就是预期的结果:

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

那么maker.cpp怎么写呢?

您最初的信息是关于从一个脑残代码创建一个可执行文件,所以这就是这个答案的重点。您当前的问题太宽泛了。

正如您在之前的一篇帖子中所链接的那样,这里已经有一个执行此操作的实现: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

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

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

以下文字摘自man-page for 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

在你的情况下,运行ning chmod("foo.out", S_IRUSR | S_IXUSR) 应该给你(所有者)读取和执行 foo.out 的权限。假设您已将 foo.out 编写为正确的 elf 文件,这将使它可执行。