// File: /workspace/github_c_makefile_star2_O1/sTeeLM[P]dwipe/pass.c
// Function: dwipe_random_verify
int dwipe_random_verify( dwipe_context_t* c )
{
/**
 * Verifies that a random pass was correctly written to the device.
 *
 */

	/* The result holder. */
	int r;

	/* The IO size. */
	size_t blocksize;

	/* The result buffer for calls to lseek. */
	loff_t offset;

	/* The input buffer. */
	char* b;

	/* The pattern buffer that is used to check the input buffer. */
	char* d;

	/* The number of bytes remaining in the pass. */
	u64 z = c->device_size;


	if( c->prng_seed.s == NULL )
	{
		dwipe_log( DWIPE_LOG_SANITY, "Null seed pointer." );
		return -1;
	}

	if( c->prng_seed.length <= 0 )
	{
		dwipe_log( DWIPE_LOG_SANITY, "The entropy length member is %i.", c->prng_seed.length );
		return -1;
	}

	/* Create the input buffer. */
	b = malloc( c->device_stat.st_blksize * 1024 );

	/* Check the memory allocation. */
	if( ! b )
	{
		dwipe_perror( errno, __FUNCTION__, "malloc" );
		dwipe_log( DWIPE_LOG_FATAL, "Unable to allocate memory for the input buffer." );
		return -1;
	}

	/* Create the pattern buffer */
	d = malloc( c->device_stat.st_blksize * 1024  );

	/* Check the memory allocation. */
	if( ! d )
	{
		dwipe_perror( errno, __FUNCTION__, "malloc" );
		dwipe_log( DWIPE_LOG_FATAL, "Unable to allocate memory for the pattern buffer." );
		return -1;
	}

	/* Reset the file pointer. */
	offset = lseek( c->device_fd, 0, SEEK_SET );

	if( offset == (loff_t)-1 )
	{
		dwipe_perror( errno, __FUNCTION__, "lseek" );
		dwipe_log( DWIPE_LOG_FATAL, "Unable to reset the '%s' file offset.", c->device_name );
		return -1;
	}

	if( offset != 0 )
	{
		/* This is system insanity. */
		dwipe_log( DWIPE_LOG_SANITY, "lseek() returned a bogus offset on '%s'.", c->device_name );
		return -1;
	}

	/* Tell our parent that we are syncing the device. */
	c->sync_status = 1;

	/* Sync the device. */
	r = fdatasync( c->device_fd );

	/* Tell our parent that we have finished syncing the device. */
	c->sync_status = 0;

	if( r != 0 )
	{
		/* FIXME: Is there a better way to handle this? */
		dwipe_perror( errno, __FUNCTION__, "fdatasync" );
		dwipe_log( DWIPE_LOG_WARNING, "Buffer flush failure on '%s'.", c->device_name );
	}

	/* Reseed the PRNG. */
	c->prng->init( &c->prng_state, &c->prng_seed );

	while( z > 0 )
	{
		if( c->device_stat.st_blksize * 1024 < z )
		{
			blocksize = c->device_stat.st_blksize * 1024;
		}
		else
		{
			/* This is a seatbelt for buggy drivers and programming errors because */
			/* the device size should always be an even multiple of its blocksize. */
			blocksize = z;
			dwipe_log( DWIPE_LOG_WARNING,
			  "%s: The size of '%s' is not a multiple of its block size %i.",
			  __FUNCTION__, c->device_name, c->device_stat.st_blksize );
		}

		/* Fill the output buffer with the random pattern. */
		c->prng->read( &c->prng_state, d, blocksize );

		/* Read the buffer in from the device. */
		r = read( c->device_fd, b, blocksize );

		/* Check the result. */
		if( r < 0 )
		{
			dwipe_perror( errno, __FUNCTION__, "read" );
			dwipe_log( DWIPE_LOG_ERROR, "Unable to read from '%s'.", c->device_name );
			return -1;
		}

		/* Check for a partial read. */
		if( r != blocksize )
		{
			/* TODO: Handle a partial read. */

			/* The number of bytes that were not read. */
			int s = blocksize - r;

			dwipe_log( DWIPE_LOG_WARNING, "%s: Partial read from '%s', %i bytes short.", __FUNCTION__, c->device_name, s );
			
			/* Increment the error count. */
			c->verify_errors += 1;

			/* Bump the file pointer to the next block. */
			offset = lseek( c->device_fd, s, SEEK_CUR );

			if( offset == (loff_t)-1 )
			{
				dwipe_perror( errno, __FUNCTION__, "lseek" );
				dwipe_log( DWIPE_LOG_ERROR, "Unable to bump the '%s' file offset after a partial read.", c->device_name );
				return -1;
			}

		} /* partial read */

		/* Compare buffer contents. */
		if( memcmp( b, d, blocksize ) != 0 ) { c->verify_errors += 1; }

		/* Decrement the bytes remaining in this pass. */
		z -= r;

		/* Increment the total progress counters. */
		c->round_done += r;
		c->pass_done += r;

	} /* while bytes remaining */

	/* Release the buffers. */
	free( b );
	free( d );

	/* We're done. */
	return 0;

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
cmpq $0x0, 0x328(%rdi)
je 0x92fd
movq %rdi, %rbx
leaq 0x320(%rdi), %r13
cmpq $0x0, (%r13)
je 0x930b
movq 0x230(%rbx), %r12
movq 0x270(%rbx), %r15
shlq $0xa, %r15
movq %r15, %rdi
callq 0x32f0
testq %rax, %rax
je 0x9322
movq %rax, %r14
movq %r15, %rdi
callq 0x32f0
testq %rax, %rax
je 0x9345
movq %rax, %rbp
movl 0x8(%rbx), %edi
xorl %esi, %esi
xorl %edx, %edx
callq 0x3410
testq %rax, %rax
je 0x9386
cmpq $-0x1, %rax
jne 0x950d
callq 0x3070
movl (%rax), %edi
leaq 0x4c54(%rip), %rsi      # 0xdf30
leaq 0x2ab6(%rip), %rdx      # 0xbd99
callq 0x7c3f
movq 0x228(%rbx), %rdx
leaq 0x2acf(%rip), %rsi      # 0xbdc5
movl $0x6, %edi
jmp 0x9319
leaq 0x4d95(%rip), %rsi      # 0xe099
movl $0x7, %edi
jmp 0x936b
leaq 0x4da8(%rip), %rsi      # 0xe0ba
movl $0x7, %edi
xorl %edx, %edx
xorl %eax, %eax
callq 0x79f8
jmp 0x9372
callq 0x3070
movl (%rax), %edi
leaq 0x4c00(%rip), %rsi      # 0xdf30
leaq 0x2879(%rip), %rdx      # 0xbbb0
callq 0x7c3f
leaq 0x4c01(%rip), %rsi      # 0xdf44
jmp 0x9366
callq 0x3070
movl (%rax), %edi
leaq 0x4bdd(%rip), %rsi      # 0xdf30
leaq 0x2856(%rip), %rdx      # 0xbbb0
callq 0x7c3f
leaq 0x4c0e(%rip), %rsi      # 0xdf74
movl $0x6, %edi
xorl %eax, %eax
callq 0x79f8
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movw $0x1, 0x57c(%rbx)
movl 0x8(%rbx), %edi
callq 0x3080
movw $0x0, 0x57c(%rbx)
testl %eax, %eax
je 0x93d8
callq 0x3070
movl (%rax), %edi
leaq 0x4b7e(%rip), %rsi      # 0xdf30
leaq 0x4bed(%rip), %rdx      # 0xdfa6
callq 0x7c3f
movq 0x228(%rbx), %rdx
leaq 0x4be4(%rip), %rsi      # 0xdfb0
movl $0x4, %edi
xorl %eax, %eax
callq 0x79f8
movq 0x318(%rbx), %rax
leaq 0x330(%rbx), %rdi
movq %rdi, 0x10(%rsp)
movq %r13, %rsi
callq *0x8(%rax)
testq %r12, %r12
je 0x94f6
movq %r14, 0x8(%rsp)
movq 0x270(%rbx), %r8
movq %r8, %r13
shlq $0xa, %r13
cmpq %r12, %r13
jb 0x9436
movq 0x228(%rbx), %rcx
movl $0x4, %edi
leaq 0x4ba9(%rip), %rsi      # 0xdfce
leaq 0x4b04(%rip), %rdx      # 0xdf30
xorl %eax, %eax
callq 0x79f8
movq %r12, %r13
movq 0x318(%rbx), %rax
movq 0x10(%rsp), %rdi
movq %rbp, %rsi
movq %r13, %rdx
callq *0x10(%rax)
movl 0x8(%rbx), %edi
movq %r14, %rsi
movq %r13, %rdx
callq 0x3240
testl %eax, %eax
js 0x9525
movl %eax, %r15d
andl $0x7fffffff, %r15d      # imm = 0x7FFFFFFF
cmpq %r13, %r15
je 0x94c6
movq %rbp, %r14
movq %r13, %rbp
subq %rax, %rbp
movq 0x228(%rbx), %rcx
movl $0x4, %edi
leaq 0x4b99(%rip), %rsi      # 0xe025
leaq 0x4a9d(%rip), %rdx      # 0xdf30
movl %ebp, %r8d
xorl %eax, %eax
callq 0x79f8
incq 0x588(%rbx)
movl 0x8(%rbx), %edi
movslq %ebp, %rsi
movq %r14, %rbp
movq 0x8(%rsp), %r14
movl $0x1, %edx
callq 0x3410
cmpq $-0x1, %rax
je 0x954f
movq %r14, %rdi
movq %rbp, %rsi
movq %r13, %rdx
callq 0x3310
testl %eax, %eax
je 0x94df
incq 0x588(%rbx)
addq %r15, 0x340(%rbx)
addq %r15, 0x2f0(%rbx)
subq %r15, %r12
jne 0x93ff
movq %r14, %rdi
callq 0x3060
movq %rbp, %rdi
callq 0x3060
xorl %eax, %eax
jmp 0x9377
movq 0x228(%rbx), %rdx
leaq 0x4c11(%rip), %rsi      # 0xe12c
movl $0x7, %edi
jmp 0x9319
callq 0x3070
movl (%rax), %edi
leaq 0x49fd(%rip), %rsi      # 0xdf30
leaq 0x3f4d(%rip), %rdx      # 0xd487
callq 0x7c3f
movq 0x228(%rbx), %rdx
leaq 0x4abe(%rip), %rsi      # 0xe00b
jmp 0x9577
callq 0x3070
movl (%rax), %edi
leaq 0x49d3(%rip), %rsi      # 0xdf30
leaq 0x2835(%rip), %rdx      # 0xbd99
callq 0x7c3f
movq 0x228(%rbx), %rdx
leaq 0x4ada(%rip), %rsi      # 0xe051
movl $0x5, %edi
jmp 0x9319