cc_amd64: fix stack alignment and save non-volatile registers.

This commit is contained in:
Andrius Štikonas 2023-12-23 23:09:33 +00:00
parent 8247a28f78
commit 1407f92220
Signed by: andrius
GPG Key ID: 0C0331D5228A3B62
16 changed files with 176 additions and 69 deletions

View File

@ -402,7 +402,7 @@ DEFINE xor_r13,r13 4D31ED
push_rsp # align stack to 16 bytes push_rsp # align stack to 16 bytes
push_[rsp] # align stack to 16 bytes push_[rsp] # align stack to 16 bytes
and_rsp, !-16 # align stack to 16 bytes and_rsp, !-16 # align stack to 16 bytes
sub_rsp, !32 # allocate shadow stack space for UEFI sub_rsp, !32 # allocate shadow stack space for UEFI function
call_[rcx+BYTE] !32 # fin->read() call_[rcx+BYTE] !32 # fin->read()
mov_rsp,[rsp+BYTE] !40 # deallocate stack mov_rsp,[rsp+BYTE] !40 # deallocate stack
pop_rax # save input to rax pop_rax # save input to rax
@ -1169,7 +1169,7 @@ DEFINE xor_r13,r13 4D31ED
push_rsp # align stack to 16 bytes push_rsp # align stack to 16 bytes
push_[rsp] # align stack to 16 bytes push_[rsp] # align stack to 16 bytes
and_rsp, !-16 # align stack to 16 bytes and_rsp, !-16 # align stack to 16 bytes
sub_rsp, !32 # allocate shadow stack space for UEFI sub_rsp, !32 # allocate shadow stack space for UEFI function
call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool)
mov_rsp,[rsp+BYTE] !40 # deallocate stack mov_rsp,[rsp+BYTE] !40 # deallocate stack
pop_rax # get pool pop_rax # get pool
@ -1181,7 +1181,7 @@ DEFINE xor_r13,r13 4D31ED
push_rsp # align stack to 16 bytes push_rsp # align stack to 16 bytes
push_[rsp] # align stack to 16 bytes push_[rsp] # align stack to 16 bytes
and_rsp, !-16 # align stack to 16 bytes and_rsp, !-16 # align stack to 16 bytes
sub_rsp, !32 # allocate shadow stack space for UEFI sub_rsp, !32 # allocate shadow stack space for UEFI function
call_[r14+BYTE] !72 # system->boot->free_pool(pool) call_[r14+BYTE] !72 # system->boot->free_pool(pool)
mov_rsp,[rsp+BYTE] !40 # deallocate stack mov_rsp,[rsp+BYTE] !40 # deallocate stack
ret ret

View File

@ -252,7 +252,7 @@ fgetc:
push rsp # align stack to 16 bytes push rsp # align stack to 16 bytes
push [rsp] # align stack to 16 bytes push [rsp] # align stack to 16 bytes
and rsp, -16 # align stack to 16 bytes and rsp, -16 # align stack to 16 bytes
sub rsp, 32 # allocate shadow stack space for UEFI sub rsp, 32 # allocate shadow stack space for UEFI function
call [rcx+32] # fin->read() call [rcx+32] # fin->read()
mov rsp, [rsp+40] # deallocate stack mov rsp, [rsp+40] # deallocate stack
pop rax # save input to rax pop rax # save input to rax
@ -958,7 +958,7 @@ fputc:
mov rdx, rsp # arg2 = &size mov rdx, rsp # arg2 = &size
push rax # allocate stack push rax # allocate stack
mov r8, rsp # arg3 = &output mov r8, rsp # arg3 = &output
sub rsp, 32 # allocate shadow stack space for UEFI sub rsp, 32 # allocate shadow stack space for UEFI function
call [rcx+40] # fout->write() call [rcx+40] # fout->write()
mov rsp, [rsp+56] # deallocate stack mov rsp, [rsp+56] # deallocate stack
@ -1019,7 +1019,7 @@ allocate_pool:
push rsp # align stack to 16 bytes push rsp # align stack to 16 bytes
push [rsp] # align stack to 16 bytes push [rsp] # align stack to 16 bytes
and rsp, -16 # align stack to 16 bytes and rsp, -16 # align stack to 16 bytes
sub rsp, 32 # allocate shadow stack space for UEFI sub rsp, 32 # allocate shadow stack space for UEFI function
call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool)
mov rsp, [rsp+40] # deallocate stack mov rsp, [rsp+40] # deallocate stack
pop rax # get pool pop rax # get pool

View File

@ -294,7 +294,7 @@ DEFINE xor_r9,r9 4D31C9
push_rsp # align stack to 16 bytes push_rsp # align stack to 16 bytes
push_[rsp] # align stack to 16 bytes push_[rsp] # align stack to 16 bytes
and_rsp, !-16 # align stack to 16 bytes and_rsp, !-16 # align stack to 16 bytes
sub_rsp, !32 # allocate shadow stack space for UEFI sub_rsp, !32 # allocate shadow stack space for UEFI function
call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool)
mov_rsp,[rsp+BYTE] !40 # deallocate stack mov_rsp,[rsp+BYTE] !40 # deallocate stack
pop_rax # get pool pop_rax # get pool
@ -306,7 +306,7 @@ DEFINE xor_r9,r9 4D31C9
push_rsp # align stack to 16 bytes push_rsp # align stack to 16 bytes
push_[rsp] # align stack to 16 bytes push_[rsp] # align stack to 16 bytes
and_rsp, !-16 # align stack to 16 bytes and_rsp, !-16 # align stack to 16 bytes
sub_rsp, !32 # allocate shadow stack space for UEFI sub_rsp, !32 # allocate shadow stack space for UEFI function
call_[r14+BYTE] !72 # system->boot->free_pool(pool) call_[r14+BYTE] !72 # system->boot->free_pool(pool)
mov_rsp,[rsp+BYTE] !40 # deallocate stack mov_rsp,[rsp+BYTE] !40 # deallocate stack
ret ret
@ -323,7 +323,7 @@ DEFINE xor_r9,r9 4D31C9
push_rsp # align stack to 16 bytes push_rsp # align stack to 16 bytes
push_[rsp] # align stack to 16 bytes push_[rsp] # align stack to 16 bytes
and_rsp, !-16 # align stack to 16 bytes and_rsp, !-16 # align stack to 16 bytes
sub_rsp, !32 # allocate shadow stack space for UEFI sub_rsp, !32 # allocate shadow stack space for UEFI function
call_[rcx+BYTE] !32 # fin->read() call_[rcx+BYTE] !32 # fin->read()
mov_rsp,[rsp+BYTE] !40 # deallocate stack mov_rsp,[rsp+BYTE] !40 # deallocate stack
pop_rax # save size to rax pop_rax # save size to rax
@ -341,7 +341,7 @@ DEFINE xor_r9,r9 4D31C9
push_rsp # align stack to 16 bytes push_rsp # align stack to 16 bytes
push_[rsp] # align stack to 16 bytes push_[rsp] # align stack to 16 bytes
and_rsp, !-16 # align stack to 16 bytes and_rsp, !-16 # align stack to 16 bytes
sub_rsp, !32 # allocate shadow stack space for UEFI sub_rsp, !32 # allocate shadow stack space for UEFI function
call_[rcx+BYTE] !40 # fin->write() call_[rcx+BYTE] !40 # fin->write()
mov_rsp,[rsp+BYTE] !40 # deallocate stack mov_rsp,[rsp+BYTE] !40 # deallocate stack
pop_rax # save size to rax pop_rax # save size to rax

View File

@ -218,7 +218,7 @@ allocate_pool:
push rsp # align stack to 16 bytes push rsp # align stack to 16 bytes
push [rsp] # align stack to 16 bytes push [rsp] # align stack to 16 bytes
and rsp, -16 # align stack to 16 bytes and rsp, -16 # align stack to 16 bytes
sub rsp, 32 # allocate shadow stack space for UEFI sub rsp, 32 # allocate shadow stack space for UEFI function
call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool)
mov rsp, [rsp+40] # deallocate stack mov rsp, [rsp+40] # deallocate stack
pop rax # get pool pop rax # get pool
@ -247,7 +247,7 @@ read:
push rsp # align stack to 16 bytes push rsp # align stack to 16 bytes
push [rsp] # align stack to 16 bytes push [rsp] # align stack to 16 bytes
and rsp, -16 # align stack to 16 bytes and rsp, -16 # align stack to 16 bytes
sub rsp, 32 # allocate shadow stack space for UEFI sub rsp, 32 # allocate shadow stack space for UEFI function
call [rcx+32] # fin->read() call [rcx+32] # fin->read()
mov rsp, [rsp+40] # deallocate stack mov rsp, [rsp+40] # deallocate stack
pop rax # save size to rax pop rax # save size to rax
@ -265,7 +265,7 @@ write:
push rsp # align stack to 16 bytes push rsp # align stack to 16 bytes
push [rsp] # align stack to 16 bytes push [rsp] # align stack to 16 bytes
and rsp, -16 # align stack to 16 bytes and rsp, -16 # align stack to 16 bytes
sub rsp, 32 # allocate shadow stack space for UEFI sub rsp, 32 # allocate shadow stack space for UEFI function
call [rcx+40] # fin->write() call [rcx+40] # fin->write()
mov rsp, [rsp+40] # deallocate stack mov rsp, [rsp+40] # deallocate stack
pop rax # save size to rax pop rax # save size to rax

View File

@ -42,7 +42,17 @@
# efi_main(void *image_handle, struct efi_system_table *system) # efi_main(void *image_handle, struct efi_system_table *system)
_start: _start:
# Save non-volatile registers
push rbp
push rbx
push rdi
push rsi
push r12
push r13
push r14
push r15
mov rbp, rsp # save stack pointer mov rbp, rsp # save stack pointer
mov [rip+image_handle], rcx # save image_handle mov [rip+image_handle], rcx # save image_handle
mov [rip+system], rdx # save system mov [rip+system], rdx # save system
mov r14, [rdx+96] # system->boot mov r14, [rdx+96] # system->boot
@ -64,9 +74,9 @@ _start:
# Get root directory # Get root directory
lea rdx, [rip+rootdir] # arg2 = &rootdir lea rdx, [rip+rootdir] # arg2 = &rootdir
sub rsp, 16 # allocate shadow stack space for UEFI function sub rsp, 40 # allocate shadow stack space for UEFI function
call [rcx+8] # rootfs->open_volume(rootfs, &rootdir) call [rcx+8] # rootfs->open_volume(rootfs, &rootdir)
add rsp, 16 # deallocate stack add rsp, 40 # deallocate stack
# Push command line arguments onto stack # Push command line arguments onto stack
mov rbx, [rdi+56] # options = image->load_options mov rbx, [rdi+56] # options = image->load_options
@ -86,8 +96,11 @@ loop_options:
jmp loop_options # next argument jmp loop_options # next argument
loop_options_done: loop_options_done:
# Open file for reading
pop r8 # arg3 = in pop r8 # arg3 = in
pop r12 # file out
and rsp, -16 # align stack to 16 bytes
# Open file for reading
push 1 # Set exit code in case of failure push 1 # Set exit code in case of failure
cmp r8, 0 # If NULL cmp r8, 0 # If NULL
je failed_input # then exit je failed_input # then exit
@ -102,7 +115,7 @@ loop_options_done:
add rsp, 48 # deallocate stack add rsp, 48 # deallocate stack
# Open file for writing # Open file for writing
pop r8 # arg3 = out mov r8, r12 # arg3 = out
push 1 # Set exit code in case of failure push 1 # Set exit code in case of failure
cmp r8, 0 # If NULL cmp r8, 0 # If NULL
je failed_output # then exit je failed_output # then exit
@ -200,7 +213,17 @@ failed_input:
pop rax # restore exit code pop rax # restore exit code
abort: # used for debugging only abort: # used for debugging only
mov rsp, rbp # restore stack
# Restore non-volatile registers
mov rsp, rbp
pop r15
pop r14
pop r13
pop r12
pop rsi
pop rdi
pop rbx
pop rbp
ret # return to UEFI ret # return to UEFI
@ -642,9 +665,12 @@ fgetc:
mov rdx, rsp # arg2 = &size mov rdx, rsp # arg2 = &size
push 0 # zero rsi push 0 # zero rsi
mov r8, rsp # arg3 = &input mov r8, rsp # arg3 = &input
sub rsp, 24 # allocate shadow stack space for UEFI function push rsp # align stack to 16 bytes
push [rsp] # align stack to 16 bytes
and rsp, -16 # align stack to 16 bytes
sub rsp, 32 # allocate shadow stack space for UEFI function
call [rcx+32] # fin->read() call [rcx+32] # fin->read()
add rsp, 24 # deallocate stack mov rsp, [rsp+40] # deallocate stack
pop rax # save input to rax pop rax # save input to rax
pop rsi # save size to rsi pop rsi # save size to rsi
@ -748,9 +774,12 @@ fputc:
mov rcx, [rcx+64] # system->out (system->err doesn't print anything for some reason) mov rcx, [rcx+64] # system->out (system->err doesn't print anything for some reason)
mov [rip+WCHAR], rax # Convert to WCHAR mov [rip+WCHAR], rax # Convert to WCHAR
lea rdx, [rip+WCHAR] # arg3 = *WCHAR lea rdx, [rip+WCHAR] # arg3 = *WCHAR
sub rsp, 16 # allocate shadow stack space for UEFI function push rsp # align stack to 16 bytes
push [rsp] # align stack to 16 bytes
and rsp, -16 # align stack to 16 bytes
sub rsp, 32 # allocate shadow stack space for UEFI function
call [rcx+8] # system->err->output_string(system->err, WCHAR*) call [rcx+8] # system->err->output_string(system->err, WCHAR*)
add rsp, 16 # deallocate stack mov rsp, [rsp+40] # deallocate stack
popf # Restore condition popf # Restore condition
jne fputc_done # We are done if not LF jne fputc_done # We are done if not LF
@ -759,14 +788,17 @@ fputc:
jmp fputc_done # We are done jmp fputc_done # We are done
fputc_file: fputc_file:
push rsp # align stack to 16 bytes
push [rsp] # align stack to 16 bytes
and rsp, -16 # align stack to 16 bytes
mov rcx, [rip+fout] # arg1 = fout mov rcx, [rip+fout] # arg1 = fout
push 1 # set size push 1 # set size
mov rdx, rsp # arg2 = &size mov rdx, rsp # arg2 = &size
push rax # allocate stack push rax # allocate stack
mov r8, rsp # arg3 = &output mov r8, rsp # arg3 = &output
sub rsp, 24 # allocate shadow stack space for UEFI function sub rsp, 32 # allocate shadow stack space for UEFI function
call [rcx+40] # fout->write() call [rcx+40] # fout->write()
add rsp, 40 # deallocate stack mov rsp, [rsp+56] # deallocate stack
fputc_done: fputc_done:
pop rdx # Restore RDX pop rdx # Restore RDX
@ -4540,9 +4572,12 @@ Exit_Failure:
# rcx: file handle # rcx: file handle
close_file: close_file:
push rax # allocate shadow stack space for UEFI function push rsp # align stack to 16 bytes
push [rsp] # align stack to 16 bytes
and rsp, -16 # align stack to 16 bytes
sub rsp, 32 # allocate shadow stack space for UEFI function
call [rcx+16] # file_handle->close(file_handle) call [rcx+16] # file_handle->close(file_handle)
pop rax # deallocate stack mov rsp, [rsp+40] # deallocate stack
ret ret
# rcx: handle # rcx: handle
@ -4552,11 +4587,14 @@ close_file:
open_protocol: open_protocol:
push rax # allocate stack for interface push rax # allocate stack for interface
mov r8, rsp # arg3 = &interface mov r8, rsp # arg3 = &interface
push rsp # align stack to 16 bytes
push [rsp] # align stack to 16 bytes
and rsp, -16 # align stack to 16 bytes
push 1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL push 1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
push 0 # arg5 = NULL push 0 # arg5 = NULL
sub rsp, 32 # allocate shadow stack space for UEFI function sub rsp, 32 # allocate shadow stack space for UEFI function
call [r14+280] # system->boot->open_protocol(handle, &guid, &interface, agent_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) call [r14+280] # system->boot->open_protocol(handle, &guid, &interface, agent_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL)
add rsp, 48 # deallocate stack mov rsp, [rsp+56] # deallocate stack
pop rax # get interface pop rax # get interface
ret ret
@ -4564,10 +4602,13 @@ open_protocol:
# rdx: &guid # rdx: &guid
# r8: agent_handle # r8: agent_handle
close_protocol: close_protocol:
push rsp # align stack to 16 bytes
push [rsp] # align stack to 16 bytes
and rsp, -16 # align stack to 16 bytes
mov r9, 0 # arg4 = NULL mov r9, 0 # arg4 = NULL
sub rsp, 32 # allocate shadow stack space for UEFI function sub rsp, 32 # allocate shadow stack space for UEFI function
call [r14+288] # system->boot->close_protocol(handle, &guid, agent_handle, 0) call [r14+288] # system->boot->close_protocol(handle, &guid, agent_handle, 0)
add rsp, 32 # deallocate stack mov rsp, [rsp+40] # deallocate stack
ret ret
# rdx: number of bytes to allocate # rdx: number of bytes to allocate
@ -4577,18 +4618,24 @@ allocate_pool:
push rdx # allocate stack for pool pointer push rdx # allocate stack for pool pointer
mov r8, rsp # arg3 = &pool mov r8, rsp # arg3 = &pool
mov rcx, 2 # arg1 = EFI_LOADER_DATA mov rcx, 2 # arg1 = EFI_LOADER_DATA
sub rsp, 24 # allocate shadow stack space for UEFI push rsp # align stack to 16 bytes
push [rsp] # align stack to 16 bytes
and rsp, -16 # align stack to 16 bytes
sub rsp, 32 # allocate shadow stack space for UEFI function
call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool)
add rsp, 24 # deallocate stack mov rsp, [rsp+40] # deallocate stack
pop rax # get pool pop rax # get pool
ret ret
# rcx: memory pool # rcx: memory pool
# r14: system->boot # r14: system->boot
free_pool: free_pool:
push rax # allocate shadow stack space for UEFI function push rsp # align stack to 16 bytes
push [rsp] # align stack to 16 bytes
and rsp, -16 # align stack to 16 bytes
sub rsp, 32 # allocate shadow stack space for UEFI function
call [r14+72] # system->boot->free_pool(pool) call [r14+72] # system->boot->free_pool(pool)
pop rax # deallocate stack mov rsp, [rsp+40] # deallocate stack
ret ret
# Switch to uefi stack # Switch to uefi stack

View File

@ -123,7 +123,7 @@ loop_options_done:
mov dh, 0x8 # arg2 = 256 * 8 = 2048 = 0x800 mov dh, 0x8 # arg2 = 256 * 8 = 2048 = 0x800
push 2 push 2
pop rcx # arg1 = EFI_LOADER_DATA pop rcx # arg1 = EFI_LOADER_DATA
sub rsp, 32 # allocate shadow stack space for UEFI sub rsp, 32 # allocate shadow stack space for UEFI function
call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &table) call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &table)
add rsp, 32 # deallocate stack add rsp, 32 # deallocate stack
@ -135,7 +135,7 @@ loop_options_done:
# rewind input file # rewind input file
mov rcx, rdi # Using our input file mov rcx, rdi # Using our input file
xor edx, edx # Offset Zero xor edx, edx # Offset Zero
sub rsp, 32 # allocate shadow stack space for UEFI sub rsp, 32 # allocate shadow stack space for UEFI function
call [rcx+56] # fin->set_position(fin, 0) call [rcx+56] # fin->set_position(fin, 0)
add rsp, 32 # deallocate stack add rsp, 32 # deallocate stack

View File

@ -119,7 +119,7 @@
B6 08 ; mov_dh, !0x8 # arg2 = 256 * 8 = 2048 = 0x800 B6 08 ; mov_dh, !0x8 # arg2 = 256 * 8 = 2048 = 0x800
6A 02 ; push !2 6A 02 ; push !2
59 ; pop_rcx # arg1 = EFI_LOADER_DATA 59 ; pop_rcx # arg1 = EFI_LOADER_DATA
4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function
41FF56 40 ; call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &table) 41FF56 40 ; call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &table)
4883C4 20 ; add_rsp, !32 # deallocate stack 4883C4 20 ; add_rsp, !32 # deallocate stack
@ -131,7 +131,7 @@
# rewind input file # rewind input file
4889F9 ; mov_rcx,rdi # Using our input file 4889F9 ; mov_rcx,rdi # Using our input file
31D2 ; xor_edx,edx # Offset Zero 31D2 ; xor_edx,edx # Offset Zero
4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function
FF51 38 ; call_[rcx+BYTE] !56 # fin->set_position(fin, 0) FF51 38 ; call_[rcx+BYTE] !56 # fin->set_position(fin, 0)
4883C4 20 ; add_rsp, !32 # deallocate stack 4883C4 20 ; add_rsp, !32 # deallocate stack

View File

@ -817,7 +817,7 @@ DEFINE xor_r9,r9 4D31C9
push_rsp # align stack to 16 bytes push_rsp # align stack to 16 bytes
push_[rsp] # align stack to 16 bytes push_[rsp] # align stack to 16 bytes
and_rsp, !-16 # align stack to 16 bytes and_rsp, !-16 # align stack to 16 bytes
sub_rsp, !32 # allocate shadow stack space for UEFI sub_rsp, !32 # allocate shadow stack space for UEFI function
call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool)
mov_rsp,[rsp+BYTE] !40 # deallocate stack mov_rsp,[rsp+BYTE] !40 # deallocate stack
pop_rax # get pool pop_rax # get pool

View File

@ -692,7 +692,7 @@ allocate_pool:
push rsp # align stack to 16 bytes push rsp # align stack to 16 bytes
push [rsp] # align stack to 16 bytes push [rsp] # align stack to 16 bytes
and rsp, -16 # align stack to 16 bytes and rsp, -16 # align stack to 16 bytes
sub rsp, 32 # allocate shadow stack space for UEFI sub rsp, 32 # allocate shadow stack space for UEFI function
call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool)
mov rsp, [rsp+40] # deallocate stack mov rsp, [rsp+40] # deallocate stack
pop rax # get pool pop rax # get pool

View File

@ -51,7 +51,7 @@ _start:
# Get root directory # Get root directory
lea rdx, [rip+rootdir] # arg2 = &rootdir lea rdx, [rip+rootdir] # arg2 = &rootdir
sub rsp, 32 # allocate shadow stack space for UEFI sub rsp, 32 # allocate shadow stack space for UEFI function
call [rcx+8] # rootfs->open_volume(rootfs, &rootdir) call [rcx+8] # rootfs->open_volume(rootfs, &rootdir)
add rsp, 32 # deallocate stack add rsp, 32 # deallocate stack

View File

@ -379,7 +379,7 @@
:File_Print :File_Print
488B0D %system_out ; mov_rcx,[rip+DWORD] %system_out # get system_out 488B0D %system_out ; mov_rcx,[rip+DWORD] %system_out # get system_out
4883EC 28 ; sub_rsp, !40 # allocate shadow stack space for UEFI 4883EC 28 ; sub_rsp, !40 # allocate shadow stack space for UEFI function
FF51 08 ; call_[rcx+BYTE] !8 # system->out->output_string(system->out, WCHAR*) FF51 08 ; call_[rcx+BYTE] !8 # system->out->output_string(system->out, WCHAR*)
4883C4 28 ; add_rsp, !40 # deallocate stack 4883C4 28 ; add_rsp, !40 # deallocate stack
C3 ; ret C3 ; ret

View File

@ -1014,7 +1014,7 @@
54 ; push_rsp # align stack to 16 bytes 54 ; push_rsp # align stack to 16 bytes
FF3424 ; push_[rsp] # align stack to 16 bytes FF3424 ; push_[rsp] # align stack to 16 bytes
4883E4 F0 ; and_rsp, !-16 # align stack to 16 bytes 4883E4 F0 ; and_rsp, !-16 # align stack to 16 bytes
4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function
41FF56 40 ; call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) 41FF56 40 ; call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool)
488B6424 28 ; mov_rsp,[rsp+BYTE] !40 # deallocate stack 488B6424 28 ; mov_rsp,[rsp+BYTE] !40 # deallocate stack
58 ; pop_rax # get pool 58 ; pop_rax # get pool
@ -1026,7 +1026,7 @@
54 ; push_rsp # align stack to 16 bytes 54 ; push_rsp # align stack to 16 bytes
FF3424 ; push_[rsp] # align stack to 16 bytes FF3424 ; push_[rsp] # align stack to 16 bytes
4883E4 F0 ; and_rsp, !-16 # align stack to 16 bytes 4883E4 F0 ; and_rsp, !-16 # align stack to 16 bytes
4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function
41FF56 48 ; call_[r14+BYTE] !72 # system->boot->free_pool(pool) 41FF56 48 ; call_[r14+BYTE] !72 # system->boot->free_pool(pool)
488B6424 28 ; mov_rsp,[rsp+BYTE] !40 # deallocate stack 488B6424 28 ; mov_rsp,[rsp+BYTE] !40 # deallocate stack
C3 ; ret C3 ; ret

View File

@ -26,9 +26,10 @@ DEFINE add_rax,rbx 4801D8
DEFINE add_rax,rcx 4801C8 DEFINE add_rax,rcx 4801C8
DEFINE add_rbx,rax 4801C3 DEFINE add_rbx,rax 4801C3
DEFINE add_rcx,rdi 4801F9 DEFINE add_rcx,rdi 4801F9
DEFINE and_rax, 4825
DEFINE and_rax,rbx 4821D8
DEFINE add_rbx,[rdi+BYTE] 48035F DEFINE add_rbx,[rdi+BYTE] 48035F
DEFINE and_rax, 4825
DEFINE and_rsp, 4883E4
DEFINE and_rax,rbx 4821D8
DEFINE call E8 DEFINE call E8
DEFINE call_rax FFD0 DEFINE call_rax FFD0
DEFINE call_[rcx+BYTE] FF51 DEFINE call_[rcx+BYTE] FF51
@ -98,6 +99,7 @@ DEFINE mov_rsi,rax 4889C6
DEFINE mov_rsi,rdi 4889FE DEFINE mov_rsi,rdi 4889FE
DEFINE mov_rsp,rbp 4889EC DEFINE mov_rsp,rbp 4889EC
DEFINE mov_r8,rsp 4989E0 DEFINE mov_r8,rsp 4989E0
DEFINE mov_r8,r12 4D89E0
DEFINE mov_r12,rax 4989C4 DEFINE mov_r12,rax 4989C4
DEFINE mov_al,[rax] 8A00 DEFINE mov_al,[rax] 8A00
DEFINE mov_al,[rbx] 8A03 DEFINE mov_al,[rbx] 8A03
@ -141,6 +143,7 @@ DEFINE mov_rcx,[rdi+BYTE] 488B4F
DEFINE mov_rcx,[rdx+BYTE] 488B4A DEFINE mov_rcx,[rdx+BYTE] 488B4A
DEFINE mov_rdi,[rdx+BYTE] 488B7A DEFINE mov_rdi,[rdx+BYTE] 488B7A
DEFINE mov_rdx,[rdx+BYTE] 488B52 DEFINE mov_rdx,[rdx+BYTE] 488B52
DEFINE mov_rsp,[rsp+BYTE] 488B6424
DEFINE mov_r14,[rdx+BYTE] 4C8B72 DEFINE mov_r14,[rdx+BYTE] 4C8B72
DEFINE mov_rax,[rax+DWORD] 488B40 DEFINE mov_rax,[rax+DWORD] 488B40
DEFINE mov_rbx,[rbx+DWORD] 488B5B DEFINE mov_rbx,[rbx+DWORD] 488B5B
@ -179,6 +182,10 @@ DEFINE pop_rdi 5F
DEFINE pop_rdx 5A DEFINE pop_rdx 5A
DEFINE pop_rsi 5E DEFINE pop_rsi 5E
DEFINE pop_r8 4158 DEFINE pop_r8 4158
DEFINE pop_r12 415C
DEFINE pop_r13 415D
DEFINE pop_r14 415E
DEFINE pop_r15 415F
DEFINE push 6A DEFINE push 6A
DEFINE pushf 9C DEFINE pushf 9C
DEFINE push_rax 50 DEFINE push_rax 50
@ -188,6 +195,12 @@ DEFINE push_rcx 51
DEFINE push_rdi 57 DEFINE push_rdi 57
DEFINE push_rdx 52 DEFINE push_rdx 52
DEFINE push_rsi 56 DEFINE push_rsi 56
DEFINE push_rsp 54
DEFINE push_r12 4154
DEFINE push_r13 4155
DEFINE push_r14 4156
DEFINE push_r15 4157
DEFINE push_[rsp] FF3424
DEFINE ret C3 DEFINE ret C3
DEFINE ror_r9 49D1C9 DEFINE ror_r9 49D1C9
DEFINE sal_rax, 48C1E0 DEFINE sal_rax, 48C1E0
@ -226,7 +239,17 @@ DEFINE NULL 0000000000000000
# efi_main(void *image_handle, struct efi_system_table *system) # efi_main(void *image_handle, struct efi_system_table *system)
:_start :_start
# Save non-volatile registers
push_rbp
push_rbx
push_rdi
push_rsi
push_r12
push_r13
push_r14
push_r15
mov_rbp,rsp # save stack pointer mov_rbp,rsp # save stack pointer
mov_[rip+DWORD],rcx %image_handle # save image_handle mov_[rip+DWORD],rcx %image_handle # save image_handle
mov_[rip+DWORD],rdx %system # save system mov_[rip+DWORD],rdx %system # save system
mov_r14,[rdx+BYTE] !96 # system->boot mov_r14,[rdx+BYTE] !96 # system->boot
@ -248,9 +271,9 @@ DEFINE NULL 0000000000000000
# Get root directory # Get root directory
lea_rdx,[rip+DWORD] %rootdir # arg2 = &rootdir lea_rdx,[rip+DWORD] %rootdir # arg2 = &rootdir
sub_rsp, %16 # allocate shadow stack space for UEFI function sub_rsp, %40 # allocate shadow stack space for UEFI function
call_[rcx+BYTE] !8 # rootfs->open_volume(rootfs, &rootdir) call_[rcx+BYTE] !8 # rootfs->open_volume(rootfs, &rootdir)
add_rsp, %16 # deallocate stack add_rsp, %40 # deallocate stack
# Push command line arguments onto stack # Push command line arguments onto stack
mov_rbx,[rdi+BYTE] !56 # options = image->load_options mov_rbx,[rdi+BYTE] !56 # options = image->load_options
@ -270,8 +293,11 @@ DEFINE NULL 0000000000000000
jmp %loop_options # next argument jmp %loop_options # next argument
:loop_options_done :loop_options_done
# Open file for reading
pop_r8 # arg3 = in pop_r8 # arg3 = in
pop_r12 # file out
and_rsp, !-16 # align stack to 16 bytes
# Open file for reading
push !1 # Set exit code in case of failure push !1 # Set exit code in case of failure
cmp_r8, %0 # If NULL cmp_r8, %0 # If NULL
je %failed_input # then exit je %failed_input # then exit
@ -286,7 +312,7 @@ DEFINE NULL 0000000000000000
add_rsp, %48 # deallocate stack add_rsp, %48 # deallocate stack
# Open file for writing # Open file for writing
pop_r8 # arg3 = out mov_r8,r12 # arg3 = out
push !1 # Set exit code in case of failure push !1 # Set exit code in case of failure
cmp_r8, %0 # If NULL cmp_r8, %0 # If NULL
je %failed_output # then exit je %failed_output # then exit
@ -384,7 +410,17 @@ DEFINE NULL 0000000000000000
pop_rax # restore exit code pop_rax # restore exit code
:abort # used for debugging only :abort # used for debugging only
mov_rsp,rbp # restore stack
# Restore non-volatile registers
mov_rsp,rbp
pop_r15
pop_r14
pop_r13
pop_r12
pop_rsi
pop_rdi
pop_rbx
pop_rbp
ret # return to UEFI ret # return to UEFI
@ -850,9 +886,12 @@ DEFINE NULL 0000000000000000
mov_rdx,rsp # arg2 = &size mov_rdx,rsp # arg2 = &size
push !0 # allocate stack push !0 # allocate stack
mov_r8,rsp # arg3 = &input mov_r8,rsp # arg3 = &input
sub_rsp, %24 # allocate shadow stack space for UEFI function push_rsp # align stack to 16 bytes
push_[rsp] # align stack to 16 bytes
and_rsp, !-16 # align stack to 16 bytes
sub_rsp, %32 # allocate shadow stack space for UEFI function
call_[rcx+BYTE] !32 # fin->read() call_[rcx+BYTE] !32 # fin->read()
add_rsp, %24 # deallocate stack mov_rsp,[rsp+BYTE] !40 # deallocate stack
pop_rax # save input to rax pop_rax # save input to rax
pop_rsi # save size to rsi pop_rsi # save size to rsi
@ -956,9 +995,12 @@ DEFINE NULL 0000000000000000
mov_rcx,[rcx+BYTE] !64 # system->out (system->err doesn't print anything for some reason) mov_rcx,[rcx+BYTE] !64 # system->out (system->err doesn't print anything for some reason)
mov_[rip+DWORD],rax %WCHAR # Convert to WCHAR mov_[rip+DWORD],rax %WCHAR # Convert to WCHAR
lea_rdx,[rip+DWORD] %WCHAR # arg3 = *WCHAR lea_rdx,[rip+DWORD] %WCHAR # arg3 = *WCHAR
sub_rsp, %16 # allocate shadow stack space for UEFI function push_rsp # align stack to 16 bytes
push_[rsp] # align stack to 16 bytes
and_rsp, !-16 # align stack to 16 bytes
sub_rsp, %32 # allocate shadow stack space for UEFI function
call_[rcx+BYTE] !8 # system->err->output_string(system->err, WCHAR*) call_[rcx+BYTE] !8 # system->err->output_string(system->err, WCHAR*)
add_rsp, %16 # deallocate stack mov_rsp,[rsp+BYTE] !40 # deallocate stack
popf # Restore condition popf # Restore condition
jne %fputc_done # We are done if not LF jne %fputc_done # We are done if not LF
@ -967,14 +1009,17 @@ DEFINE NULL 0000000000000000
jmp %fputc_done # We are done jmp %fputc_done # We are done
:fputc_file :fputc_file
push_rsp # align stack to 16 bytes
push_[rsp] # align stack to 16 bytes
and_rsp, !-16 # align stack to 16 bytes
mov_rcx,[rip+DWORD] %fout # arg1 = fout mov_rcx,[rip+DWORD] %fout # arg1 = fout
push !1 # set size push !1 # set size
mov_rdx,rsp # arg2 = &size mov_rdx,rsp # arg2 = &size
push_rax # allocate stack push_rax # allocate stack
mov_r8,rsp # arg3 = &output mov_r8,rsp # arg3 = &output
sub_rsp, %24 # allocate shadow stack space for UEFI function sub_rsp, %32 # allocate shadow stack space for UEFI function
call_[rcx+BYTE] !40 # fout->write() call_[rcx+BYTE] !40 # fout->write()
add_rsp, %40 # deallocate stack mov_rsp,[rsp+BYTE] !56 # deallocate stack
:fputc_done :fputc_done
pop_rdx # Restore RDX pop_rdx # Restore RDX
@ -5197,9 +5242,12 @@ Missing ;
# rcx: file handle # rcx: file handle
:close_file :close_file
push_rax # allocate shadow stack space for UEFI function push_rsp # align stack to 16 bytes
push_[rsp] # align stack to 16 bytes
and_rsp, !-16 # align stack to 16 bytes
sub_rsp, %32 # allocate shadow stack space for UEFI function
call_[rcx+BYTE] !16 # file_handle->close(file_handle) call_[rcx+BYTE] !16 # file_handle->close(file_handle)
pop_rax # deallocate stack mov_rsp,[rsp+BYTE] !40 # deallocate stack
ret ret
# rcx: handle # rcx: handle
@ -5209,11 +5257,14 @@ Missing ;
:open_protocol :open_protocol
push_rax # allocate stack for interface push_rax # allocate stack for interface
mov_r8,rsp # arg3 = &interface mov_r8,rsp # arg3 = &interface
push_rsp # align stack to 16 bytes
push_[rsp] # align stack to 16 bytes
and_rsp, !-16 # align stack to 16 bytes
push !1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL push !1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
push !0 # arg5 = NULL push !0 # arg5 = NULL
sub_rsp, %32 # allocate shadow stack space for UEFI function sub_rsp, %32 # allocate shadow stack space for UEFI function
call_[r14+DWORD] %280 # system->boot->open_protocol(handle, &guid, &interface, agent_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) call_[r14+DWORD] %280 # system->boot->open_protocol(handle, &guid, &interface, agent_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL)
add_rsp, %48 # deallocate stack mov_rsp,[rsp+BYTE] !56 # deallocate stack
pop_rax # get interface pop_rax # get interface
ret ret
@ -5221,10 +5272,13 @@ Missing ;
# rdx: &guid # rdx: &guid
# r8: agent_handle # r8: agent_handle
:close_protocol :close_protocol
push_rsp # align stack to 16 bytes
push_[rsp] # align stack to 16 bytes
and_rsp, !-16 # align stack to 16 bytes
mov_r9, %0 # arg4 = NULL mov_r9, %0 # arg4 = NULL
sub_rsp, %32 # allocate shadow stack space for UEFI function sub_rsp, %32 # allocate shadow stack space for UEFI function
call_[r14+DWORD] %288 # system->boot->close_protocol(handle, &guid, agent_handle, 0) call_[r14+DWORD] %288 # system->boot->close_protocol(handle, &guid, agent_handle, 0)
add_rsp, %32 # deallocate stack mov_rsp,[rsp+BYTE] !40 # deallocate stack
ret ret
# rdx: number of bytes to allocate # rdx: number of bytes to allocate
@ -5234,18 +5288,24 @@ Missing ;
push_rdx # allocate stack for pool pointer push_rdx # allocate stack for pool pointer
mov_r8,rsp # arg3 = &pool mov_r8,rsp # arg3 = &pool
mov_rcx, %2 # arg1 = EFI_LOADER_DATA mov_rcx, %2 # arg1 = EFI_LOADER_DATA
sub_rsp, %24 # allocate shadow stack space for UEFI push_rsp # align stack to 16 bytes
push_[rsp] # align stack to 16 bytes
and_rsp, !-16 # align stack to 16 bytes
sub_rsp, %32 # allocate shadow stack space for UEFI function
call_[r14+DWORD] %64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) call_[r14+DWORD] %64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool)
add_rsp, %24 # deallocate stack mov_rsp,[rsp+BYTE] !40 # deallocate stack
pop_rax # get pool pop_rax # get pool
ret ret
# rcx: memory pool # rcx: memory pool
# r14: system->boot # r14: system->boot
:free_pool :free_pool
push_rax # allocate shadow stack space for UEFI function push_rsp # align stack to 16 bytes
push_[rsp] # align stack to 16 bytes
and_rsp, !-16 # align stack to 16 bytes
sub_rsp, %32 # allocate shadow stack space for UEFI function
call_[r14+DWORD] %72 # system->boot->free_pool(pool) call_[r14+DWORD] %72 # system->boot->free_pool(pool)
pop_rax # deallocate stack mov_rsp,[rsp+BYTE] !40 # deallocate stack
ret ret
# Switch to uefi stack # Switch to uefi stack

View File

@ -248,7 +248,7 @@ F0 00 # SizeOfOptionalHeader
B6 08 ; mov_dh, !0x8 # arg2 = 256 * 8 = 2048 = 0x800 B6 08 ; mov_dh, !0x8 # arg2 = 256 * 8 = 2048 = 0x800
6A 02 ; push !2 6A 02 ; push !2
59 ; pop_rcx # arg1 = EFI_LOADER_DATA 59 ; pop_rcx # arg1 = EFI_LOADER_DATA
4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function
41FF56 40 ; call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &table) 41FF56 40 ; call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &table)
4883C4 20 ; add_rsp, !32 # deallocate stack 4883C4 20 ; add_rsp, !32 # deallocate stack
@ -261,7 +261,7 @@ F0 00 # SizeOfOptionalHeader
# rewind input file # rewind input file
4889F9 ; mov_rcx,rdi # Using our input file 4889F9 ; mov_rcx,rdi # Using our input file
31D2 ; xor_edx,edx # Offset Zero 31D2 ; xor_edx,edx # Offset Zero
4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function
FF51 38 ; call_[rcx+BYTE] !56 # fin->set_position(fin, 0) FF51 38 ; call_[rcx+BYTE] !56 # fin->set_position(fin, 0)
4883C4 20 ; add_rsp, !32 # deallocate stack 4883C4 20 ; add_rsp, !32 # deallocate stack

View File

@ -254,7 +254,7 @@ F0 00 # SizeOfOptionalHeader
4153 ; push_r11 # Protect r11 4153 ; push_r11 # Protect r11
488B0D %0 ; mov_rcx,[rip+DWORD] %fin # Using our input file 488B0D %0 ; mov_rcx,[rip+DWORD] %fin # Using our input file
31D2 ; xor_edx,edx # Offset Zero 31D2 ; xor_edx,edx # Offset Zero
4883EC 28 ; sub_rsp, !40 # allocate shadow stack space for UEFI 4883EC 28 ; sub_rsp, !40 # allocate shadow stack space for UEFI function
FF51 38 ; call_[rcx+BYTE] !56 # fin->set_position(fin, 0) FF51 38 ; call_[rcx+BYTE] !56 # fin->set_position(fin, 0)
4883C4 28 ; add_rsp, !40 # deallocate stack 4883C4 28 ; add_rsp, !40 # deallocate stack
415B ; pop_r11 # restore r11 415B ; pop_r11 # restore r11
@ -817,7 +817,7 @@ F0 00 # SizeOfOptionalHeader
54 ; push_rsp # align stack to 16 bytes 54 ; push_rsp # align stack to 16 bytes
FF3424 ; push_[rsp] # align stack to 16 bytes FF3424 ; push_[rsp] # align stack to 16 bytes
4883E4 F0 ; and_rsp, !-16 # align stack to 16 bytes 4883E4 F0 ; and_rsp, !-16 # align stack to 16 bytes
4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function
41FF56 40 ; call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) 41FF56 40 ; call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool)
488B6424 28 ; mov_rsp,[rsp+BYTE] !40 # deallocate stack 488B6424 28 ; mov_rsp,[rsp+BYTE] !40 # deallocate stack
58 ; pop_rax # get pool 58 ; pop_rax # get pool

View File

@ -301,7 +301,7 @@ F0 00 # SizeOfOptionalHeader
5F ; pop_rdi # get fcmd 5F ; pop_rdi # get fcmd
# Restore command line arguments # Restore command line arguments
6641C707 2000 ; STOREI16_into_Address_R15 @0x20 # restore command line options by readding ' ' 6641C707 2000 ; STOREI16_into_Address_R15 @0x20 # restore command line options by readding ' '
# Allocate pool for file_info # Allocate pool for file_info
31D2 ; xor_edx,edx # zero RDX 31D2 ; xor_edx,edx # zero RDX
@ -510,7 +510,7 @@ F0 00 # SizeOfOptionalHeader
# :File_Print [_start+0x361] # :File_Print [_start+0x361]
488B0D E3000000 ; mov_rcx,[rip+DWORD] %system_out # get system_out 488B0D E3000000 ; mov_rcx,[rip+DWORD] %system_out # get system_out
4883EC 28 ; sub_rsp, !40 # allocate shadow stack space for UEFI 4883EC 28 ; sub_rsp, !40 # allocate shadow stack space for UEFI function
FF51 08 ; call_[rcx+BYTE] !8 # system->out->output_string(system->out, WCHAR*) FF51 08 ; call_[rcx+BYTE] !8 # system->out->output_string(system->out, WCHAR*)
4883C4 28 ; add_rsp, !40 # deallocate stack 4883C4 28 ; add_rsp, !40 # deallocate stack
C3 ; ret C3 ; ret