Home > OS >  Does dynamically-linked binaries use crt in linux?
Does dynamically-linked binaries use crt in linux?

Time:07-11

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               
  • Related