通过 运行 使可执行文件成为可执行文件
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 文件,这将使它可执行。
本来想写个脑残的编译器,但是写的时候卡在了这个问题上
我想创建一个 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 文件,这将使它可执行。