// File: /workspace/github_c_makefile_star2_O0/sos22[P]unexec/unexec.c
// Function: parse_mappings
static int parse_mappings(char * str, struct trampoline * out) {
    out->initialbrk = getbrk();
    out->used = 0;
    /* Every line in the mapping file needs a mapping operation. */
    out->nrmappings = 0;
    for (char * cursor = str; *cursor; cursor++) {
        out->nrmappings += *cursor == '\n'; }
    out->mappings = alloc_in_trampoline(
        sizeof(out->mappings[0]) * out->nrmappings,
        out);
    out->procselfexe = strdup_in_trampoline("/proc/self/exe", out);
    out->trampoline = alloc_trampoline_text(out);
    unsigned nrdone = 0;
    char * line_end;
    errno = 0;
    char * line_start;
    for (line_start = str; *line_start; line_start = line_end + 1) {
        for (line_end = line_start; *line_end != '\n'; line_end++) {
            assert(*line_end); }
        *line_end = '\0';
        char * cursor;
        struct mapping mapping = {};
        mapping.start = strtoul(line_start, &cursor, 16);
        if (*cursor != '-') goto fail;
        cursor++;
        uint64_t end = strtoul(cursor, &cursor, 16);
        if (*cursor != ' ') goto fail;
        mapping.size = end - mapping.start;
        cursor++;
        switch (*cursor) {
        case 'r':
            mapping.prot |= PROT_READ;
            break;
        case '-': break;
        default: goto fail; }
        cursor++;
        switch (*cursor) {
        case 'w':
            mapping.prot |= PROT_WRITE;
            break;
        case '-': break;
        default: goto fail; }
        cursor++;
        switch (*cursor) {
        case 'x':
            mapping.prot |= PROT_EXEC;
            break;
        case '-': break;
        default: goto fail; }
        cursor++;
        switch (*cursor) {
        case 'p':
            mapping.flags = MAP_PRIVATE;
            break;
        case 's':
            mapping.flags = MAP_SHARED;
            break;
        default: goto fail; }
        cursor++;
        if (*cursor != ' ') goto fail;
        cursor++;
        uint64_t offset = strtoul(cursor, &cursor, 16);
        if (*cursor != ' ') goto fail;
        cursor++;
        /*major = */strtoul(cursor, &cursor, 16);
        if (*cursor != ':') goto fail;
        cursor++;
        /*minor = */strtoul(cursor, &cursor, 16);
        if (*cursor != ' ') goto fail;
        cursor++;
        /*inode = */strtoul(cursor, &cursor, 10);
        if (*cursor != ' ') goto fail;
        while (*cursor == ' ') cursor++;
        const char * path = cursor;
        /* Kernel handles vsyscall for us. */
        if (!strcmp(path, "[vsyscall]")) {
            *line_end = '\n';
            continue; }
        if (!strcmp(path, "[stack]")) {
            /* Stack is special: it needs to be GROWS_DOWN to handle
             * future stack expansion, but Linux doesn't let you
             * combine GROWS_DOWN and fd mapping, and has problems if
             * you put a GROWS_DOWN right below a FIXED. Answer: the
             * stack is mapped ANONYMOUS and filled with a pread. */
            mapping.flags |= MAP_ANONYMOUS | MAP_GROWSDOWN; }
        mapping.flags |= MAP_FIXED;
        /* Other things we need to fix up somehow. Options are phdrs
         * and mmaps. */
        /* Phdr is safe for any non-shared mapping. */
        bool can_use_phdr = mapping.flags != MAP_SHARED;
        /* mmap is a bit more tricky: Have to be able to read the
         * file, and if it's private in-memory content needs to
         * match file contents */
        bool can_use_mmap;
        /* No path -> cannot mmap */
        if (strlen(path) == 0) can_use_mmap = false;
        /* Anon -> cannot mmap */
        else if (mapping.flags & MAP_ANONYMOUS) can_use_mmap = false;
        else {
            if (errno) goto fail;
            /* path need to be readable */
            struct stat st;
            if (stat(path, &st) < 0) {
                if (errno != ENOENT) goto fail;
                can_use_mmap = false; }
            else if (!(mapping.prot & PROT_READ)) {
                /* Cannot read map -> assume that mmap is safe */
                can_use_mmap = true; }
            else {
                /* Needs to match backing store. */
                int fd = open(path, O_RDONLY);
                if (fd < 0) goto fail;
                const void * remap = mmap(NULL,
                                          mapping.size,
                                          PROT_READ,
                                          MAP_PRIVATE,
                                          fd,
                                          offset);
                close(fd);
                if (remap == MAP_FAILED) goto fail;
                can_use_mmap =
                    memcmp(remap, (const void *)mapping.start, mapping.size)
                    == 0;
                munmap((void *)remap, mapping.size); }
            errno = 0; }
        if (can_use_mmap) {
            /* If we can use an mmap then do it. */
            mapping.offset = offset;
            mapping.path = strdup_in_trampoline(path, out); }
        else if (can_use_phdr) {
            mapping.path = out->procselfexe; }
        else {
            /* Can't mmap, can't phdr -> we fail */
            goto fail; }
        assert(nrdone < out->nrmappings);
        out->mappings[nrdone] = mapping;
        nrdone++;
        *line_end = '\n'; }
    out->nrmappings = nrdone;
    if (errno) goto fail;
    return 0;
  fail:
    return -1; }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
callq 0x1f70
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rax
movl $0x0, 0x4(%rax)
movq -0x18(%rbp), %rax
movl $0x0, 0x20(%rax)
movq -0x10(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpb $0x0, (%rax)
je 0x1874
movq -0x20(%rbp), %rax
movsbl (%rax), %eax
cmpl $0xa, %eax
sete %al
andb $0x1, %al
movzbl %al, %ecx
movq -0x18(%rbp), %rax
addl 0x20(%rax), %ecx
movl %ecx, 0x20(%rax)
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x1841
movq -0x18(%rbp), %rax
movl 0x20(%rax), %eax
imulq $0x28, %rax, %rdi
movq -0x18(%rbp), %rsi
callq 0x2640
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x18(%rbp), %rsi
leaq 0x183f(%rip), %rdi      # 0x30dd
callq 0x26e0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x18(%rbp), %rdi
callq 0x2740
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x10(%rax)
movl $0x0, -0x24(%rbp)
callq 0x1040
movl $0x0, (%rax)
movq -0x10(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
cmpb $0x0, (%rax)
je 0x1df1
movq -0x38(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movsbl (%rax), %eax
cmpl $0xa, %eax
je 0x1937
movq -0x30(%rbp), %rax
cmpb $0x0, (%rax)
je 0x1908
jmp 0x1927
leaq 0x17dd(%rip), %rdi      # 0x30ec
leaq 0x16f8(%rip), %rsi      # 0x300e
movl $0x19a, %edx            # imm = 0x19A
leaq 0x17d4(%rip), %rcx      # 0x30f6
callq 0x10a0
jmp 0x1929
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x18f1
movq -0x30(%rbp), %rax
movb $0x0, (%rax)
leaq -0x68(%rbp), %rdi
xorl %esi, %esi
movl $0x28, %edx
callq 0x10b0
movq -0x38(%rbp), %rdi
leaq -0x40(%rbp), %rsi
movl $0x10, %edx
callq 0x1170
movq %rax, -0x68(%rbp)
movq -0x40(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
je 0x1975
jmp 0x1e10
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
leaq -0x40(%rbp), %rsi
movl $0x10, %edx
callq 0x1170
movq %rax, -0x70(%rbp)
movq -0x40(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x20, %eax
je 0x19a8
jmp 0x1e10
movq -0x70(%rbp), %rax
movq -0x68(%rbp), %rcx
subq %rcx, %rax
movq %rax, -0x60(%rbp)
movq -0x40(%rbp), %rax
incq %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movsbl (%rax), %eax
movl %eax, -0x12c(%rbp)
subl $0x2d, %eax
je 0x19ee
jmp 0x19d6
movl -0x12c(%rbp), %eax
subl $0x72, %eax
jne 0x19f0
jmp 0x19e3
movl -0x50(%rbp), %eax
orl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0x19f5
jmp 0x19f5
jmp 0x1e10
movq -0x40(%rbp), %rax
incq %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movsbl (%rax), %eax
movl %eax, -0x130(%rbp)
subl $0x2d, %eax
je 0x1a2c
jmp 0x1a14
movl -0x130(%rbp), %eax
subl $0x77, %eax
jne 0x1a2e
jmp 0x1a21
movl -0x50(%rbp), %eax
orl $0x2, %eax
movl %eax, -0x50(%rbp)
jmp 0x1a33
jmp 0x1a33
jmp 0x1e10
movq -0x40(%rbp), %rax
incq %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movsbl (%rax), %eax
movl %eax, -0x134(%rbp)
subl $0x2d, %eax
je 0x1a6a
jmp 0x1a52
movl -0x134(%rbp), %eax
subl $0x78, %eax
jne 0x1a6c
jmp 0x1a5f
movl -0x50(%rbp), %eax
orl $0x4, %eax
movl %eax, -0x50(%rbp)
jmp 0x1a71
jmp 0x1a71
jmp 0x1e10
movq -0x40(%rbp), %rax
incq %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movsbl (%rax), %eax
movl %eax, -0x138(%rbp)
subl $0x70, %eax
je 0x1a9d
jmp 0x1a90
movl -0x138(%rbp), %eax
subl $0x73, %eax
je 0x1aa6
jmp 0x1aaf
movl $0x2, -0x4c(%rbp)
jmp 0x1ab4
movl $0x1, -0x4c(%rbp)
jmp 0x1ab4
jmp 0x1e10
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x20, %eax
je 0x1ad1
jmp 0x1e10
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
leaq -0x40(%rbp), %rsi
movl $0x10, %edx
callq 0x1170
movq %rax, -0x78(%rbp)
movq -0x40(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x20, %eax
je 0x1b04
jmp 0x1e10
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
leaq -0x40(%rbp), %rsi
movl $0x10, %edx
callq 0x1170
movq -0x40(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x3a, %eax
je 0x1b33
jmp 0x1e10
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
leaq -0x40(%rbp), %rsi
movl $0x10, %edx
callq 0x1170
movq -0x40(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x20, %eax
je 0x1b62
jmp 0x1e10
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
leaq -0x40(%rbp), %rsi
movl $0xa, %edx
callq 0x1170
movq -0x40(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x20, %eax
je 0x1b91
jmp 0x1e10
jmp 0x1b93
movq -0x40(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x20, %eax
jne 0x1bad
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0x1b93
movq -0x40(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rdi
leaq 0x1566(%rip), %rsi      # 0x3126
callq 0x1100
cmpl $0x0, %eax
jne 0x1bd6
movq -0x30(%rbp), %rax
movb $0xa, (%rax)
jmp 0x1de0
movq -0x80(%rbp), %rdi
leaq 0x1550(%rip), %rsi      # 0x3131
callq 0x1100
cmpl $0x0, %eax
jne 0x1bf6
movl -0x4c(%rbp), %eax
orl $0x120, %eax            # imm = 0x120
movl %eax, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
orl $0x10, %eax
movl %eax, -0x4c(%rbp)
cmpl $0x1, -0x4c(%rbp)
setne %al
andb $0x1, %al
movb %al, -0x81(%rbp)
movq -0x80(%rbp), %rdi
callq 0x1070
cmpq $0x0, %rax
jne 0x1c29
movb $0x0, -0x82(%rbp)
jmp 0x1d41
movl -0x4c(%rbp), %eax
andl $0x20, %eax
cmpl $0x0, %eax
je 0x1c40
movb $0x0, -0x82(%rbp)
jmp 0x1d3f
callq 0x1040
cmpl $0x0, (%rax)
je 0x1c4f
jmp 0x1e10
movq -0x80(%rbp), %rdi
leaq -0x118(%rbp), %rsi
callq 0x1120
cmpl $0x0, %eax
jge 0x1c7f
callq 0x1040
cmpl $0x2, (%rax)
je 0x1c73
jmp 0x1e10
movb $0x0, -0x82(%rbp)
jmp 0x1d34
movl -0x50(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x1c96
movb $0x1, -0x82(%rbp)
jmp 0x1d32
movq -0x80(%rbp), %rdi
xorl %esi, %esi
movb $0x0, %al
callq 0x1160
movl %eax, -0x11c(%rbp)
cmpl $0x0, -0x11c(%rbp)
jge 0x1cb7
jmp 0x1e10
movq -0x60(%rbp), %rsi
movl -0x11c(%rbp), %r8d
movq -0x78(%rbp), %r9
xorl %eax, %eax
movl %eax, %edi
movl $0x1, %edx
movl $0x2, %ecx
callq 0x1080
movq %rax, -0x128(%rbp)
movl -0x11c(%rbp), %edi
callq 0x10c0
movq $-0x1, %rax
cmpq %rax, -0x128(%rbp)
jne 0x1d00
jmp 0x1e10
movq -0x128(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq -0x60(%rbp), %rdx
callq 0x10f0
cmpl $0x0, %eax
sete %al
andb $0x1, %al
movb %al, -0x82(%rbp)
movq -0x128(%rbp), %rdi
movq -0x60(%rbp), %rsi
callq 0x1140
jmp 0x1d34
callq 0x1040
movl $0x0, (%rax)
jmp 0x1d41
testb $0x1, -0x82(%rbp)
je 0x1d65
movq -0x78(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x80(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x26e0
movq %rax, -0x48(%rbp)
jmp 0x1d83
testb $0x1, -0x81(%rbp)
je 0x1d7c
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x48(%rbp)
jmp 0x1d81
jmp 0x1e10
jmp 0x1d83
movl -0x24(%rbp), %eax
movq -0x18(%rbp), %rcx
cmpl 0x20(%rcx), %eax
jae 0x1d91
jmp 0x1db0
leaq 0x13a1(%rip), %rdi      # 0x3139
leaq 0x126f(%rip), %rsi      # 0x300e
movl $0x20e, %edx            # imm = 0x20E
leaq 0x134b(%rip), %rcx      # 0x30f6
callq 0x10a0
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rdi
movl -0x24(%rbp), %eax
imulq $0x28, %rax, %rax
addq %rax, %rdi
leaq -0x68(%rbp), %rsi
movl $0x28, %edx
callq 0x1130
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
movq -0x30(%rbp), %rax
movb $0xa, (%rax)
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x18dc
movl -0x24(%rbp), %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x20(%rax)
callq 0x1040
cmpl $0x0, (%rax)
je 0x1e07
jmp 0x1e10
movl $0x0, -0x4(%rbp)
jmp 0x1e17
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl -0x4(%rbp), %eax
addq $0x140, %rsp            # imm = 0x140
popq %rbp
retq
nopw %cs:(%rax,%rax)