【问题标题】:Why is my simple `main` program's ELF header say it's a `DYN (Shared object file)` instead of an executable? [duplicate]为什么我的简单“主”程序的 ELF 标头说它是“DYN(共享对象文件)”而不是可执行文件? [复制]
【发布时间】:2020-08-17 09:59:07
【问题描述】:

这是一个非常简单的 C++ 程序:

// main.cpp
int main() {}

我的Makefile 生成以下命令来编译程序。

❯ make
g++ -O0 -fverbose-asm  -o main main.cpp

我使用命令 file 检查它是一个 ELF 可执行文件:

❯ file main
main: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=921d352e49a0e4262aece7e72418290189520782, for GNU/Linux 3.2.0, not stripped

一切似乎都很好直到我尝试检查 ELF 标头

❯ readelf -e main
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
...
  Type:                              DYN (Shared object file)

来自维基百科here,似乎有不同类型的文件,例如EXEC。为什么它说我的简单主程序是共享对象而不是 ELF 标头上的可执行文件?

从我对.so 的有限知识范围来看,我认为它们是链接但直到运行时才加载的库。在这种情况下这有什么意义?

额外信息:

❯ g++ --version
g++ (Arch Linux 9.3.0-1) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.

❯ readelf --version
GNU readelf (GNU Binutils) 2.34
Copyright (C) 2020 Free Software Foundation, Inc.

❯ lsb_release -a
LSB Version:    1.4
Distributor ID: Arch
Description:    Arch Linux
Release:    rolling
Codename:   n/a

【问题讨论】:

  • 我用 g++ 9.3.1 和 readelf 2.32-31.fc31 得到Type EXEC (Executable file)

标签: c++ g++ elf readelf


【解决方案1】:

编译为“与位置无关的可执行文件”(带有-pie/-fPIE)的可执行文件应在运行时重新定位到随机地址。为此,他们使用 DYN 类型。

您的 g++ 版本配置了--enable-default-pie,因此默认设置为-pie-fPIE。您可以通过与-no-pie 链接来禁用此功能并生成正常的可执行文件。

【讨论】:

  • 谢谢!我刚刚检查过:Configured with: /build/gcc/src/gcc/configure ... --enable-default-pie ...。你是对的。在我看来仍然很奇怪,默认情况下所有可执行文件都是 DYN 类型。总是启用 pie 不会有一些性能损失吗?
  • @OneRaynyDay 是的,有一些性能影响。但是,无论如何,大多数应用程序在已经与位置无关的共享库中花费了相当多的运行时间。随机化主程序的加载地址有安全方面的好处,因此许多发行版都采取了较小的性能影响,只是构建了与位置无关的所有内容。
  • 对现代架构 (x86-64) 的性能影响实际上可以忽略不计,而 ASLR 对二进制文件的安全影响具有更大的价值,这就是大多数发行版朝这个方向发展的原因。
猜你喜欢
  • 2011-10-01
  • 1970-01-01
  • 2012-02-11
  • 1970-01-01
  • 1970-01-01
  • 2018-08-01
  • 1970-01-01
  • 2020-12-26
  • 2023-03-04
相关资源
最近更新 更多