为什么在将代码直接编译为可执行文件而不是编译为目标文件然后手动链接时会得到额外的系统调用?

发布于 2025-01-12 10:51:06 字数 1231 浏览 4 评论 0原文

我想在 Ubuntu 上使用 GNU C 编译器编译此 C 代码,而不链接任何标准库,只执行以下代码。

static void exit(long long code)
  {asm inline
  ("movq $60,%%rax\n"
  "movq %[code],%%rdi\n"
  "syscall"
  :
  :[code]"rm"(code)
  :"rax"
  ,"rdi");}
static void write(long long fd,char *msg,long long len)
  {asm inline
  ("movq $0x1,%%rax\n"
  "movq %[fd],%%rdi\n"
  "movq %[msg],%%rsi\n"
  "movq %[len],%%rdx\n"
  "syscall"
  :
  :[fd]"rm"(fd)
  ,[msg]"rm"(msg)
  ,[len]"rm"(len)
  :"rax"
  ,"rdi"
  ,"rsi"
  ,"rdx");}
#define PRINT(msg) write(1,msg,sizeof(msg))
void _start()
  {PRINT("Hello World.\n");
  exit(0);}

我使用 cc example.c -ffreestand -nostartfiles -O3 -o example 进行编译。

当我调用输出文件时,我看到许多不应该存在的额外系统调用 strace

  1. brk
  2. arch_prctl
  3. access
  4. mmap
  5. arch_prctl
  6. mprotect

然后我像这样编译: cc example.c - c -O3 -o 示例.o; ld example.o -o example 并且它没有执行额外的系统调用。它甚至使文件大小变得更小。

它的 objdump -d 完全相同。在 objdump -D 中,与第二种情况相比,我在第一种情况下发现了一些额外的符号(_DYNAMIC,__GNU_EH_FRAME_HDR,.interp),但代码中仍然没有任何额外系统调用的迹象。

你知道为什么我使用 cc example.c -ffreestand -nostartfiles -O3 -o example 得到额外的系统调用,而不是使用 cc example.c -c -O3 -o example.o ; ld example.o -o 示例?

I want to compile this C code with the GNU C Compiler on Ubuntu without linking any standard libraries, having only the following code execute.

static void exit(long long code)
  {asm inline
  ("movq $60,%%rax\n"
  "movq %[code],%%rdi\n"
  "syscall"
  :
  :[code]"rm"(code)
  :"rax"
  ,"rdi");}
static void write(long long fd,char *msg,long long len)
  {asm inline
  ("movq $0x1,%%rax\n"
  "movq %[fd],%%rdi\n"
  "movq %[msg],%%rsi\n"
  "movq %[len],%%rdx\n"
  "syscall"
  :
  :[fd]"rm"(fd)
  ,[msg]"rm"(msg)
  ,[len]"rm"(len)
  :"rax"
  ,"rdi"
  ,"rsi"
  ,"rdx");}
#define PRINT(msg) write(1,msg,sizeof(msg))
void _start()
  {PRINT("Hello World.\n");
  exit(0);}

I compiled with cc example.c -ffreestanding -nostartfiles -O3 -o example.

When I called the output file I saw a lot of extra system calls with strace that should not have been there:

  1. brk
  2. arch_prctl
  3. access
  4. mmap
  5. arch_prctl
  6. mprotect

I then compiled like this: cc example.c -c -O3 -o example.o; ld example.o -o example and it did not do the extra syscalls. It even made the filesize somewhat smaller.

The objdump -d of it was exactly the same. In the objdump -D I found some extra symbols (_DYNAMIC,__GNU_EH_FRAME_HDR,.interp) in the first case compared to the second, but still no sign of any extra syscalls in the code.

Do you know why I get the extra system calls with cc example.c -ffreestanding -nostartfiles -O3 -o example and not with cc example.c -c -O3 -o example.o; ld example.o -o example?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

玉环 2025-01-19 10:51:06

我知道发生了什么事。

如果我使用 cc example.c -ffreestand -nostartfiles -O3 -o example 编译代码,编译器会生成动态链接的可执行文件。动态链接的可执行文件有一个 .interp 部分。这就是我在 objdump -D 中看到的。

动态链接的可执行文件通过程序解释器和动态链接器执行。我看到的额外系统调用来自动态链接器。我仍然不知道为什么可执行文件想要动态链接程序中不链接任何库并且想要独立的任何内容。

如果您不希望动态链接器进行额外的系统调用 - 您应该为 gcc 提供额外的 -static 选项。如果没有发生动态链接,编译器不会自动执行此操作。

I found out what is happening.

If I compile the code with cc example.c -ffreestanding -nostartfiles -O3 -o example the compiler makes a dynamically linked executable. Dynamically linked executables have an .interp section. That is what I was seeing in my objdump -D.

Dynamically linked executables are executing via the program interpreter and the dynamic linker. The additional system calls I saw, came from the dynamic linker. I still do not know why the executable wants to dynamically link anything in a program that does not link any libraries and wants to be freestanding.

If you do not want the extra system calls from the dynamic linker - you should give gcc the extra -static option. The compiler does not automatically do this if there is no dynamic linking happening.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文