// File: adhipradhana[P]sliding-window-protocol/src/sendfile.cpp
// Function: main
int main(int argc, char *argv[]) {
    // Initialize packet related variables
    unsigned int seq_num;
    unsigned int packet_size, data_size;
    char data[MAX_DATA_LENGTH];
    char packet[MAX_PACKET_LENGTH];

    // Initialize file related variables
    FILE *file;
    char *buffer;
    char *filename;
    unsigned int max_buffer_size, buffer_size;

    if (argc != 6) {
    	cerr << "usage: ./sendfile <filename> <window_size> <buffer_size> <destination_ip> <destination_port>" << endl;
    	exit(1);
    }

    // Get data from argument
    filename = argv[1];
    window_size = atoi(argv[2]);
    max_buffer_size = atoi(argv[3]) * (unsigned int) MAX_DATA_LENGTH;
    ip = argv[4];
    port = atoi(argv[5]);

    // Create socket
    sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0) {
    	cerr << "ERROR on creating socket" << endl;
    	exit(1);
    }

    // Get host name
    server.sin_family = AF_INET;
    hp = gethostbyname(ip);
    if (hp == 0) {
    	cerr << "ERROR on getting host name" << endl;
    	exit(1);
    }

    // Fill server data struct
    bcopy((char *)hp->h_addr, (char *)&server.sin_addr, hp->h_length);
    server.sin_port = htons(port);
    sock_length = sizeof(struct sockaddr_in);

    // Open file
    if (access(filename, F_OK) < 0) {
        cerr << "FILE not exist\n";
        exit(1);
    }
    file = fopen(filename, "rb");
    buffer = new char[max_buffer_size];


    // Create a receiver thread
    thread receiver_thread(get_ack);

    bool read_done = false;
    while (!read_done) {

        // Read file from buffer
        buffer_size = fread(buffer, 1, max_buffer_size, file);
        read_done = max_buffer_size > buffer_size;

        // Initialized sliding window variable
        mt.lock();
        has_ack_received = new bool[window_size];
        packet_send_time = new time_stamp[window_size];
        bool has_packet_send[window_size];
        int seq_count = buffer_size / MAX_DATA_LENGTH;
        if (buffer_size % MAX_DATA_LENGTH) {
            seq_count++;
        }

        for (int i = 0; i < window_size; i++) {
            has_packet_send[i] = false;
            has_ack_received[i] = false;
        }

        lar = -1;
        lfs = lar + window_size;
        mt.unlock();

        bool send_done = false;
        while (!send_done) {
            mt.lock();
            if (has_ack_received[0]) {
                unsigned int shift = 1;

                for (unsigned int i = 1; i < window_size; i++) {
                    if (!has_ack_received[i]) {
                        break;
                    }
                    shift++;
                }

                for (unsigned int i = 0; i < window_size - shift; i++) {
                    has_packet_send[i] = has_packet_send[i + shift];
                    has_ack_received[i] = has_ack_received[i + shift];
                    packet_send_time[i] = packet_send_time[i + shift];
                }

                for (unsigned int i = window_size - shift; i < window_size; i++) {
                    has_packet_send[i] = false;
                    has_ack_received[i] = false;
                }

                lar += shift;
                lfs = lar + window_size;
            }
            mt.unlock();

            for (unsigned int i = 0; i < window_size; i ++) {
                seq_num = lar + i + 1;

                if (seq_num < seq_count) {
                    if (!has_packet_send[i] || ((!has_ack_received[i]) && (elapsed_time(current_time(), packet_send_time[i]) > TIMEOUT))) {
                        unsigned int buffer_shift = seq_num * MAX_DATA_LENGTH;
                        data_size = (buffer_size - buffer_shift < MAX_DATA_LENGTH) ? (buffer_size - buffer_shift) : MAX_DATA_LENGTH;
                        memcpy(data, buffer + buffer_shift, data_size);

                        bool eot = (seq_num == seq_count - 1) && (read_done);
                        packet_size = create_packet(packet, seq_num, data_size, data, eot);

                        int n = sendto(sock, packet, packet_size, MSG_WAITALL, (const struct sockaddr *) &server, sock_length);
                        if (n < 0) {
                            cerr << "ERROR sending packet\n";
                            // exit(1);
                        } else {
                            has_packet_send[i] = true;
                            packet_send_time[i] = current_time();

                            if (!eot) {
                                cout << "Sending package " << seq_num << endl;
                            } else {
                                cout << "Sending eot package " << seq_num << endl;
                            }
                        }
                    }
                }
            }

            if (lar >= seq_count - 1) {
                send_done = true;
            }
        }
        cout << "is read done ? " << read_done << "\n";
        if (read_done) {
            break;
        }
    }

    fclose(file);
    delete[] packet_send_time;
    delete[] has_ack_received;
    receiver_thread.detach();

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x9a0, %rsp            # imm = 0x9A0
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x6, -0x8(%rbp)
je 0x295b
movq 0x46ba(%rip), %rdi      # 0x6ff0
leaq 0x1729(%rip), %rsi      # 0x4066
callq 0x2120
movq %rax, %rdi
movq 0x466c(%rip), %rsi      # 0x6fb8
callq 0x2160
movl $0x1, %edi
callq 0x2190
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x848(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x2200
movl %eax, 0x47e3(%rip)      # 0x7160
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x2200
shll $0xa, %eax
movl %eax, -0x84c(%rbp)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, 0x47f6(%rip)      # 0x7198
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0x2200
movl %eax, 0x47b3(%rip)      # 0x7168
movl $0x2, %esi
xorl %edx, %edx
movl %esi, %edi
callq 0x2070
movl %eax, 0x4793(%rip)      # 0x715c
cmpl $0x0, 0x478c(%rip)      # 0x715c
jge 0x29fe
movq 0x4617(%rip), %rdi      # 0x6ff0
leaq 0x16e3(%rip), %rsi      # 0x40c3
callq 0x2120
movq %rax, %rdi
movq 0x45c9(%rip), %rsi      # 0x6fb8
callq 0x2160
movl $0x1, %edi
callq 0x2190
movw $0x2, 0x4765(%rip)      # 0x716c
movq 0x478a(%rip), %rdi      # 0x7198
callq 0x2170
movq %rax, 0x4776(%rip)      # 0x7190
cmpq $0x0, 0x476e(%rip)      # 0x7190
jne 0x2a50
movq 0x45c5(%rip), %rdi      # 0x6ff0
leaq 0x16aa(%rip), %rsi      # 0x40dc
callq 0x2120
movq %rax, %rdi
movq 0x4577(%rip), %rsi      # 0x6fb8
callq 0x2160
movl $0x1, %edi
callq 0x2190
movq 0x4739(%rip), %rax      # 0x7190
movq 0x18(%rax), %rax
movq (%rax), %rsi
movq 0x472b(%rip), %rax      # 0x7190
movslq 0x14(%rax), %rdx
leaq 0x4700(%rip), %rdi      # 0x7170
callq 0x2210
movl 0x46ed(%rip), %eax      # 0x7168
movzwl %ax, %edi
callq 0x2050
movw %ax, 0x46e4(%rip)       # 0x716e
movl $0x10, 0x46d0(%rip)     # 0x7164
movq -0x848(%rbp), %rdi
xorl %esi, %esi
callq 0x2220
cmpl $0x0, %eax
jge 0x2ac4
movq 0x4542(%rip), %rdi      # 0x6ff0
leaq 0x1642(%rip), %rsi      # 0x40f7
callq 0x2120
movl $0x1, %edi
callq 0x2190
movq -0x848(%rbp), %rdi
leaq 0x1635(%rip), %rsi      # 0x4107
callq 0x2180
movq %rax, -0x838(%rbp)
movl -0x84c(%rbp), %eax
movl %eax, %edi
callq 0x2030
movq %rax, -0x840(%rbp)
leaq -0x858(%rbp), %rdi
leaq -0x3b0(%rip), %rsi      # 0x2750
callq 0x34a0
movb $0x0, -0x859(%rbp)
movb -0x859(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x2b1d
jmp 0x3323
movq -0x840(%rbp), %rdi
movl -0x84c(%rbp), %eax
movl %eax, %edx
movq -0x838(%rbp), %rcx
movl $0x1, %esi
callq 0x21e0
movq %rax, -0x8e0(%rbp)
jmp 0x2b46
movq -0x8e0(%rbp), %rax
movl %eax, -0x850(%rbp)
movl -0x84c(%rbp), %eax
movl -0x850(%rbp), %ecx
subl %ecx, %eax
seta -0x859(%rbp)
leaq 0x4659(%rip), %rdi      # 0x71c8
callq 0x3450
jmp 0x2b76
movslq 0x45e3(%rip), %rdi      # 0x7160
callq 0x2030
movq %rax, -0x8e8(%rbp)
jmp 0x2b8b
movq -0x8e8(%rbp), %rax
movq %rax, 0x460f(%rip)      # 0x71a8
movslq 0x45c0(%rip), %rax      # 0x7160
movq %rax, -0x900(%rbp)
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
movq %rdi, -0x8f8(%rbp)
callq 0x2030
movq %rax, -0x8f0(%rbp)
jmp 0x2bd2
movq -0x900(%rbp), %rax
cmpq $0x0, %rax
je 0x2c38
movq -0x8f0(%rbp), %rax
movq -0x900(%rbp), %rdx
shlq $0x3, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq %rcx, -0x910(%rbp)
movq %rax, -0x908(%rbp)
movq -0x908(%rbp), %rdi
movq %rdi, -0x918(%rbp)
callq 0x3560
jmp 0x2c1a
movq -0x910(%rbp), %rcx
movq -0x918(%rbp), %rax
addq $0x8, %rax
cmpq %rcx, %rax
movq %rax, -0x908(%rbp)
jne 0x2c05
movq -0x8f0(%rbp), %rax
movq %rax, 0x4572(%rip)      # 0x71b8
movl 0x4514(%rip), %eax      # 0x7160
movq %rsp, %rcx
movq %rcx, -0x878(%rbp)
movq %rax, %rdx
addq $0xf, %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x920(%rbp)
movq %rcx, %rsp
movq %rax, -0x880(%rbp)
movl -0x850(%rbp), %eax
shrl $0xa, %eax
movl %eax, -0x884(%rbp)
movl -0x850(%rbp), %eax
andl $0x3ff, %eax            # imm = 0x3FF
cmpl $0x0, %eax
je 0x2ce9
movl -0x884(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x884(%rbp)
jmp 0x2ce9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x868(%rbp)
movl %eax, -0x86c(%rbp)
jmp 0x33a4
movq -0x8f8(%rbp), %rsi
movq -0x8f0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x868(%rbp)
movl %eax, -0x86c(%rbp)
callq 0x2260
jmp 0x33a4
movl $0x0, -0x888(%rbp)
movl -0x888(%rbp), %eax
cmpl 0x4461(%rip), %eax      # 0x7160
jge 0x2d36
movq -0x920(%rbp), %rax
movslq -0x888(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movq 0x448e(%rip), %rax      # 0x71a8
movslq -0x888(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movl -0x888(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x888(%rbp)
jmp 0x2cf3
movl $0xffffffff, 0x4460(%rip) # imm = 0xFFFFFFFF
movl 0x445a(%rip), %eax      # 0x71a0
movl 0x4414(%rip), %ecx      # 0x7160
addl %ecx, %eax
movl %eax, 0x4450(%rip)      # 0x71a4
leaq 0x446d(%rip), %rdi      # 0x71c8
callq 0x3480
jmp 0x2d62
movb $0x0, -0x889(%rbp)
movb -0x889(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x2d7a
jmp 0x3297
leaq 0x4447(%rip), %rdi      # 0x71c8
callq 0x3450
jmp 0x2d88
movq 0x4419(%rip), %rax      # 0x71a8
testb $0x1, (%rax)
je 0x2f19
movl $0x1, -0x890(%rbp)
movl $0x1, -0x894(%rbp)
movl -0x894(%rbp), %eax
cmpl 0x43a8(%rip), %eax      # 0x7160
jae 0x2def
movq 0x43e7(%rip), %rax      # 0x71a8
movl -0x894(%rbp), %ecx
testb $0x1, (%rax,%rcx)
jne 0x2dcf
jmp 0x2def
movl -0x890(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x890(%rbp)
movl -0x894(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x894(%rbp)
jmp 0x2dac
movl $0x0, -0x898(%rbp)
movl -0x898(%rbp), %eax
movl 0x435b(%rip), %ecx      # 0x7160
subl -0x890(%rbp), %ecx
cmpl %ecx, %eax
jae 0x2ea2
movq -0x920(%rbp), %rax
movl -0x898(%rbp), %ecx
addl -0x890(%rbp), %ecx
movl %ecx, %ecx
movb (%rax,%rcx), %dl
movl -0x898(%rbp), %ecx
andb $0x1, %dl
movb %dl, (%rax,%rcx)
movq 0x436a(%rip), %rax      # 0x71a8
movl -0x898(%rbp), %ecx
addl -0x890(%rbp), %ecx
movl %ecx, %ecx
movb (%rax,%rcx), %dl
movq 0x4352(%rip), %rax      # 0x71a8
movl -0x898(%rbp), %ecx
andb $0x1, %dl
movb %dl, (%rax,%rcx)
movq 0x434f(%rip), %rdx      # 0x71b8
movl -0x898(%rbp), %eax
addl -0x890(%rbp), %eax
movl %eax, %eax
movl %eax, %esi
movq 0x4338(%rip), %rax      # 0x71b8
movl -0x898(%rbp), %ecx
movq (%rdx,%rsi,8), %rdx
movq %rdx, (%rax,%rcx,8)
movl -0x898(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x898(%rbp)
jmp 0x2df9
movl 0x42b8(%rip), %eax      # 0x7160
subl -0x890(%rbp), %eax
movl %eax, -0x89c(%rbp)
movl -0x89c(%rbp), %eax
cmpl 0x42a0(%rip), %eax      # 0x7160
jae 0x2ef5
movq -0x920(%rbp), %rax
movl -0x89c(%rbp), %ecx
movb $0x0, (%rax,%rcx)
movq 0x42ce(%rip), %rax      # 0x71a8
movl -0x89c(%rbp), %ecx
movb $0x0, (%rax,%rcx)
movl -0x89c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x89c(%rbp)
jmp 0x2eb4
movl -0x890(%rbp), %eax
addl 0x429f(%rip), %eax      # 0x71a0
movl %eax, 0x4299(%rip)      # 0x71a0
movl 0x4293(%rip), %eax      # 0x71a0
addl 0x424d(%rip), %eax      # 0x7160
movl %eax, 0x428b(%rip)      # 0x71a4
leaq 0x42a8(%rip), %rdi      # 0x71c8
callq 0x3480
jmp 0x2f27
movl $0x0, -0x8a0(%rbp)
movl -0x8a0(%rbp), %eax
cmpl 0x4223(%rip), %eax      # 0x7160
jae 0x3278
movl 0x4257(%rip), %eax      # 0x71a0
addl -0x8a0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
cmpl -0x884(%rbp), %eax
jae 0x3262
movq -0x920(%rbp), %rcx
movl -0x8a0(%rbp), %eax
movl %eax, %edx
movb $0x1, %al
testb $0x1, (%rcx,%rdx)
movb %al, -0x921(%rbp)
je 0x3040
movq 0x421c(%rip), %rcx      # 0x71a8
movl -0x8a0(%rbp), %eax
movl %eax, %edx
xorl %eax, %eax
testb $0x1, (%rcx,%rdx)
movb %al, -0x922(%rbp)
jne 0x3034
callq 0x2040
movq %rax, -0x8b8(%rbp)
movq 0x41ff(%rip), %rax      # 0x71b8
movl -0x8a0(%rbp), %ecx
leaq (%rax,%rcx,8), %rsi
leaq -0x8b8(%rbp), %rdi
callq 0x35c0
movq %rax, -0x930(%rbp)
jmp 0x2fd8
movq -0x930(%rbp), %rax
movq %rax, -0x8b0(%rbp)
leaq -0x8b0(%rbp), %rdi
callq 0x3590
movq %rax, -0x938(%rbp)
jmp 0x2ffb
movq -0x938(%rbp), %rax
movq %rax, -0x8a8(%rbp)
leaq -0x8a8(%rbp), %rdi
callq 0x3610
movq %rax, -0x940(%rbp)
jmp 0x301e
movq -0x940(%rbp), %rax
cmpq $0x3e8, %rax            # imm = 0x3E8
setg %al
movb %al, -0x922(%rbp)
movb -0x922(%rbp), %al
movb %al, -0x921(%rbp)
movb -0x921(%rbp), %al
testb $0x1, %al
jne 0x304f
jmp 0x3260
movl -0x14(%rbp), %eax
shll $0xa, %eax
movl %eax, -0x8bc(%rbp)
movl -0x850(%rbp), %eax
subl -0x8bc(%rbp), %eax
cmpl $0x400, %eax            # imm = 0x400
jae 0x3082
movl -0x850(%rbp), %eax
subl -0x8bc(%rbp), %eax
movl %eax, -0x944(%rbp)
jmp 0x308f
movl $0x400, %eax            # imm = 0x400
movl %eax, -0x944(%rbp)
jmp 0x308f
movl -0x944(%rbp), %eax
movl %eax, -0x1c(%rbp)
leaq -0x420(%rbp), %rdi
movq -0x840(%rbp), %rsi
movl -0x8bc(%rbp), %eax
addq %rax, %rsi
movl -0x1c(%rbp), %eax
movl %eax, %edx
callq 0x20f0
movl -0x14(%rbp), %ecx
movl -0x884(%rbp), %edx
subl $0x1, %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x945(%rbp)
jne 0x30dd
movb -0x859(%rbp), %al
movb %al, -0x945(%rbp)
movb -0x945(%rbp), %al
andb $0x1, %al
movb %al, -0x8bd(%rbp)
movl -0x14(%rbp), %esi
movl -0x1c(%rbp), %eax
movl %eax, %edx
movzbl -0x8bd(%rbp), %r8d
andl $0x1, %r8d
leaq -0x830(%rbp), %rdi
leaq -0x420(%rbp), %rcx
callq 0x2450
movq %rax, -0x950(%rbp)
jmp 0x311b
movq -0x950(%rbp), %rax
movl %eax, -0x18(%rbp)
movl 0x4031(%rip), %edi      # 0x715c
movl -0x18(%rbp), %eax
movl %eax, %edx
movl 0x402d(%rip), %r9d      # 0x7164
leaq 0x402e(%rip), %r8       # 0x716c
leaq -0x830(%rbp), %rsi
movl $0x100, %ecx            # imm = 0x100
callq 0x2060
movq %rax, -0x958(%rbp)
jmp 0x3158
movq -0x958(%rbp), %rax
movl %eax, -0x8c4(%rbp)
cmpl $0x0, -0x8c4(%rbp)
jge 0x3188
movq 0x3e7b(%rip), %rdi      # 0x6ff0
leaq 0xf8e(%rip), %rsi       # 0x410a
callq 0x2120
jmp 0x3183
jmp 0x325e
movq -0x920(%rbp), %rax
movl -0x8a0(%rbp), %ecx
movb $0x1, (%rax,%rcx)
callq 0x2040
movq %rax, -0x8d0(%rbp)
movq 0x400c(%rip), %rax      # 0x71b8
movl -0x8a0(%rbp), %ecx
movq -0x8d0(%rbp), %rdx
movq %rdx, (%rax,%rcx,8)
testb $0x1, -0x8bd(%rbp)
jne 0x3211
movq 0x3e03(%rip), %rdi      # 0x6fd0
leaq 0xf4c(%rip), %rsi       # 0x4120
callq 0x2120
movq %rax, -0x960(%rbp)
jmp 0x31e2
movq -0x960(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x21c0
movq %rax, -0x968(%rbp)
jmp 0x31fa
movq -0x968(%rbp), %rdi
movq 0x3db0(%rip), %rsi      # 0x6fb8
callq 0x2160
jmp 0x320f
jmp 0x325c
movq 0x3db8(%rip), %rdi      # 0x6fd0
leaq 0xf12(%rip), %rsi       # 0x4131
callq 0x2120
movq %rax, -0x970(%rbp)
jmp 0x322d
movq -0x970(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x21c0
movq %rax, -0x978(%rbp)
jmp 0x3245
movq -0x978(%rbp), %rdi
movq 0x3d65(%rip), %rsi      # 0x6fb8
callq 0x2160
jmp 0x325a
jmp 0x325c
jmp 0x325e
jmp 0x3260
jmp 0x3262
jmp 0x3264
movl -0x8a0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8a0(%rbp)
jmp 0x2f31
movl 0x3f22(%rip), %eax      # 0x71a0
movl -0x884(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jl 0x3292
movb $0x1, -0x889(%rbp)
jmp 0x2d69
movq 0x3d32(%rip), %rdi      # 0x6fd0
leaq 0xea1(%rip), %rsi       # 0x4146
callq 0x2120
movq %rax, -0x980(%rbp)
jmp 0x32b3
movq -0x980(%rbp), %rdi
movzbl -0x859(%rbp), %esi
andl $0x1, %esi
callq 0x2250
movq %rax, -0x988(%rbp)
jmp 0x32d2
movq -0x988(%rbp), %rdi
leaq 0xe3e(%rip), %rsi       # 0x411e
callq 0x2120
jmp 0x32e7
testb $0x1, -0x859(%rbp)
je 0x32fc
movl $0x3, -0x8d4(%rbp)
jmp 0x3306
movl $0x0, -0x8d4(%rbp)
movq -0x878(%rbp), %rax
movq %rax, %rsp
movl -0x8d4(%rbp), %eax
testl %eax, %eax
je 0x331e
jmp 0x331c
jmp 0x3323
jmp 0x2b0c
movq -0x838(%rbp), %rdi
callq 0x2130
jmp 0x3331
movq 0x3e80(%rip), %rax      # 0x71b8
movq %rax, -0x990(%rbp)
cmpq $0x0, %rax
je 0x3351
movq -0x990(%rbp), %rdi
callq 0x21b0
movq 0x3e50(%rip), %rax      # 0x71a8
movq %rax, -0x998(%rbp)
cmpq $0x0, %rax
je 0x3371
movq -0x998(%rbp), %rdi
callq 0x21b0
leaq -0x858(%rbp), %rdi
callq 0x2230
jmp 0x337f
movl $0x0, -0x4(%rbp)
movl $0x1, -0x8d4(%rbp)
leaq -0x858(%rbp), %rdi
callq 0x3630
movl -0x4(%rbp), %eax
movq %rbp, %rsp
popq %rbp
retq
leaq -0x858(%rbp), %rdi
callq 0x3630
movq -0x868(%rbp), %rdi
callq 0x2240
nopl (%rax)