vak: (Default)
[personal profile] vak
Удалось мне наконец с помощью bintrace оттрассировать выполнение простейшей программы на маке с процессором arm-64. Конкретно мак мини M1, но на M2/M3/M4 то же самое будет.

Как выяснилось, в MacOS на новых процессорах ARM невозможно собрать юзерный бинарник статически. То есть линкер-то можно вызвать с флагом -static, и даже выполняемый файл получится, но при запуске он упадёт с диагностикой "Killed: 9".

Так что всё теперь через ж... динамический загрузчик. А он штука серьёзная. Файл трассировки занял, на минуточку, 472 мегабайта. Выполнено 7838857 машинных команд загрузчика и 9 команд программы юзера. Вот она, расплата за гибкость. 😀

Вот такой исходник на ассемблере:
#include <sys/syscall.h>
.text
.align 2
.globl _main
_main:
mov x16, #SYS_write // syscall write(fd, message, size)
mov x0, #1 // file descriptor 1 - stdout
adrp x1, message@PAGE // high 20 bits of message address
add x1, x1, :lo12:message@PAGEOFF // low 12 bits of message address
mov x2, 13 // size
svc 0x80 // do system call

mov x16, #SYS_exit // syscall exit(status)
mov x0, #0 // status - 0
svc 0x80 // do system call
message:
.ascii "Hello world!\n"
Начало трассы:
Starting program: ./demo-arm64-macos
sp = 0x16fdffaf8
cpsr = 0x1000
0x000000010000cb30: 910003e0 mov x0, sp
x0 = 0x16fdffaf8
0x000000010000cb34: 927cec1f and sp, x0, #0xfffffffffffffff0
sp = 0x16fdffaf0
0x000000010000cb38: d280001d mov x29, #0
0x000000010000cb3c: d280001e mov x30, #0
0x000000010000cb40: 14000307 b #0x10000d75c
0x000000010000d75c: d503237f pacibsp
0x000000010000d760: a9bb6ffc stp x28, x27, [sp, #-0x50]!
sp = 0x16fdffaa0
Вот конец трассы. Цветом выделен код пользователя:
0x00000001971b0258:  f94027e8   ldr x8, [sp, #0x48]
x8 = 0x100003f74
0x00000001971b025c: f94033e9 ldr x9, [sp, #0x60]
x9 = 0x1fc3b04d0
0x00000001971b0260: f9400529 ldr x9, [x9, #8]
x9 = 0x1fc3b0150
0x00000001971b0264: b9406920 ldr w0, [x9, #0x68]
x0 = 0x1
0x00000001971b0268: a9470921 ldp x1, x2, [x9, #0x70]
x1 = 0x16fdffb08
x2 = 0x16fdffb18
0x00000001971b026c: f9404123 ldr x3, [x9, #0x80]
x3 = 0x16fdffb98
0x00000001971b0270: d63f091f blraaz x8
lr = 0x1971b0274
0x0000000100003f74: d2800090 mov x16, #4
x16 = 0x4
0x0000000100003f78: d2800020 mov x0, #1
0x0000000100003f7c: 90000001 adrp x1, #0x100003000

x1 = 0x100003000
0x0000000100003f80: 913e6021 add x1, x1, #0xf98
x1 = 0x100003f98
0x0000000100003f84: d28001a2 mov x2, #0xd
x2 = 0xd
0x0000000100003f88: d4001001 svc #0x80
Hello world!
x0 = 0xd
x1 = 0
cpsr = 0x40001000
0x0000000100003f8c: d2800030 mov x16, #1
x16 = 0x1
0x0000000100003f90: d2800000 mov x0, #0
x0 = 0
0x0000000100003f94: d4001001 svc #0x80
Process exited normally.

Date: 2024-12-18 21:05 (UTC)
juan_gandhi: (Default)
From: [personal profile] juan_gandhi
Свирепо. И ты отловил!

Date: 2024-12-18 21:46 (UTC)
spamsink: (Default)
From: [personal profile] spamsink
How exactly is the static executable killed? What happens under gdb, if you first put a breakpoint at the starting address?

Date: 2024-12-18 22:16 (UTC)
spamsink: (Default)
From: [personal profile] spamsink
error: Bad executable (or shared library)

Тонко :)

Date: 2024-12-18 23:24 (UTC)
an_3: (Default)
From: [personal profile] an_3
Ото пан мав час та натхнення.

Date: 2024-12-19 15:41 (UTC)
dmarck: (Default)
From: [personal profile] dmarck
как только что в соседнем чяте процитировали "до чего довёл планету этот фигляр ПэЖэ!"

"начиналось всё с rtld и ASLR"