`file`,为什么可执行文件不报告为可执行文件?

`file`, why executables not reported as executables?

在 GNU/Linux Debian 9.9 (stretch) 中,我的程序被报告为:

build/debug/program_g:              ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=be082fb3..., not stripped
build/debug/stripped_program_g:     ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=be082fb3..., stripped
build/release/program:              ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=6477469..., stripped
build/release/program_not_stripped: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=6477469..., not stripped

编译器是 GCC(香草发行版,即 gcc (Debian 6.3.0-18+deb9u1) 6.3.0 2017051),标志是 "release":

 -ansi -pedantic -Wall -Wextra -Werror -Wunused-result -Wmissing-include-dirs 
 -Wparentheses -std=c89 -DPROGRAM_USE_STD_C89 -O2 -DNDEBUG

对于"debug":

 -ansi -pedantic -Wall -Wextra -Werror -Wunused-result -Wmissing-include-dirs 
 -Wparentheses -std=c89 -DPROGRAM_USE_STD_C89 -O0 -g -fprofile-arcs -ftest-coverage -DTRACE_U0 -DTRACE_U1 -no-pie

问题是为什么 "release" 的可执行文件被报告为 shared object 而不是 executable

因为

1. 您在 "debug" 构建中使用了 -no-pie 选项。构建与位置无关的可执行文件 (-pie) 是最近 Linux 发行版的默认设置。为什么要在调试版本中禁用它?

2. 您系统 (Debian stretch) 上的 file 程序不知道 PIE 可执行文件。其魔术文件的较新版本将正确地将其识别为 pie executable.

示例(/mnt/old 是 Debian 9.9 root fs):

$ cc -xc - <<<'int main(){}'

$ file -m /mnt/old/usr/share/misc/magic a.out
a.out: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=df3780407016f3ea1a936c35d786288b1c0d4486, not stripped

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