我想写一个脑力激荡的编译器,但是当我去写一个编译器时,我陷入了这个问题
我想创建一个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?
答案 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文件,这将使其可执行。