// File: /workspace/github_c_makefile_star2_O0/TeaInside[P]teavpn/src/teavpn/server/tcp.c
// Function: teavpn_tcp_server
__attribute__((force_align_arg_pointer)) uint8_t teavpn_tcp_server(server_config *config)
{
	fd_set rd_set;
	int  fd_ret, max_fd;
	ssize_t nwrite, nread;
	int16_t bufchan_index;
	pthread_t accept_worker;
	struct sockaddr_in server_addr;
	struct teavpn_tcp_queue _queues[QUEUE_AMOUNT];
	struct buffer_channel _bufchan[BUFCHAN_ALLOC];
	struct connection_entry _connections[CONNECTION_ALLOC];

	/**
	 * To store config file buffer (parsing).
	 *
	 * Avoid to use heap as long as it
	 * is still eligible to use stack.
	 *
	 * (heap is slower than stack)
	 */
	char config_buffer[4096];

	/** 
	 * Assign internal stack allocation to global vars
	 * in order to make other threads can access them.
	 */
	queues = _queues;
	bufchan = _bufchan;
	connections = _connections;

	/**
	 * Initialize TeaVPN server (vars, socket, iface, etc.)
	 */
	if (teavpn_tcp_server_init(config_buffer, config)) {
		return 1;
	}

	thread_amount = config->threads;

	/**
	 * Prepare worker threads.
	 * (Threads which transmit data to client).
	 *
	 * Use stack allocation as long as possible.
	 */
	struct worker_thread _workers[thread_amount];
	workers = _workers;

	if (thread_amount < 3) {
		debug_log(0, "Minimal threads amount is 3, but %d given", thread_amount);
		goto close_server;
	}


	/**
	 * Create the worker threads.
	 */
	for (register uint8_t i = 0; i < config->threads; ++i) {
		workers[i].busy = false;
		workers[i].num = i;
		pthread_cond_init(&(workers[i].cond), NULL);
		pthread_mutex_init(&(workers[i].mutex), NULL);
		pthread_create(
			&(workers[i].thread),
			NULL,
			(void * (*)(void *))teavpn_tcp_worker_thread,
			(void *)&(workers[i])
		);
		pthread_detach(workers[i].thread);

		#define thread_name (bufchan[0].buffer)
		sprintf(thread_name, "teavpn-worker-%d", i);
		pthread_setname_np(workers[i].thread, thread_name);
		#undef thread_name
	}
	memset(bufchan[0].buffer, 0, sizeof("teavpn-worker-xxx"));

	/**
	 * Prepare server bind address data.
	 */
	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(config->bind_port);
	server_addr.sin_addr.s_addr = inet_addr(config->bind_addr);

	/**
	 * Bind socket to address.
	 */
	if (bind(net_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
		debug_log(0, "Bind socket failed");
		perror("Bind failed");
		goto close_server;
	}

	/**
	 * Listen
	 */
	if (listen(net_fd, 3) < 0) {
		debug_log(0, "Listen socket failed");
		perror("Listen failed");
		goto close_server;
	}

	/**
	 * Ignore SIGPIPE
	 */
	signal(SIGPIPE, SIG_IGN);

	/**
	 * Create accept worker thread.
	 * (Thread which accepts new connection).
	 */
	pthread_create(
		&accept_worker,
		NULL,
		(void * (*)(void *))teavpn_tcp_accept_worker_thread,
		(void *)config
	);
	pthread_setname_np(accept_worker, "accept-worker");
	pthread_detach(accept_worker);

	debug_log(0, "Listening on %s:%d...", config->bind_addr, config->bind_port);

	/**
	 * TeaVPN server event loop.
	 */
	while (true) {

		/**
		 * Calculate maximum value between tap_fd, net_fd and m_pie_fd[0].
		 */
		max_fd = (((tap_fd > net_fd) && (tap_fd > m_pipe_fd[0])) ? tap_fd :
				(net_fd > m_pipe_fd[0]) ? net_fd : m_pipe_fd[0]);

		/**
		 * Set rd_set to zero.
		 *
		 * This is a compulsory step in using
		 * select(2) inside of an event loop.
		 */
		FD_ZERO(&rd_set);

		/**
		 * Add file descriptors to rd_set.
		 */
		FD_SET(net_fd, &rd_set);
		FD_SET(tap_fd, &rd_set);
		FD_SET(m_pipe_fd[0], &rd_set);


		/**
		 * Add all connected clients file descriptor to rd_set.
		 */
		for (register uint16_t i = 0; i < CONNECTION_ALLOC; i++) {
			if (connections[i].connected) {

				/**
				 * Recalculate max fd to make sure that max_fd
				 * has the maximum value from the entire involved
				 * file descriptors.
				 */
				if (connections[i].fd > max_fd) {
					max_fd = connections[i].fd;
				}

				/**
				 * Add file descriptors to rd_set.
				 */
				FD_SET(connections[i].fd, &rd_set);
			}
		}


		/**
		 * Get buffer channel index.
		 */
		do {
			bufchan_index = get_bufchan_index();
		} while (bufchan_index == -1);


		/**
		 * Block main process until there is one or more ready fd.
		 * Read `man 2 select_tut` for details.
		 */
		fd_ret = select(max_fd + 1, &rd_set, NULL, NULL, NULL);

		/**
		 * Got interrupt signal.
		 */
		if ((fd_ret < 0) && (errno == EINTR)) {
			debug_log(2, "select(2) got interrupt signal");
			continue;
		}

		/**
		 * Got an error.
		 */
		if (fd_ret < 0) {
			debug_log(0, "select(2) got an error");
			perror("select()");
			continue;
		}

		/**
		 * Create a macro to manage buffer channel as other data type.
		 *
		 * Don't make a new variable as long as we can use the available
		 * resources in safely way.
		 */
		#define packet ((teavpn_packet *)(bufchan[bufchan_index].buffer))


		/**
		 * Read data from server TUN/TAP.
		 */
		if (FD_ISSET(tap_fd, &rd_set)) {
			/**
			 * Read from TUN/TAP.
			 */
			nread = read(tap_fd, packet->data.data, TEAVPN_TAP_READ_SIZE);
			if (nread < 0) {
				debug_log(0, "Error read from tap_fd");
				perror("Error read from tap_fd");
				goto next_1;
			}

			packet->info.type = TEAVPN_PACKET_DATA;
			packet->info.len = TEAVPN_PACK(nread);
			for (register uint16_t i = 0; i < CONNECTION_ALLOC; i++) {
				if (connections[i].connected) {
					/**
					 * Insert write queue.
					 *
					 * Send bufchan_index to connection i.
					 */
					bufchan[bufchan_index].ref_count++;
					// printf("i = %d;  r = %d\n", bufchan_index, bufchan[bufchan_index].ref_count);
					enqueue_packet(i, bufchan_index);
					thread_job_broadcast();
				}
			}
		}


		next_1:
		/**
		 * Traverse clients fd and read data from clients.
		 */
		for (register uint16_t i = 0; i < CONNECTION_ALLOC; i++) {
			if (connections[i].connected) {
				if (FD_ISSET(connections[i].fd, &rd_set)) {

					/**
					 * Get buffer channel index.
					 */
					do {
						bufchan_index = get_bufchan_index();
					} while (bufchan_index == -1);

					nread = read(connections[i].fd, packet, TEAVPN_PACKET_BUFFER);

					/**
					 * Connection closed by client.
					 */
					if (nread == 0) {
						FD_CLR(connections[i].fd, &rd_set);
						close(connections[i].fd);
						debug_log(1, "(%s:%d) connection closed",
							inet_ntoa(connections[i].addr.sin_addr),
							ntohs(connections[i].addr.sin_port)
						);
						connection_zero(i);
						continue;
					}

					/**
					 * Error read from client fd.
					 */
					if (nread < 0) {
						char *remote_addr = inet_ntoa(connections[i].addr.sin_addr);
						uint16_t remote_port = ntohs(connections[i].addr.sin_port);

						debug_log(0, "Error read from (%s:%d)", remote_addr, remote_port);
						perror("Error read from connection fd");

						/**
						 * Increment the error counter.
						 */
						connections[i].error++;

						/**
						 * Force disconnect client if it has
						 * reached the max number of errors.
						 */
						if (connections[i].error > MAX_CLIENT_ERR) {
							debug_log(0,
								"Client %s:%d has been disconnected because it has reached the max number of errors",
								remote_port,
								remote_port
							);
							FD_CLR(connections[i].fd, &rd_set);
							close(connections[i].fd);
							connection_zero(i);
						}

						continue;
					}


					/**
					 * Write to TUN/TAP server.
					 */
					if (packet->info.type == TEAVPN_PACKET_DATA) {

						while (nread < (packet->info.len)) {
							register ssize_t tmp_nread;
							debug_log(3, "Read extra %ld/%ld bytes", nread, packet->info.len);
							tmp_nread = read(
								connections[i].fd,
								&(((char *)packet)[nread]),
								packet->info.len - nread
							);

							if (tmp_nread < 0) {
								connections[i].error++;
								perror("Error read extra");
							} else {
								nread += tmp_nread;
							}
						}

						connections[i].seq++;
						debug_log(3, "[%ld] Read from client %s:%d (server_seq: %ld) (client_seq: %ld) (seq %s)",
							connections[i].seq,
							inet_ntoa(connections[i].addr.sin_addr),
							ntohs(connections[i].addr.sin_port),
							connections[i].seq,
							packet->info.seq,
							(connections[i].seq == packet->info.seq) ? "match" : "invalid"
						);

						nwrite = write(tap_fd, &(packet->data.data), nread - TEAVPN_PACK(0));
						if (nwrite < 0) {
							connections[i].error++;
							perror("Error write to tap_fd");
							continue;
						}

						debug_log(3, "Write to tap_fd %ld bytes", nwrite);

					} else {
						connections[i].error++;
					}
				}
			}
		}


		/**
		 * Deal with new connection.
		 */
		if (FD_ISSET(m_pipe_fd[0], &rd_set)) {
			uint8_t sig_x;

			nread = read(m_pipe_fd[0], &sig_x, sizeof(sig_x));
			if (nread < 0) {
				debug_log(0, "Error read from m_pipe_fd[0]");
				perror("Error read from m_pipe_fd[0]");
			}
		}

		if (FD_ISSET(net_fd, &rd_set)) {
			pthread_cond_signal(&accept_worker_cond);
		}

		/**
		 * Since macro doesn't have scope limit, we have to undef here
		 * so that it doesn't distrub the outer scope of variable usage.
		 */
		#undef packet
	}

	close_server:
	close(m_pipe_fd[0]);
	close(m_pipe_fd[1]);
	close(net_fd);
	close(tap_fd);
	return 1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
andq $-0x10, %rsp
subq $0x1a1f0, %rsp          # imm = 0x1A1F0
movq %rsp, %rbx
movq %fs:0x28, %rax
movq %rax, 0x1a1e0(%rbx)
movq %rdi, 0xb8(%rbx)
leaq 0x19cd0(%rbx), %rax
movq %rax, 0x8d80(%rip)      # 0xe368
leaq 0x1850(%rbx), %rax
movq %rax, 0x8d7a(%rip)      # 0xe370
leaq 0x10d0(%rbx), %rax
movq %rax, 0x8d74(%rip)      # 0xe378
leaq 0xd0(%rbx), %rdi
movq 0xb8(%rbx), %rsi
callq 0x6590
cmpb $0x0, %al
je 0x5627
movb $0x1, 0xc6(%rbx)
jmp 0x6560
movq 0xb8(%rbx), %rax
movb 0x3d(%rax), %al
movb %al, 0x8d49(%rip)       # 0xe380
movzbl 0x8d42(%rip), %eax      # 0xe380
movl %eax, %ecx
movq %rsp, %rdx
movq %rdx, 0x90(%rbx)
imull $0x68, %eax, %eax
addl $0xf, %eax
andl $-0x10, %eax
movl %eax, %edx
movq %rsp, %rax
subq %rdx, %rax
movq %rax, %rsp
movq %rcx, 0x88(%rbx)
movq %rax, 0x8d1c(%rip)      # 0xe388
movzbl 0x8d0d(%rip), %eax      # 0xe380
cmpl $0x3, %eax
jge 0x56a2
leaq 0x8da5(%rip), %rax      # 0xe424
movzbl (%rax), %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jg 0x569d
movzbl 0x8cf1(%rip), %esi      # 0xe380
leaq 0x53a5(%rip), %rdi      # 0xaa3b
movb $0x0, %al
callq 0x84c0
jmp 0x6523
movb $0x0, 0x87(%rbx)
movzbl 0x87(%rbx), %eax
movq 0xb8(%rbx), %rcx
movzbl 0x3d(%rcx), %ecx
cmpl %ecx, %eax
jge 0x57f5
movq 0x8cbe(%rip), %rax      # 0xe388
movzbl 0x87(%rbx), %ecx
imulq $0x68, %rcx, %rcx
addq %rcx, %rax
movb $0x0, (%rax)
movb 0x87(%rbx), %cl
movq 0x8ca0(%rip), %rax      # 0xe388
movzbl 0x87(%rbx), %edx
imulq $0x68, %rdx, %rdx
addq %rdx, %rax
movb %cl, 0x1(%rax)
movq 0x8c88(%rip), %rdi      # 0xe388
movzbl 0x87(%rbx), %eax
imulq $0x68, %rax, %rax
addq %rax, %rdi
addq $0x38, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x22a0
movq 0x8c66(%rip), %rdi      # 0xe388
movzbl 0x87(%rbx), %eax
imulq $0x68, %rax, %rax
addq %rax, %rdi
addq $0x10, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x23e0
movq 0x8c44(%rip), %rdi      # 0xe388
movzbl 0x87(%rbx), %eax
imulq $0x68, %rax, %rax
addq %rax, %rdi
addq $0x8, %rdi
movq 0x8c2b(%rip), %rcx      # 0xe388
movzbl 0x87(%rbx), %eax
imulq $0x68, %rax, %rax
addq %rax, %rcx
xorl %eax, %eax
movl %eax, %esi
leaq 0x11da(%rip), %rdx      # 0x6950
callq 0x2320
movq 0x8c06(%rip), %rax      # 0xe388
movzbl 0x87(%rbx), %ecx
imulq $0x68, %rcx, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rdi
callq 0x22e0
movq 0x8bd0(%rip), %rdi      # 0xe370
addq $0x10, %rdi
movzbl 0x87(%rbx), %edx
leaq 0x52b3(%rip), %rsi      # 0xaa65
movb $0x0, %al
callq 0x23a0
movq 0x8bc8(%rip), %rax      # 0xe388
movzbl 0x87(%rbx), %ecx
imulq $0x68, %rcx, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rdi
movq 0x8b97(%rip), %rsi      # 0xe370
addq $0x10, %rsi
callq 0x2170
movb 0x87(%rbx), %al
addb $0x1, %al
movb %al, 0x87(%rbx)
jmp 0x56a9
movq 0x8b74(%rip), %rdi      # 0xe370
addq $0x10, %rdi
xorl %esi, %esi
movl $0x12, %edx
callq 0x2190
leaq 0x1a150(%rbx), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x2190
movw $0x2, 0x1a150(%rbx)
movq 0xb8(%rbx), %rax
movzwl 0x3a(%rax), %edi
callq 0x2140
movw %ax, 0x1a152(%rbx)
movq 0xb8(%rbx), %rax
movq (%rax), %rdi
callq 0x2210
movl %eax, 0x1a154(%rbx)
movl 0x8b36(%rip), %edi      # 0xe390
leaq 0x1a150(%rbx), %rax
movq %rax, 0x78(%rbx)
movq 0x78(%rbx), %rsi
movl $0x10, %edx
callq 0x2310
cmpl $0x0, %eax
jge 0x58a7
leaq 0x8ba5(%rip), %rax      # 0xe424
movzbl (%rax), %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jg 0x5896
leaq 0x51e7(%rip), %rdi      # 0xaa76
movb $0x0, %al
callq 0x84c0
leaq 0x51ec(%rip), %rdi      # 0xaa89
callq 0x2360
jmp 0x6523
movl 0x8ae3(%rip), %edi      # 0xe390
movl $0x3, %esi
callq 0x22f0
cmpl $0x0, %eax
jge 0x58eb
leaq 0x8b61(%rip), %rax      # 0xe424
movzbl (%rax), %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jg 0x58da
leaq 0x51c2(%rip), %rdi      # 0xaa95
movb $0x0, %al
callq 0x84c0
leaq 0x51c9(%rip), %rdi      # 0xaaaa
callq 0x2360
jmp 0x6523
movl $0xd, %edi
movl $0x1, %esi
callq 0x2230
movq 0xb8(%rbx), %rcx
leaq 0xc8(%rbx), %rdi
xorl %eax, %eax
movl %eax, %esi
leaq 0x15cd(%rip), %rdx      # 0x6ee0
callq 0x2320
movq 0xc8(%rbx), %rdi
leaq 0x5192(%rip), %rsi      # 0xaab8
callq 0x2170
movq 0xc8(%rbx), %rdi
callq 0x22e0
leaq 0x8ae6(%rip), %rax      # 0xe424
movzbl (%rax), %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jg 0x596a
movq 0xb8(%rbx), %rax
movq (%rax), %rsi
movq 0xb8(%rbx), %rax
movzwl 0x3a(%rax), %edx
leaq 0x5163(%rip), %rdi      # 0xaac6
movb $0x0, %al
callq 0x84c0
jmp 0x596c
jmp 0x596e
movl 0x8a20(%rip), %eax      # 0xe394
cmpl 0x8a16(%rip), %eax      # 0xe390
jle 0x5995
movl 0x8a12(%rip), %eax      # 0xe394
cmpl 0x8a10(%rip), %eax      # 0xe398
jle 0x5995
movl 0x8a04(%rip), %eax      # 0xe394
movl %eax, 0x44(%rbx)
jmp 0x59bd
movl 0x89f5(%rip), %eax      # 0xe390
cmpl 0x89f7(%rip), %eax      # 0xe398
jle 0x59ae
movl 0x89e7(%rip), %eax      # 0xe390
movl %eax, 0x40(%rbx)
jmp 0x59b7
movl 0x89e4(%rip), %eax      # 0xe398
movl %eax, 0x40(%rbx)
movl 0x40(%rbx), %eax
movl %eax, 0x44(%rbx)
movl 0x44(%rbx), %eax
movl %eax, 0xb0(%rbx)
leaq 0x1a160(%rbx), %rax
movq %rax, 0x68(%rbx)
movl $0x0, 0x74(%rbx)
movl 0x74(%rbx), %eax
cmpq $0x10, %rax
jae 0x59fb
movq 0x68(%rbx), %rax
movl 0x74(%rbx), %ecx
movq $0x0, (%rax,%rcx,8)
movl 0x74(%rbx), %eax
addl $0x1, %eax
movl %eax, 0x74(%rbx)
jmp 0x59d8
jmp 0x59fd
jmp 0x59ff
movl 0x898b(%rip), %eax      # 0xe390
movl $0x40, %ecx
cltd
idivl %ecx
movl %edx, %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
movq %rax, %rcx
movl 0x896e(%rip), %eax      # 0xe390
movl $0x40, %esi
cltd
idivl %esi
cltq
orq 0x1a160(%rbx,%rax,8), %rcx
movq %rcx, 0x1a160(%rbx,%rax,8)
movl 0x8952(%rip), %eax      # 0xe394
movl $0x40, %ecx
cltd
idivl %ecx
movl %edx, %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
movq %rax, %rcx
movl 0x8935(%rip), %eax      # 0xe394
movl $0x40, %esi
cltd
idivl %esi
cltq
orq 0x1a160(%rbx,%rax,8), %rcx
movq %rcx, 0x1a160(%rbx,%rax,8)
movl 0x8919(%rip), %eax      # 0xe398
movl $0x40, %ecx
cltd
idivl %ecx
movl %edx, %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
movq %rax, %rcx
movl 0x88fc(%rip), %eax      # 0xe398
movl $0x40, %esi
cltd
idivl %esi
cltq
orq 0x1a160(%rbx,%rax,8), %rcx
movq %rcx, 0x1a160(%rbx,%rax,8)
movw $0x0, 0x66(%rbx)
movzwl 0x66(%rbx), %eax
cmpl $0x18, %eax
jge 0x5b87
movq 0x88a8(%rip), %rax      # 0xe378
movzwl 0x66(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
testb $0x1, 0x4(%rax)
je 0x5b74
movq 0x888c(%rip), %rax      # 0xe378
movzwl 0x66(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %eax
cmpl 0xb0(%rbx), %eax
jle 0x5b1b
movq 0x8870(%rip), %rax      # 0xe378
movzwl 0x66(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %eax
movl %eax, 0xb0(%rbx)
movq 0x8856(%rip), %rax      # 0xe378
movzwl 0x66(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movl %edx, %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
movq %rax, %rcx
movq 0x882b(%rip), %rax      # 0xe378
movzwl 0x66(%rbx), %edx
imulq $0x50, %rdx, %rdx
addq %rdx, %rax
movl (%rax), %eax
movl $0x40, %esi
cltd
idivl %esi
cltq
orq 0x1a160(%rbx,%rax,8), %rcx
movq %rcx, 0x1a160(%rbx,%rax,8)
jmp 0x5b76
movw 0x66(%rbx), %ax
addw $0x1, %ax
movw %ax, 0x66(%rbx)
jmp 0x5abc
jmp 0x5b89
callq 0x81e0
movw %ax, 0x9e(%rbx)
movswl 0x9e(%rbx), %eax
cmpl $-0x1, %eax
je 0x5b89
movl 0xb0(%rbx), %edi
addl $0x1, %edi
leaq 0x1a160(%rbx), %rsi
xorl %eax, %eax
movl %eax, %r8d
movq %r8, %rdx
movq %r8, %rcx
callq 0x2290
movl %eax, 0xb4(%rbx)
cmpl $0x0, 0xb4(%rbx)
jge 0x5c00
callq 0x2050
cmpl $0x4, (%rax)
jne 0x5c00
leaq 0x8843(%rip), %rax      # 0xe424
movzbl (%rax), %ecx
movl $0x2, %eax
cmpl %ecx, %eax
jg 0x5bfb
leaq 0x4a16(%rip), %rdi      # 0xa60a
movb $0x0, %al
callq 0x84c0
jmp 0x596c
cmpl $0x0, 0xb4(%rbx)
jge 0x5c38
leaq 0x8814(%rip), %rax      # 0xe424
movzbl (%rax), %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jg 0x5c27
leaq 0x4a09(%rip), %rdi      # 0xa629
movb $0x0, %al
callq 0x84c0
leaq 0x4a12(%rip), %rdi      # 0xa640
callq 0x2360
jmp 0x596c
movl 0x8756(%rip), %eax      # 0xe394
movl $0x40, %ecx
cltd
idivl %ecx
cltq
movq 0x1a160(%rbx,%rax,8), %rax
movq %rax, 0x38(%rbx)
movl 0x873a(%rip), %eax      # 0xe394
movl $0x40, %ecx
cltd
idivl %ecx
movq 0x38(%rbx), %rax
movl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
je 0x5db2
movl 0x870e(%rip), %edi      # 0xe394
movq 0x86e3(%rip), %rsi      # 0xe370
movswq 0x9e(%rbx), %rax
imulq $0x1030, %rax, %rax     # imm = 0x1030
addq %rax, %rsi
addq $0x10, %rsi
addq $0x10, %rsi
movl $0xbb8, %edx            # imm = 0xBB8
callq 0x21d0
movq %rax, 0xa0(%rbx)
cmpq $0x0, 0xa0(%rbx)
jge 0x5cf1
leaq 0x875b(%rip), %rax      # 0xe424
movzbl (%rax), %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jg 0x5ce0
leaq 0x498b(%rip), %rdi      # 0xa664
movb $0x0, %al
callq 0x84c0
leaq 0x497d(%rip), %rdi      # 0xa664
callq 0x2360
jmp 0x5db4
movq 0x8678(%rip), %rax      # 0xe370
movswq 0x9e(%rbx), %rcx
imulq $0x1030, %rcx, %rcx     # imm = 0x1030
addq %rcx, %rax
movl $0x2, 0x10(%rax)
xorl %eax, %eax
addq $0x10, %rax
addq 0xa0(%rbx), %rax
movw %ax, %cx
movq 0x8648(%rip), %rax      # 0xe370
movswq 0x9e(%rbx), %rdx
imulq $0x1030, %rdx, %rdx     # imm = 0x1030
addq %rdx, %rax
movw %cx, 0x14(%rax)
movw $0x0, 0x64(%rbx)
movzwl 0x64(%rbx), %eax
cmpl $0x18, %eax
jge 0x5db0
movq 0x8624(%rip), %rax      # 0xe378
movzwl 0x64(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
testb $0x1, 0x4(%rax)
je 0x5da0
movq 0x8604(%rip), %rax      # 0xe370
movswq 0x9e(%rbx), %rcx
imulq $0x1030, %rcx, %rcx     # imm = 0x1030
addq %rcx, %rax
movw (%rax), %cx
addw $0x1, %cx
movw %cx, (%rax)
movw 0x64(%rbx), %ax
movzwl %ax, %edi
movzwl 0x9e(%rbx), %esi
callq 0x7c10
callq 0x7de0
jmp 0x5da2
movw 0x64(%rbx), %ax
addw $0x1, %ax
movw %ax, 0x64(%rbx)
jmp 0x5d44
jmp 0x5db2
jmp 0x5db4
movw $0x0, 0x62(%rbx)
movzwl 0x62(%rbx), %eax
cmpl $0x18, %eax
jge 0x6436
movq 0x85aa(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
testb $0x1, 0x4(%rax)
je 0x6423
movq 0x858e(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
cltq
movq 0x1a160(%rbx,%rax,8), %rax
movq %rax, 0x30(%rbx)
movq 0x8564(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq 0x30(%rbx), %rax
movl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
je 0x6421
jmp 0x5e49
callq 0x81e0
movw %ax, 0x9e(%rbx)
movswl 0x9e(%rbx), %eax
cmpl $-0x1, %eax
je 0x5e49
movq 0x8510(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %edi
movq 0x84f4(%rip), %rsi      # 0xe370
movswq 0x9e(%rbx), %rax
imulq $0x1030, %rax, %rax     # imm = 0x1030
addq %rax, %rsi
addq $0x10, %rsi
movl $0xfa0, %edx            # imm = 0xFA0
callq 0x21d0
movq %rax, 0xa0(%rbx)
cmpq $0x0, 0xa0(%rbx)
jne 0x5f96
movq 0x84c0(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movl %edx, %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
movq %rax, %rcx
xorq $-0x1, %rcx
movq 0x8491(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %edx
imulq $0x50, %rdx, %rdx
addq %rdx, %rax
movl (%rax), %eax
movl $0x40, %esi
cltd
idivl %esi
cltq
andq 0x1a160(%rbx,%rax,8), %rcx
movq %rcx, 0x1a160(%rbx,%rax,8)
movq 0x8463(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %edi
callq 0x21b0
leaq 0x84f6(%rip), %rax      # 0xe424
movzbl (%rax), %ecx
movl $0x1, %eax
cmpl %ecx, %eax
jg 0x5f88
movq 0x8437(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movl 0x44(%rax), %edi
callq 0x20c0
movq %rax, 0x28(%rbx)
movq 0x8419(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movzwl 0x42(%rax), %edi
callq 0x2300
movq 0x28(%rbx), %rsi
movzwl %ax, %edx
leaq 0x4b5b(%rip), %rdi      # 0xaadc
movb $0x0, %al
callq 0x84c0
movzwl 0x62(%rbx), %edi
callq 0x7cf0
jmp 0x6425
cmpq $0x0, 0xa0(%rbx)
jge 0x60f7
movq 0x83cd(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movl 0x44(%rax), %edi
callq 0x20c0
movq %rax, 0x58(%rbx)
movq 0x83af(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movzwl 0x42(%rax), %edi
callq 0x2300
movw %ax, 0x56(%rbx)
leaq 0x843c(%rip), %rax      # 0xe424
movzbl (%rax), %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jg 0x6007
movq 0x58(%rbx), %rsi
movzwl 0x56(%rbx), %edx
leaq 0x4af6(%rip), %rdi      # 0xaaf6
movb $0x0, %al
callq 0x84c0
leaq 0x4b00(%rip), %rdi      # 0xab0e
callq 0x2360
movq 0x835e(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movb 0x5(%rax), %cl
addb $0x1, %cl
movb %cl, 0x5(%rax)
movq 0x8343(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movzbl 0x5(%rax), %eax
cmpl $0xf, %eax
jle 0x60f2
leaq 0x83d0(%rip), %rax      # 0xe424
movzbl (%rax), %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jg 0x6073
movzwl 0x56(%rbx), %esi
movzwl 0x56(%rbx), %edx
leaq 0x4ac0(%rip), %rdi      # 0xab2c
movb $0x0, %al
callq 0x84c0
movq 0x82fe(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movl %edx, %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
movq %rax, %rcx
xorq $-0x1, %rcx
movq 0x82cf(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %edx
imulq $0x50, %rdx, %rdx
addq %rdx, %rax
movl (%rax), %eax
movl $0x40, %esi
cltd
idivl %esi
cltq
andq 0x1a160(%rbx,%rax,8), %rcx
movq %rcx, 0x1a160(%rbx,%rax,8)
movq 0x82a1(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %edi
callq 0x21b0
movzwl 0x62(%rbx), %edi
callq 0x7cf0
jmp 0x6425
movq 0x8272(%rip), %rax      # 0xe370
movswq 0x9e(%rbx), %rcx
imulq $0x1030, %rcx, %rcx     # imm = 0x1030
addq %rcx, %rax
cmpl $0x2, 0x10(%rax)
jne 0x6404
jmp 0x611c
movq 0xa0(%rbx), %rax
movq 0x8246(%rip), %rcx      # 0xe370
movswq 0x9e(%rbx), %rdx
imulq $0x1030, %rdx, %rdx     # imm = 0x1030
addq %rdx, %rcx
movzwl 0x14(%rcx), %ecx
cmpq %rcx, %rax
jge 0x623c
leaq 0x82d4(%rip), %rax      # 0xe424
movzbl (%rax), %ecx
movl $0x3, %eax
cmpl %ecx, %eax
jg 0x618e
movq 0xa0(%rbx), %rsi
movq 0x8206(%rip), %rax      # 0xe370
movswq 0x9e(%rbx), %rcx
imulq $0x1030, %rcx, %rcx     # imm = 0x1030
addq %rcx, %rax
movzwl 0x14(%rax), %edx
leaq 0x4530(%rip), %rdi      # 0xa6b7
movb $0x0, %al
callq 0x84c0
movq 0x81e3(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %edi
movq 0x81c7(%rip), %rsi      # 0xe370
movswq 0x9e(%rbx), %rax
imulq $0x1030, %rax, %rax     # imm = 0x1030
addq %rax, %rsi
addq $0x10, %rsi
addq 0xa0(%rbx), %rsi
movq 0x81a3(%rip), %rax      # 0xe370
movswq 0x9e(%rbx), %rcx
imulq $0x1030, %rcx, %rcx     # imm = 0x1030
addq %rcx, %rax
movzwl 0x14(%rax), %eax
movl %eax, %edx
subq 0xa0(%rbx), %rdx
callq 0x21d0
movq %rax, 0x48(%rbx)
cmpq $0x0, 0x48(%rbx)
jge 0x6225
movq 0x8175(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movb 0x5(%rax), %cl
addb $0x1, %cl
movb %cl, 0x5(%rax)
leaq 0x44b2(%rip), %rdi      # 0xa6d0
callq 0x2360
jmp 0x6237
movq 0x48(%rbx), %rax
addq 0xa0(%rbx), %rax
movq %rax, 0xa0(%rbx)
jmp 0x611c
movq 0x8135(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x8(%rax)
leaq 0x81c3(%rip), %rax      # 0xe424
movzbl (%rax), %ecx
movl $0x3, %eax
cmpl %ecx, %eax
jg 0x6364
movq 0x8100(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rax
movq %rax, 0x18(%rbx)
movq 0x80e6(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movl 0x44(%rax), %edi
callq 0x20c0
movq %rax, 0x20(%rbx)
movq 0x80c8(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movzwl 0x42(%rax), %edi
callq 0x2300
movq 0x18(%rbx), %rsi
movq 0x20(%rbx), %rdx
movzwl %ax, %ecx
movq 0x80a2(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %edi
imulq $0x50, %rdi, %rdi
addq %rdi, %rax
movq 0x8(%rax), %r8
movq 0x8084(%rip), %rax      # 0xe370
movswq 0x9e(%rbx), %rdi
imulq $0x1030, %rdi, %rdi     # imm = 0x1030
addq %rdi, %rax
movq 0x18(%rax), %r9
movq 0x806f(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %edi
imulq $0x50, %rdi, %rdi
addq %rdi, %rax
movq 0x8(%rax), %r10
movq 0x8051(%rip), %rax      # 0xe370
movswq 0x9e(%rbx), %rdi
imulq $0x1030, %rdi, %rdi     # imm = 0x1030
addq %rdi, %rax
movq 0x18(%rax), %r11
leaq 0x41d1(%rip), %rax      # 0xa50d
leaq 0x41c4(%rip), %rdi      # 0xa507
cmpq %r11, %r10
cmoveq %rdi, %rax
leaq 0x482e(%rip), %rdi      # 0xab7f
subq $0x10, %rsp
movq %rax, (%rsp)
movb $0x0, %al
callq 0x84c0
addq $0x10, %rsp
movl 0x802a(%rip), %edi      # 0xe394
movq 0x7fff(%rip), %rsi      # 0xe370
movswq 0x9e(%rbx), %rax
imulq $0x1030, %rax, %rax     # imm = 0x1030
addq %rax, %rsi
addq $0x10, %rsi
addq $0x10, %rsi
movq 0xa0(%rbx), %rdx
xorl %eax, %eax
addq $0x10, %rax
subq %rax, %rdx
callq 0x20b0
movq %rax, 0xa8(%rbx)
cmpq $0x0, 0xa8(%rbx)
jge 0x63da
movq 0x7fc0(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movb 0x5(%rax), %cl
addb $0x1, %cl
movb %cl, 0x5(%rax)
leaq 0x47f6(%rip), %rdi      # 0xabc9
callq 0x2360
jmp 0x6425
leaq 0x8043(%rip), %rax      # 0xe424
movzbl (%rax), %ecx
movl $0x3, %eax
cmpl %ecx, %eax
jg 0x6402
movq 0xa8(%rbx), %rsi
leaq 0x4339(%rip), %rdi      # 0xa734
movb $0x0, %al
callq 0x84c0
jmp 0x641f
movq 0x7f6d(%rip), %rax      # 0xe378
movzwl 0x62(%rbx), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movb 0x5(%rax), %cl
addb $0x1, %cl
movb %cl, 0x5(%rax)
jmp 0x6421
jmp 0x6423
jmp 0x6425
movw 0x62(%rbx), %ax
addw $0x1, %ax
movw %ax, 0x62(%rbx)
jmp 0x5dba
movl 0x7f5c(%rip), %eax      # 0xe398
movl $0x40, %ecx
cltd
idivl %ecx
cltq
movq 0x1a160(%rbx,%rax,8), %rax
movq %rax, 0x10(%rbx)
movl 0x7f40(%rip), %eax      # 0xe398
movl $0x40, %ecx
cltd
idivl %ecx
movq 0x10(%rbx), %rax
movl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
je 0x64ce
movl 0x7f18(%rip), %edi      # 0xe398
leaq 0xc7(%rbx), %rsi
movl $0x1, %edx
callq 0x21d0
movq %rax, 0xa0(%rbx)
cmpq $0x0, 0xa0(%rbx)
jge 0x64cc
leaq 0x7f7b(%rip), %rax      # 0xe424
movzbl (%rax), %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jg 0x64c0
leaq 0x4726(%rip), %rdi      # 0xabdf
movb $0x0, %al
callq 0x84c0
leaq 0x4718(%rip), %rdi      # 0xabdf
callq 0x2360
jmp 0x64ce
movl 0x7ebc(%rip), %eax      # 0xe390
movl $0x40, %ecx
cltd
idivl %ecx
cltq
movq 0x1a160(%rbx,%rax,8), %rax
movq %rax, 0x8(%rbx)
movl 0x7ea0(%rip), %eax      # 0xe390
movl $0x40, %ecx
cltd
idivl %ecx
movq 0x8(%rbx), %rax
movl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
je 0x651e
leaq 0x7e87(%rip), %rdi      # 0xe3a0
callq 0x21f0
jmp 0x596c
movl 0x7e6f(%rip), %edi      # 0xe398
callq 0x21b0
movl 0x7e68(%rip), %edi      # 0xe39c
callq 0x21b0
movl 0x7e51(%rip), %edi      # 0xe390
callq 0x21b0
movl 0x7e4a(%rip), %edi      # 0xe394
callq 0x21b0
movb $0x1, 0xc6(%rbx)
movq 0x90(%rbx), %rax
movq %rax, %rsp
movb 0xc6(%rbx), %al
movb %al, 0x7(%rbx)
movq %fs:0x28, %rax
movq 0x1a1e0(%rbx), %rcx
cmpq %rcx, %rax
jne 0x6588
movb 0x7(%rbx), %al
leaq -0x8(%rbp), %rsp
popq %rbx
popq %rbp
retq
callq 0x2100
nopl (%rax)