// File: /workspace/github_c_makefile_star2_O0/krinkinmu[P]64bit/exec.c
// Function: exec
int exec(int argc, const char **argv)
{
	if (argc <= 0)
		return -EINVAL;

	struct fs_file file;

	int rc = vfs_open(argv[0], &file);

	if (rc)
		return -EIO;

	struct elf_hdr hdr;

	rc = read_elf_hdr(&file, &hdr);
	if (rc) {
		vfs_release(&file);
		return rc;
	}

	rc = check_elf_hdr(&hdr);
	if (rc) {
		vfs_release(&file);
		return rc;
	}

	struct mm *new_mm = create_mm();

	if (!new_mm) {
		vfs_release(&file);
		return -ENOMEM;
	}

	rc = setup_stack(new_mm, USER_STACK_SIZE);
	if (rc) {
		release_mm(new_mm);
		vfs_release(&file);
		return rc;
	}

	rc = copy_args(new_mm, argc, argv);
	if (rc) {
		release_mm(new_mm);
		vfs_release(&file);
		return rc;
	}

	rc = load_binary(new_mm, &hdr, &file);
	if (rc) {
		release_mm(new_mm);
		vfs_release(&file);
		return rc;
	}

	struct thread *thread = current();
	struct mm *old_mm = thread->mm;

	thread->mm = new_mm;
	store_pml4(page_paddr(new_mm->pt));
	release_mm(old_mm);

	struct thread_regs *regs = thread_regs(thread);

	memset(regs, 0, sizeof(*regs));
	regs->rip = hdr.e_entry;
	regs->rsp = new_mm->stack_pointer;
	regs->rdi = new_mm->argc;
	regs->rsi = new_mm->argv_addr;
	regs->cs = USER_CS;
	regs->ss = USER_DS;
	regs->rflags = RFLAGS_IF;
	vfs_release(&file);

	return rc;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x0, -0x8(%rbp)
jg 0xffffffff80110f84
movl $0xfffffffa, -0x4(%rbp) # imm = 0xFFFFFFFA
jmp 0xffffffff801111c6
movq -0x10(%rbp), %rax
movq (%rax), %rdi
leaq -0x30(%rbp), %rsi
callq 0xffffffff80109ab0
movl %eax, -0x34(%rbp)
cmpl $0x0, -0x34(%rbp)
je 0xffffffff80110fa9
movl $0xfffffff9, -0x4(%rbp) # imm = 0xFFFFFFF9
jmp 0xffffffff801111c6
leaq -0x30(%rbp), %rdi
leaq -0x74(%rbp), %rsi
callq 0xffffffff801111e0
movl %eax, -0x34(%rbp)
cmpl $0x0, -0x34(%rbp)
je 0xffffffff80110fd3
leaq -0x30(%rbp), %rdi
callq 0xffffffff80109ae0
movl -0x34(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0xffffffff801111c6
leaq -0x74(%rbp), %rdi
callq 0xffffffff80111230
movl %eax, -0x34(%rbp)
cmpl $0x0, -0x34(%rbp)
je 0xffffffff80110ff9
leaq -0x30(%rbp), %rdi
callq 0xffffffff80109ae0
movl -0x34(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0xffffffff801111c6
callq 0xffffffff80110430
movq %rax, -0x80(%rbp)
cmpq $0x0, -0x80(%rbp)
jne 0xffffffff8011101e
leaq -0x30(%rbp), %rdi
callq 0xffffffff80109ae0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xffffffff801111c6
movq -0x80(%rbp), %rdi
movl $0x200000, %esi         # imm = 0x200000
callq 0xffffffff801112b0
movl %eax, -0x34(%rbp)
cmpl $0x0, -0x34(%rbp)
je 0xffffffff80111052
movq -0x80(%rbp), %rdi
callq 0xffffffff80110b30
leaq -0x30(%rbp), %rdi
callq 0xffffffff80109ae0
movl -0x34(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0xffffffff801111c6
movq -0x80(%rbp), %rdi
movl -0x8(%rbp), %esi
movq -0x10(%rbp), %rdx
callq 0xffffffff80111390
movl %eax, -0x34(%rbp)
cmpl $0x0, -0x34(%rbp)
je 0xffffffff80111088
movq -0x80(%rbp), %rdi
callq 0xffffffff80110b30
leaq -0x30(%rbp), %rdi
callq 0xffffffff80109ae0
movl -0x34(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0xffffffff801111c6
movq -0x80(%rbp), %rdi
leaq -0x74(%rbp), %rsi
leaq -0x30(%rbp), %rdx
callq 0xffffffff801116e0
movl %eax, -0x34(%rbp)
cmpl $0x0, -0x34(%rbp)
je 0xffffffff801110bf
movq -0x80(%rbp), %rdi
callq 0xffffffff80110b30
leaq -0x30(%rbp), %rdi
callq 0xffffffff80109ae0
movl -0x34(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0xffffffff801111c6
callq 0xffffffff80108940
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0x90(%rbp)
movq -0x80(%rbp), %rcx
movq -0x88(%rbp), %rax
movq %rcx, 0x40(%rax)
movq -0x80(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0xffffffff801117c0
movq %rax, %rdi
callq 0xffffffff801117a0
movq -0x90(%rbp), %rdi
callq 0xffffffff80110b30
movq -0x88(%rbp), %rdi
callq 0xffffffff80108760
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rdi
xorl %esi, %esi
movl $0xb0, %edx
callq 0xffffffff801017e0
movq -0x5c(%rbp), %rcx
movq -0x98(%rbp), %rax
movq %rcx, 0x88(%rax)
movq -0x80(%rbp), %rax
movq 0x18(%rax), %rcx
movq -0x98(%rbp), %rax
movq %rcx, 0xa0(%rax)
movq -0x80(%rbp), %rax
movslq 0x28(%rax), %rcx
movq -0x98(%rbp), %rax
movq %rcx, 0x70(%rax)
movq -0x80(%rbp), %rax
movq 0x20(%rax), %rcx
movq -0x98(%rbp), %rax
movq %rcx, 0x68(%rax)
movq -0x98(%rbp), %rax
movq $0x1b, 0x90(%rax)
movq -0x98(%rbp), %rax
movq $0x23, 0xa8(%rax)
movq -0x98(%rbp), %rax
movq $0x200, 0x98(%rax) # imm = 0x200
leaq -0x30(%rbp), %rdi
callq 0xffffffff80109ae0
movl -0x34(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xa0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)