// File: /workspace/github_c_makefile_star2_O0/sos22[P]unexec/unexec.c
// Function: unexec_core
static int unexec_core(const char * path, struct new_environment * env) {
    int r;
    r = -1;
    struct trampoline * tramp = MAP_FAILED;
    size_t sz = 0;
    char * mappings_str = read_file("/proc/self/maps");
    if (!mappings_str) goto end;
    /* Start with an allocator which can't do anything, even though we
     * know it'll fail, mostly so that that path gets tested. */
    size_t extra_sz = 0;
    while (true) {
        sz = sizeof(*tramp) + extra_sz;
        sz = (sz + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
        /* We need this to be below all other mappings, so that it
         * doesn't affect initial brk, but not so low the kernel stops
         * us mapping it. Guess 16 pages from the bottom is safe. */
        tramp = mmap((void *)(PAGE_SIZE * 16),
                     sz,
                     PROT_READ|PROT_WRITE,
                     MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,
                     -1,
                     0);
        if (tramp == MAP_FAILED) goto end;
        if (extra_sz != 0) tramp->allocated = sz - sizeof(*tramp);
        else tramp->allocated = 0;
        if (parse_mappings(mappings_str, tramp) < 0) goto end;
        if (tramp->used <= tramp->allocated) break;
        /* Guessed too small. */
        extra_sz = tramp->used;
        munmap(tramp, sz); }
    place_phdrs(tramp);
    unsigned long brk = getbrk();
    r = write_elf_binary(path, tramp);
    if (r == 0) {
        unsigned long newbrk = getbrk();
        /* This is error-prone and hard to test elsewhere, so assert on it
         * here. */
        assert(brk == newbrk);
        extract_new_environment((void *)tramp + sz, env); }
    if (r == 1) {
        chmod(path, 0700);
        if (env) memset(env, 0, sizeof(*env)); }
  end:
    free_with_mmap(mappings_str);
    if (tramp != MAP_FAILED) munmap(tramp, sz);
    return r; }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0xffffffff, -0x14(%rbp) # imm = 0xFFFFFFFF
movq $-0x1, %rax
movq %rax, -0x20(%rbp)
movq $0x0, -0x28(%rbp)
leaq 0x1ae6(%rip), %rdi      # 0x3057
callq 0x1720
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x1586
jmp 0x16f3
movq $0x0, -0x38(%rbp)
movq -0x38(%rbp), %rax
addq $0x80, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
addq $0x1000, %rax           # imm = 0x1000
subq $0x1, %rax
andq $-0x1000, %rax          # imm = 0xF000
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rsi
movl $0x10000, %edi          # imm = 0x10000
movl $0x3, %edx
movl $0x32, %ecx
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
xorl %eax, %eax
movl %eax, %r9d
callq 0x1080
movq %rax, -0x20(%rbp)
movq $-0x1, %rax
cmpq %rax, -0x20(%rbp)
jne 0x15ed
jmp 0x16f3
cmpq $0x0, -0x38(%rbp)
je 0x1608
movq -0x28(%rbp), %rax
subq $0x80, %rax
movl %eax, %ecx
movq -0x20(%rbp), %rax
movl %ecx, (%rax)
jmp 0x1612
movq -0x20(%rbp), %rax
movl $0x0, (%rax)
movq -0x30(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x1800
cmpl $0x0, %eax
jge 0x1629
jmp 0x16f3
movq -0x20(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x20(%rbp), %rcx
cmpl (%rcx), %eax
ja 0x163a
jmp 0x1657
movq -0x20(%rbp), %rax
movl 0x4(%rax), %eax
movq %rax, -0x38(%rbp)
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x1140
jmp 0x158e
movq -0x20(%rbp), %rdi
callq 0x1e30
callq 0x1f70
movq %rax, -0x40(%rbp)
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x1f90
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
jne 0x16c4
callq 0x1f70
movq %rax, -0x48(%rbp)
movq -0x40(%rbp), %rax
cmpq -0x48(%rbp), %rax
jne 0x1694
jmp 0x16b3
leaq 0x19cc(%rip), %rdi      # 0x3067
leaq 0x196c(%rip), %rsi      # 0x300e
movl $0x30c, %edx            # imm = 0x30C
leaq 0x19c7(%rip), %rcx      # 0x3075
callq 0x10a0
movq -0x20(%rbp), %rdi
addq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2280
cmpl $0x1, -0x14(%rbp)
jne 0x16f1
movq -0x8(%rbp), %rdi
movl $0x1c0, %esi            # imm = 0x1C0
callq 0x1150
cmpq $0x0, -0x10(%rbp)
je 0x16ef
movq -0x10(%rbp), %rdi
xorl %esi, %esi
movl $0x18, %edx
callq 0x10b0
jmp 0x16f1
jmp 0x16f3
movq -0x30(%rbp), %rdi
callq 0x12a0
movq $-0x1, %rax
cmpq %rax, -0x20(%rbp)
je 0x1716
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x1140
movl -0x14(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq
nop