// File: /workspace/github_c_makefile_star2_O2/sabotage-linux[P]libnl-tiny/nl.c
// Function: nl_recv
int nl_recv(struct nl_sock *sk, struct sockaddr_nl *nla,
	    unsigned char **buf, struct ucred **creds)
{
	int n;
	int flags = 0;
	static int page_size = 0;
	struct iovec iov;
	struct msghdr msg = {
		.msg_name = (void *) nla,
		.msg_namelen = sizeof(struct sockaddr_nl),
		.msg_iov = &iov,
		.msg_iovlen = 1,
		.msg_control = NULL,
		.msg_controllen = 0,
		.msg_flags = 0,
	};
	struct cmsghdr *cmsg;

	if (sk->s_flags & NL_MSG_PEEK)
		flags |= MSG_PEEK;

	if (page_size == 0)
		page_size = getpagesize() * 4;

	iov.iov_len = page_size;
	iov.iov_base = *buf = calloc(1, iov.iov_len);
	if (!*buf)
		return -nl_syserr2nlerr(errno);

	if (sk->s_flags & NL_SOCK_PASSCRED) {
		msg.msg_controllen = CMSG_SPACE(sizeof(struct ucred));
		msg.msg_control = calloc(1, msg.msg_controllen);
	}
retry:

	n = recvmsg(sk->s_fd, &msg, flags);
	if (!n)
		goto abort;
	else if (n < 0) {
		if (errno == EINTR) {
			NL_DBG(3, "recvmsg() returned EINTR, retrying\n");
			goto retry;
		} else if (errno == EAGAIN) {
			NL_DBG(3, "recvmsg() returned EAGAIN, aborting\n");
			goto abort;
		} else {
			free(msg.msg_control);
			free(*buf);
			*buf = NULL;
			return -nl_syserr2nlerr(errno);
		}
	}

	if (iov.iov_len < (size_t) n ||
	    msg.msg_flags & MSG_TRUNC) {
		/* Provided buffer is not long enough, enlarge it
		 * and try again. */
		iov.iov_len *= 2;
		iov.iov_base = *buf = realloc(*buf, iov.iov_len);
		goto retry;
	} else if (msg.msg_flags & MSG_CTRUNC) {
		msg.msg_controllen *= 2;
		msg.msg_control = realloc(msg.msg_control, msg.msg_controllen);
		goto retry;
	} else if (flags != 0) {
		/* Buffer is big enough, do the actual reading */
		flags = 0;
		goto retry;
	}

	if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
		free(msg.msg_control);
		free(*buf);
		*buf = NULL;
		return -NLE_NOADDR;
	}

	for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
		if (cmsg->cmsg_level == SOL_SOCKET &&
		    cmsg->cmsg_type == SCM_CREDENTIALS) {
			*creds = calloc(1, sizeof(struct ucred));
			memcpy(*creds, CMSG_DATA(cmsg), sizeof(struct ucred));
			break;
		}
	}

	free(msg.msg_control);
	return n;

abort:
	free(msg.msg_control);
	free(*buf);
	*buf = NULL;
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rcx, %rbx
movq %rdx, %r14
movq %rdi, %r15
movq %rsi, (%rsp)
movl $0xc, 0x8(%rsp)
leaq 0x38(%rsp), %rax
movq %rax, 0x10(%rsp)
movq $0x1, 0x18(%rsp)
xorps %xmm0, %xmm0
andl $0x0, 0x30(%rsp)
movups %xmm0, 0x20(%rsp)
movl 0x28(%rdi), %r12d
movl 0x7b85(%rip), %eax      # 0xb5d4
testl %eax, %eax
jne 0x3a61
callq 0x3560
shll $0x2, %eax
movl %eax, 0x7b73(%rip)      # 0xb5d4
movslq %eax, %rsi
movq %rsi, 0x40(%rsp)
pushq $0x1
popq %rdi
callq 0x32a0
movq %rax, (%r14)
movq %rax, 0x38(%rsp)
testq %rax, %rax
je 0x3b5b
movl %r12d, %ebp
shrl $0x2, %ebp
testb $0x2, %r12b
je 0x3aa7
movq $0x20, 0x28(%rsp)
pushq $0x1
popq %rdi
pushq $0x20
popq %rsi
callq 0x32a0
movq %rax, 0x20(%rsp)
andl $0x2, %ebp
movq %rsp, %r13
movl 0x18(%r15), %edi
movq %r13, %rsi
movl %ebp, %edx
callq 0x3430
movq %rax, %r12
testl %r12d, %r12d
je 0x3b69
js 0x3b1f
movq 0x40(%rsp), %rsi
movl %r12d, %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
cmpq %rax, %rsi
jb 0x3b05
movl 0x30(%rsp), %eax
testb $0x20, %al
jne 0x3b05
testb $0x8, %al
je 0x3b34
movq 0x20(%rsp), %rdi
movq 0x28(%rsp), %rsi
addq %rsi, %rsi
movq %rsi, 0x28(%rsp)
callq 0x3400
movq %rax, 0x20(%rsp)
jmp 0x3aad
addq %rsi, %rsi
movq %rsi, 0x40(%rsp)
movq (%r14), %rdi
callq 0x3400
movq %rax, (%r14)
movq %rax, 0x38(%rsp)
jmp 0x3aad
callq 0x30a0
movq %rax, %r12
movl (%rax), %eax
cmpl $0x4, %eax
je 0x3aad
jmp 0x3b64
testl %ebp, %ebp
movl $0x0, %ebp
jne 0x3aad
cmpl $0xc, 0x8(%rsp)
jne 0x3bbb
cmpq $0x10, 0x28(%rsp)
jb 0x3bd7
movq 0x20(%rsp), %r14
jmp 0x3bda
callq 0x30a0
movl (%rax), %edi
jmp 0x3b9e
cmpl $0xb, %eax
jne 0x3b84
movq 0x20(%rsp), %rdi
callq 0x3070
movq (%r14), %rdi
callq 0x3070
andq $0x0, (%r14)
xorl %r12d, %r12d
jmp 0x3ba9
movq 0x20(%rsp), %rdi
callq 0x3070
movq (%r14), %rdi
callq 0x3070
andq $0x0, (%r14)
movl (%r12), %edi
callq 0x3370
movl %eax, %r12d
negl %r12d
movl %r12d, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x20(%rsp), %rdi
callq 0x3070
movq (%r14), %rdi
callq 0x3070
andq $0x0, (%r14)
pushq $-0x13
popq %r12
jmp 0x3ba9
xorl %r14d, %r14d
movq %rsp, %r15
testq %r14, %r14
je 0x3c1c
cmpl $0x1, 0x8(%r14)
jne 0x3bf0
cmpl $0x2, 0xc(%r14)
je 0x3c00
movq %r15, %rdi
movq %r14, %rsi
callq 0x3610
movq %rax, %r14
jmp 0x3bdd
pushq $0x1
popq %rdi
pushq $0xc
popq %rsi
callq 0x32a0
movq %rax, (%rbx)
movq 0x10(%r14), %rcx
movq %rcx, (%rax)
movl 0x18(%r14), %ecx
movl %ecx, 0x8(%rax)
movq 0x20(%rsp), %rdi
callq 0x3070
jmp 0x3ba9