Size: a a a

2020 February 13

EG

Emmanuel Goldstein in rust_offtopic
Забавно, пустой мейн gcc -O3 компилирует так:
0000000000001020 <main>:
   1020:  31 c0                  xor    %eax,%eax
   1022:  c3                     retq
   1023:  66 2e 0f 1f 84 00 00   nopw   %cs:0x0(%rax,%rax,1)
   102a:  00 00 00
   102d:  0f 1f 00               nopl   (%rax)

Выглядит, как будто как раз инлайнит __libc_start_main
источник

EG

Emmanuel Goldstein in rust_offtopic
gcc без оптимизаций компилирует так:
0000000000001119 <main>:
   1119:  55                     push   %rbp
   111a:  48 89 e5               mov    %rsp,%rbp
   111d:  b8 00 00 00 00         mov    $0x0,%eax
   1122:  5d                     pop    %rbp
   1123:  c3                     retq
   1124:  66 2e 0f 1f 84 00 00   nopw   %cs:0x0(%rax,%rax,1)
   112b:  00 00 00
   112e:  66 90                  xchg   %ax,%ax

Т. е. всё равно обнуляет return code
источник

r

red75prime in rust_offtopic
В LLVM IR
; playground::main
; Function Attrs: noreturn nonlazybind uwtable
define internal void @_ZN10playground4main17h70cad4f2055e264eE() unnamed_addr #2 {
start:
; call std::process::exit
 tail call void @_ZN3std7process4exit17hf8ff86be877a630cE(i32 1)
 unreachable
}


push rax`это из-за каких-то атрибутов `std::process::exit? Кто-нибудь LLVM IR знает?
источник

EG

Emmanuel Goldstein in rust_offtopic
Кажется, что musl libc не обнуляет %rax
https://git.musl-libc.org/cgit/musl/tree/src/env/__libc_start_main.c#n94
источник

EG

Emmanuel Goldstein in rust_offtopic
Я не знаю, в чём прикол, но C тоже так делает.
    1031:  50                     push   %rax
   1032:  54                     push   %rsp
   1033:  4c 8d 05 66 01 00 00   lea    0x166(%rip),%r8        # 11a0 <__libc_csu_fini>
   103a:  48 8d 0d ef 00 00 00   lea    0xef(%rip),%rcx        # 1130 <__libc_csu_init>
   1041:  48 8d 3d d1 00 00 00   lea    0xd1(%rip),%rdi        # 1119 <main>
   1048:  ff 15 92 2f 00 00      callq  *0x2f92(%rip)        # 3fe0 <__libc_start_main@GLIBC_2.2.5>
источник

EG

Emmanuel Goldstein in rust_offtopic
А потом ещё push %rsp, что вообще противоестественно
источник

EG

Emmanuel Goldstein in rust_offtopic
Причём даже на -O3, то есть это правда зачем-то нужно.
источник

r

red75prime in rust_offtopic
Unwinding может быть?
источник

EG

Emmanuel Goldstein in rust_offtopic
red75prime
Unwinding может быть?
Разверни свою мысль?
источник

r

red75prime in rust_offtopic
Да, не проходит. Если бы был push адреса предыдущего stack frame и адреса процедуры деструкции ресурсов в stack frame, тогда могло бы быть.
источник

EG

Emmanuel Goldstein in rust_offtopic
Да и setjmp() в коде не было
источник

EG

Emmanuel Goldstein in rust_offtopic
О господи, выравнивание стека.
источник

EG

Emmanuel Goldstein in rust_offtopic
На стек пушат мусор, чтобы выровнять его к 16 байтам.
источник

EG

Emmanuel Goldstein in rust_offtopic
Я думаю, так.
источник

EG

Emmanuel Goldstein in rust_offtopic
И это объясняет, почему в начале функции там действительно мусор
источник

BD

Berkus Decker in rust_offtopic
Emmanuel Goldstein
А потом ещё push %rsp, что вообще противоестественно
это оно stack frame сетапит
источник

BD

Berkus Decker in rust_offtopic
потому что дальше внятных фреймов нет
источник

BD

Berkus Decker in rust_offtopic
а так простая проверка при разворачивании - если rsp = pop rsp равно самому себе то дальше ничего нет
источник

EG

Emmanuel Goldstein in rust_offtopic
Ща, я ещё попробую скомпилировать без push %rax. Если моя теория верна, оно упадёт с каким-нибудь плохим сигналом типа ILL
источник

BD

Berkus Decker in rust_offtopic
оке
источник