Does dynamically-linked binaries use crt in linux?

Issue

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?

Solution

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    %ebp,%ebp
  401526:       49 89 d1                mov    %rdx,%r9
  401529:       5e                      pop    %rsi
  40152a:       48 89 e2                mov    %rsp,%rdx
  40152d:       48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
  401531:       50                      push   %rax
  401532:       54                      push   %rsp
  401533:       45 31 c0                xor    %r8d,%r8d
  401536:       31 c9                   xor    %ecx,%ecx
+ objdump -D dynamic.out
+ grep -C10 '<_start>:'
    1026:       ff 25 e4 2f 00 00       jmp    *0x2fe4(%rip)        # 4010 <_GLOBAL_OFFSET_TABLE_+0x10>
    102c:       0f 1f 40 00             nopl   0x0(%rax)

0000000000001030 <[email protected]>:
    1030:       ff 25 e2 2f 00 00       jmp    *0x2fe2(%rip)        # 4018 <[email protected]_2.2.5>
    1036:       68 00 00 00 00          push   $0x0
    103b:       e9 e0 ff ff ff          jmp    1020 <_init+0x20>

Disassembly of section .text:

0000000000001040 <_start>:
    1040:       f3 0f 1e fa             endbr64 
    1044:       31 ed                   xor    %ebp,%ebp
    1046:       49 89 d1                mov    %rdx,%r9
    1049:       5e                      pop    %rsi
    104a:       48 89 e2                mov    %rsp,%rdx
    104d:       48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
    1051:       50                      push   %rax
    1052:       54                      push   %rsp
    1053:       45 31 c0                xor    %r8d,%r8d
    1056:       31 c9                   xor    %ecx,%ecx

We can learn that:

  • static.out is static executable
  • dynamic.out is dynamic executable
  • both executables include code for _start symbol
  • _start symbol comes from crt

Ergo, both executables include crt inside them.

Answered By – KamilCuk

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published