Why does GCC not putting functions at the begining of the text section in a shared library?

28 Views Asked by At

I have a C source file temp1.c

void foo(void){}

On my AMD64 Archlinux environment I compile this with command gcc -o test1.so -shared test1.c, and generates a shared library test1.so. I then dump the text section of test1.so using command objdump -D -j .text test1.so, and got the following output:

test1.so:     file format elf64-x86-64


Disassembly of section .text:

0000000000001020 <foo-0xc9>:
    1020:       48 8d 3d e1 2f 00 00    lea    0x2fe1(%rip),%rdi        # 4008 <__TMC_END__>
    1027:       48 8d 05 da 2f 00 00    lea    0x2fda(%rip),%rax        # 4008 <__TMC_END__>
    102e:       48 39 f8                cmp    %rdi,%rax
    1031:       74 15                   je     1048 <_init+0x48>
    1033:       48 8b 05 8e 2f 00 00    mov    0x2f8e(%rip),%rax        # 3fc8 <_ITM_deregisterTMCloneTable@Base>
    103a:       48 85 c0                test   %rax,%rax
    103d:       74 09                   je     1048 <_init+0x48>
    103f:       ff e0                   jmp    *%rax
    1041:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
    1048:       c3                      ret
    1049:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
    1050:       48 8d 3d b1 2f 00 00    lea    0x2fb1(%rip),%rdi        # 4008 <__TMC_END__>
    1057:       48 8d 35 aa 2f 00 00    lea    0x2faa(%rip),%rsi        # 4008 <__TMC_END__>
    105e:       48 29 fe                sub    %rdi,%rsi
    1061:       48 89 f0                mov    %rsi,%rax
    1064:       48 c1 ee 3f             shr    $0x3f,%rsi
    1068:       48 c1 f8 03             sar    $0x3,%rax
    106c:       48 01 c6                add    %rax,%rsi
    106f:       48 d1 fe                sar    %rsi
    1072:       74 14                   je     1088 <_init+0x88>
    1074:       48 8b 05 5d 2f 00 00    mov    0x2f5d(%rip),%rax        # 3fd8 <_ITM_registerTMCloneTable@Base>
    107b:       48 85 c0                test   %rax,%rax
    107e:       74 08                   je     1088 <_init+0x88>
    1080:       ff e0                   jmp    *%rax
    1082:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
    1088:       c3                      ret
    1089:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
    1090:       f3 0f 1e fa             endbr64
    1094:       80 3d 6d 2f 00 00 00    cmpb   $0x0,0x2f6d(%rip)        # 4008 <__TMC_END__>
    109b:       75 33                   jne    10d0 <_init+0xd0>
    109d:       55                      push   %rbp
    109e:       48 83 3d 3a 2f 00 00    cmpq   $0x0,0x2f3a(%rip)        # 3fe0 <__cxa_finalize@GLIBC_2.2.5>
    10a5:       00 
    10a6:       48 89 e5                mov    %rsp,%rbp
    10a9:       74 0d                   je     10b8 <_init+0xb8>
    10ab:       48 8b 3d 4e 2f 00 00    mov    0x2f4e(%rip),%rdi        # 4000 <__dso_handle>
    10b2:       ff 15 28 2f 00 00       call   *0x2f28(%rip)        # 3fe0 <__cxa_finalize@GLIBC_2.2.5>
    10b8:       e8 63 ff ff ff          call   1020 <_init+0x20>
    10bd:       c6 05 44 2f 00 00 01    movb   $0x1,0x2f44(%rip)        # 4008 <__TMC_END__>
    10c4:       5d                      pop    %rbp
    10c5:       c3                      ret
    10c6:       66 2e 0f 1f 84 00 00    cs nopw 0x0(%rax,%rax,1)
    10cd:       00 00 00 
    10d0:       c3                      ret
    10d1:       66 66 2e 0f 1f 84 00    data16 cs nopw 0x0(%rax,%rax,1)
    10d8:       00 00 00 00 
    10dc:       0f 1f 40 00             nopl   0x0(%rax)
    10e0:       f3 0f 1e fa             endbr64
    10e4:       e9 67 ff ff ff          jmp    1050 <_init+0x50>

00000000000010e9 <foo>:
    10e9:       55                      push   %rbp
    10ea:       48 89 e5                mov    %rsp,%rbp
    10ed:       90                      nop
    10ee:       5d                      pop    %rbp
    10ef:       c3                      ret

I have two questions regarding this output:

  1. Why are the contents of function foo not put at the beginning of the text section?
  2. What's the meaning of the contents from the beginning of the text section to the beginning of function foo? Is it just some random value, or actually useful?
1

There are 1 best solutions below

0
Employed Russian On

Why are the contents of function foo not put at the beginning of the text section?

Why should it be at the beginning? There is no requirement that foo should be at the start of .text.

What's the meaning of the contents from the beginning of the text section to the beginning of function foo? I

You appear to be running objdump on a stripped version of test1.so. Don't do that (especially if you want to know what's there).

When I run objdump -D -j.text test1-stripped.so, I get output very similar to yours:

Disassembly of section .text:

0000000000001040 <foo-0xb9>:
    1040:       48 8d 3d c1 2f 00 00    lea    0x2fc1(%rip),%rdi        # 4008 <foo+0x2f0f>
    1047:       48 8d 05 ba 2f 00 00    lea    0x2fba(%rip),%rax        # 4008 <foo+0x2f0f>
    104e:       48 39 f8                cmp    %rdi,%rax
    1051:       74 15                   je     1068 <__cxa_finalize@plt+0x38>
    1053:       48 8b 05 7e 2f 00 00    mov    0x2f7e(%rip),%rax        # 3fd8 <foo+0x2edf>
    105a:       48 85 c0                test   %rax,%rax
    105d:       74 09                   je     1068 <__cxa_finalize@plt+0x38>
    105f:       ff e0                   jmp    *%rax
...
    10e8:       c3                      ret
    10e9:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
    10f0:       f3 0f 1e fa             endbr64
    10f4:       e9 77 ff ff ff          jmp    1070 <__cxa_finalize@plt+0x40>

00000000000010f9 <foo>:
    10f9:       55                      push   %rbp
    10fa:       48 89 e5                mov    %rsp,%rbp
    10fd:       90                      nop
    10fe:       5d                      pop    %rbp
    10ff:       c3                      ret

But when I run objdump on unstripped version, I see this:

Disassembly of section .text:

0000000000001040 <deregister_tm_clones>:
    1040:       48 8d 3d c1 2f 00 00    lea    0x2fc1(%rip),%rdi        # 4008 <completed.0>
    1047:       48 8d 05 ba 2f 00 00    lea    0x2fba(%rip),%rax        # 4008 <completed.0>
    104e:       48 39 f8                cmp    %rdi,%rax
    1051:       74 15                   je     1068 <deregister_tm_clones+0x28>
    1053:       48 8b 05 7e 2f 00 00    mov    0x2f7e(%rip),%rax        # 3fd8 <_ITM_deregisterTMCloneTable>
    105a:       48 85 c0                test   %rax,%rax
    105d:       74 09                   je     1068 <deregister_tm_clones+0x28>
    105f:       ff e0                   jmp    *%rax
    1061:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
    1068:       c3                      ret
    1069:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)

0000000000001070 <register_tm_clones>:
    1070:       48 8d 3d 91 2f 00 00    lea    0x2f91(%rip),%rdi        # 4008 <completed.0>
    1077:       48 8d 35 8a 2f 00 00    lea    0x2f8a(%rip),%rsi        # 4008 <completed.0>
    107e:       48 29 fe                sub    %rdi,%rsi
    1081:       48 89 f0                mov    %rsi,%rax
    1084:       48 c1 ee 3f             shr    $0x3f,%rsi
    1088:       48 c1 f8 03             sar    $0x3,%rax
    108c:       48 01 c6                add    %rax,%rsi
    108f:       48 d1 fe                sar    %rsi
    1092:       74 14                   je     10a8 <register_tm_clones+0x38>
    1094:       48 8b 05 35 2f 00 00    mov    0x2f35(%rip),%rax        # 3fd0 <_ITM_registerTMCloneTable>
    109b:       48 85 c0                test   %rax,%rax
    109e:       74 08                   je     10a8 <register_tm_clones+0x38>
    10a0:       ff e0                   jmp    *%rax
    10a2:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
    10a8:       c3                      ret
    10a9:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)

00000000000010b0 <__do_global_dtors_aux>:
    10b0:       f3 0f 1e fa             endbr64
    10b4:       80 3d 4d 2f 00 00 00    cmpb   $0x0,0x2f4d(%rip)        # 4008 <completed.0>
    10bb:       75 2b                   jne    10e8 <__do_global_dtors_aux+0x38>
    10bd:       55                      push   %rbp
    10be:       48 83 3d 02 2f 00 00    cmpq   $0x0,0x2f02(%rip)        # 3fc8 <__cxa_finalize>
    10c5:       00
    10c6:       48 89 e5                mov    %rsp,%rbp
    10c9:       74 0c                   je     10d7 <__do_global_dtors_aux+0x27>
    10cb:       48 8b 3d 2e 2f 00 00    mov    0x2f2e(%rip),%rdi        # 4000 <__dso_handle>
    10d2:       e8 59 ff ff ff          call   1030 <__cxa_finalize@plt>
    10d7:       e8 64 ff ff ff          call   1040 <deregister_tm_clones>
    10dc:       c6 05 25 2f 00 00 01    movb   $0x1,0x2f25(%rip)        # 4008 <completed.0>
    10e3:       5d                      pop    %rbp
    10e4:       c3                      ret
    10e5:       0f 1f 00                nopl   (%rax)
    10e8:       c3                      ret
    10e9:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)

00000000000010f0 <frame_dummy>:
    10f0:       f3 0f 1e fa             endbr64
    10f4:       e9 77 ff ff ff          jmp    1070 <register_tm_clones>

00000000000010f9 <foo>:
    10f9:       55                      push   %rbp
    10fa:       48 89 e5                mov    %rsp,%rbp
    10fd:       90                      nop
    10fe:       5d                      pop    %rbp
    10ff:       c3                      ret

P.S. You should use -fPIC when building shared libraries. You'll have a bad time(TM) if you don't.