I know that statically-linked binaries use crt (C Runtime) when linking, as it passes cmd arguments to main
, deals with TLS storage, etc. However, inside a dynamically-linked binary, there is no such codes, so crt is not linked to it when linking.
But after searching keyword "crt" in source codes of ld
, glibc
and even linux kernel, I can't find any clue that dynamically-linked binaries use crt.
So how does those dynamically-linked binaries handle cmd arguments passing, TLS initialization, etc. without crt?
CodePudding user response:
Linux C runtime called gnulibc, unlike CRT in Microsoft interpretation.
If you are using any functions from standard library like strlen or malloc - linker will associate your shared library with Gnulibc.
If you d'like to avoid it for some reason i.e. you have your own implementation of such functions you can instruct linker not to link with standard librarians
-nodefaultlibs -nostdlib
command line options. Anyway in most cases this is really a bad idea, these options are rather for developing device drivers and operating system kernel it self rather then shared librarians.
In order to check what dependencies a shared library have, you can use ldd
or readelf
command as described in the following manual
CodePudding user response:
It doesn't matter if the binary links with no other libraries or does link. The crt is always "statically" included inside the executable.
Let's do real life, consider the following setup:
==> main.c <==
#include <stdio.h>
int main(int argc, char **argv) {
puts(argv[0]);
}
==> compile.sh <==
#!/bin/bash
set -x
gcc -static main.c -o static.out
gcc main.c -o dynamic.out
ldd static.out
ldd dynamic.out
./static.out
./dynamic.out
objdump -D static.out | grep -C10 '<_start>:'
objdump -D dynamic.out | grep -C10 '<_start>:'
The ./compile.sh
script execution outputs:
gcc -static main.c -o static.out
gcc main.c -o dynamic.out
ldd static.out
not a dynamic executable
ldd dynamic.out
linux-vdso.so.1 (0x00007ffc226e7000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f079878e000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f07989cf000)
./static.out
./static.out
./dynamic.out
./dynamic.out
objdump -D static.out
grep -C10 '<_start>:'
0000000000401508 <read_encoded_value_with_base.cold>:
401508: 50 push %rax
401509: 67 e8 cb fb ff ff addr32 call 4010da <abort>
000000000040150f <__gcc_personality_v0.cold>:
40150f: 67 e8 c5 fb ff ff addr32 call 4010da <abort>
401515: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1)
40151c: 00 00 00
40151f: 90 nop
0000000000401520 <_start>:
401520: f3 0f 1e fa endbr64
401524: 31 ed xor