linuxdynamic-linkingcrt

Does dynamically-linked binaries use crt in linux?


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 <puts@plt>:
        1030:       ff 25 e2 2f 00 00       jmp    *0x2fe2(%rip)        # 4018 <puts@GLIBC_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:

    Ergo, both executables include crt inside them.