I have a binary file in linux. How can I check whether it has been compiled with "-static" or not?
相关问题
- Is shmid returned by shmget() unique across proces
- how to get running process information in java?
- Error building gcc 4.8.3 from source: libstdc++.so
- Why should we check WIFEXITED after wait in order
- Null-terminated string, opening file for reading
Check if it has a program header of type
INTERP
At the lower level, an executable is static if it does not have a program header with type:
This is mentioned in the System V ABI spec.
Remember that program headers determine the ELF segments, including those of type
PT_LOAD
that will get loaded in to memory and be run.If that header is present, its contents are exactly the path of the dynamic loader.
readelf
checkWe can observe this with
readelf
. First compile a C hello world dynamically:and then:
outputs:
so note the
INTERP
header is there, and it is so important thatreadelf
even gave a quick preview of its short 28 (0x1c) byte contents:/lib64/ld-linux-x86-64.so.2
, which is the path to the dynamic loader (27 bytes long + 1 for\0
).Note how this resides side by side with the other segments, including e.g. those that actually get loaded into memory such as:
.text
.We can then more directly extract those bytes without the preview with:
which gives:
as explained at: How can I examine contents of a data section of an ELF file on Linux?
file
source codefile
5.36 source code comments at src/readelf.c claim that it also checks forPT_INTERP
:found with
git grep statically
from the messagemain.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
.However, this comment seems to be outdated compared to the code, which instead checks for
PT_DYNAMIC
:I'm not sure why this is done, and I'm lazy to dig into
git log
now. In particular, this confused me a bit when I tried to make a statically linked PIE executable with--no-dynamic-linker
as shown at: How to create a statically linked position independent executable ELF in Linux? which does not havePT_INTERP
but does havePT_DYNAMIC
, and which I do not expect to use the dynamic loader.I ended up doing a deeper source analysis for
-fPIE
at: Why does GCC create a shared object instead of an executable binary according to file? the answer is likely there as well.Linux kernel source code
The Linux kernel 5.0 reads the ELF file during the exec system call at fs/binfmt_elf.c as explained at: How does kernel get an executable binary file running under linux?
The kernel loops over the program headers at
load_elf_binary
I haven't read the code fully, but I would expect then that it only uses the dynamic loader if
INTERP
is found, otherwise which path should it use?PT_DYNAMIC
is not used in that file.Bonus: check if
-pie
was usedI've explained that in detail at: Why does GCC create a shared object instead of an executable binary according to file?
ldd /path/to/binary
should not list any shared libraries if the binary is statically compiled.You can also use the
file
command (andobjdump
could also be useful).