// File: /workspace/github_c_makefile_star2_O0/sTeeLM[P]dwipe/pass.c
// Function: dwipe_static_verify
int dwipe_static_verify( DWIPE_METHOD_SIGNATURE, dwipe_pattern_t* pattern )
{
/**
 * Verifies that a static 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;

	/* A pointer into the pattern buffer. */
	char* q;

	/* The pattern buffer window offset. */
	int w = 0;

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

	if( pattern == NULL )
	{
		/* Caught insanity. */	
		dwipe_log( DWIPE_LOG_SANITY, "dwipe_static_verify: Null entropy pointer." );
		return -1;
	}

	if( pattern->length <= 0 )
	{
		/* Caught insanity. */	
		dwipe_log( DWIPE_LOG_SANITY, "dwipe_static_verify: The pattern length member is %i.", pattern->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 + pattern->length * 2 );

	/* 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;
	}

	for( q = d ; q < d + c->device_stat.st_blksize * 1024 + pattern->length ; q += pattern->length )
	{
		/* Fill the pattern buffer with the pattern. */
		memcpy( q, pattern->s, pattern->length );
	}

	/* 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 );
	}


	/* 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, "dwipe_static_verify: lseek() returned a bogus offset on '%s'.", c->device_name );
		return -1;
	}


	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. */
		/* 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 )
		{
			/* Check every byte in the buffer. */
			if( memcmp( b, &d[w], r ) != 0 ) { c->verify_errors += 1; }
		}
		else
		{
			/* The number of bytes that were not read. */
			int s = blocksize - r;

			/* TODO: Handle a partial read. */

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

			/* 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 */

		/* Adjust the window. */
		w = ( c->device_stat.st_blksize * 1024 + w ) % pattern->length;

		/* Intuition check: 
		 *   If the pattern length evenly divides the block size
		 *   then ( w == 0 ) always.
		 */

		/* 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:
subq $0x68, %rsp
movq %rdi, 0x58(%rsp)
movq %rsi, 0x50(%rsp)
movl $0x0, 0x1c(%rsp)
movq 0x58(%rsp), %rax
movq 0x230(%rax), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, 0x50(%rsp)
jne 0xdf6f
movl $0x7, %edi
leaq 0x4216(%rip), %rsi      # 0x12171
movb $0x0, %al
callq 0xade0
movl $0xffffffff, 0x64(%rsp) # imm = 0xFFFFFFFF
jmp 0xe446
movq 0x50(%rsp), %rax
cmpl $0x0, (%rax)
jg 0xdfa0
movq 0x50(%rsp), %rax
movl (%rax), %edx
movl $0x7, %edi
leaq 0x4210(%rip), %rsi      # 0x1219c
movb $0x0, %al
callq 0xade0
movl $0xffffffff, 0x64(%rsp) # imm = 0xFFFFFFFF
jmp 0xe446
movq 0x58(%rsp), %rax
movq 0x270(%rax), %rdi
shlq $0xa, %rdi
callq 0x32f0
movq %rax, 0x30(%rsp)
cmpq $0x0, 0x30(%rsp)
jne 0xdffc
callq 0x3070
movl (%rax), %edi
leaq 0x4202(%rip), %rsi      # 0x121d2
leaq 0x1bf2(%rip), %rdx      # 0xfbc9
callq 0xb160
movl $0x6, %edi
leaq 0x3f10(%rip), %rsi      # 0x11ef8
movb $0x0, %al
callq 0xade0
movl $0xffffffff, 0x64(%rsp) # imm = 0xFFFFFFFF
jmp 0xe446
movq 0x58(%rsp), %rax
movq 0x270(%rax), %rdi
shlq $0xa, %rdi
movq 0x50(%rsp), %rax
movl (%rax), %eax
shll %eax
cltq
addq %rax, %rdi
callq 0x32f0
movq %rax, 0x28(%rsp)
cmpq $0x0, 0x28(%rsp)
jne 0xe066
callq 0x3070
movl (%rax), %edi
leaq 0x4198(%rip), %rsi      # 0x121d2
leaq 0x1b88(%rip), %rdx      # 0xfbc9
callq 0xb160
movl $0x6, %edi
leaq 0x3ed6(%rip), %rsi      # 0x11f28
movb $0x0, %al
callq 0xade0
movl $0xffffffff, 0x64(%rsp) # imm = 0xFFFFFFFF
jmp 0xe446
movq 0x28(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rax
movq 0x28(%rsp), %rcx
movq 0x58(%rsp), %rdx
movq 0x270(%rdx), %rdx
shlq $0xa, %rdx
addq %rdx, %rcx
movq 0x50(%rsp), %rdx
movslq (%rdx), %rdx
addq %rdx, %rcx
cmpq %rcx, %rax
jae 0xe0d1
movq 0x20(%rsp), %rdi
movq 0x50(%rsp), %rax
movq 0x8(%rax), %rsi
movq 0x50(%rsp), %rax
movslq (%rax), %rdx
callq 0x3290
movq 0x50(%rsp), %rax
movl (%rax), %ecx
movq 0x20(%rsp), %rax
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, 0x20(%rsp)
jmp 0xe070
movq 0x58(%rsp), %rax
movw $0x1, 0x57c(%rax)
movq 0x58(%rsp), %rax
movl 0x8(%rax), %edi
callq 0x3080
movl %eax, 0x4c(%rsp)
movq 0x58(%rsp), %rax
movw $0x0, 0x57c(%rax)
cmpl $0x0, 0x4c(%rsp)
je 0xe13e
callq 0x3070
movl (%rax), %edi
leaq 0x40bf(%rip), %rsi      # 0x121d2
leaq 0x3e40(%rip), %rdx      # 0x11f5a
callq 0xb160
movq 0x58(%rsp), %rax
movq 0x228(%rax), %rdx
movl $0x4, %edi
leaq 0x3e2d(%rip), %rsi      # 0x11f64
movb $0x0, %al
callq 0xade0
movq 0x58(%rsp), %rax
movl 0x8(%rax), %edi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x33f0
movq %rax, 0x38(%rsp)
cmpq $-0x1, 0x38(%rsp)
jne 0xe1a4
callq 0x3070
movl (%rax), %edi
leaq 0x4066(%rip), %rsi      # 0x121d2
leaq 0x1c3f(%rip), %rdx      # 0xfdb2
callq 0xb160
movq 0x58(%rsp), %rax
movq 0x228(%rax), %rdx
movl $0x6, %edi
leaq 0x1c4e(%rip), %rsi      # 0xfdde
movb $0x0, %al
callq 0xade0
movl $0xffffffff, 0x64(%rsp) # imm = 0xFFFFFFFF
jmp 0xe446
cmpq $0x0, 0x38(%rsp)
je 0xe1d8
movq 0x58(%rsp), %rax
movq 0x228(%rax), %rdx
movl $0x7, %edi
leaq 0x4022(%rip), %rsi      # 0x121e6
movb $0x0, %al
callq 0xade0
movl $0xffffffff, 0x64(%rsp) # imm = 0xFFFFFFFF
jmp 0xe446
jmp 0xe1da
cmpq $0x0, 0x10(%rsp)
jbe 0xe42a
movq 0x58(%rsp), %rax
movq 0x270(%rax), %rax
shlq $0xa, %rax
cmpq 0x10(%rsp), %rax
jae 0xe214
movq 0x58(%rsp), %rax
movq 0x270(%rax), %rax
shlq $0xa, %rax
movq %rax, 0x40(%rsp)
jmp 0xe250
movq 0x10(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x58(%rsp), %rax
movq 0x228(%rax), %rcx
movq 0x58(%rsp), %rax
movq 0x270(%rax), %r8
movl $0x4, %edi
leaq 0x3d40(%rip), %rsi      # 0x11f82
leaq 0x3f89(%rip), %rdx      # 0x121d2
movb $0x0, %al
callq 0xade0
movq 0x58(%rsp), %rax
movl 0x8(%rax), %edi
movq 0x30(%rsp), %rsi
movq 0x40(%rsp), %rdx
callq 0x3230
movl %eax, 0x4c(%rsp)
cmpl $0x0, 0x4c(%rsp)
jge 0xe2b8
callq 0x3070
movl (%rax), %edi
leaq 0x3f52(%rip), %rsi      # 0x121d2
leaq 0x3198(%rip), %rdx      # 0x1141f
callq 0xb160
movq 0x58(%rsp), %rax
movq 0x228(%rax), %rdx
movl $0x5, %edi
leaq 0x3d1b(%rip), %rsi      # 0x11fbf
movb $0x0, %al
callq 0xade0
movl $0xffffffff, 0x64(%rsp) # imm = 0xFFFFFFFF
jmp 0xe446
movslq 0x4c(%rsp), %rax
cmpq 0x40(%rsp), %rax
jne 0xe301
movq 0x30(%rsp), %rdi
movq 0x28(%rsp), %rsi
movslq 0x1c(%rsp), %rax
addq %rax, %rsi
movslq 0x4c(%rsp), %rdx
callq 0x3240
cmpl $0x0, %eax
je 0xe2fc
movq 0x58(%rsp), %rax
movq 0x588(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x588(%rax)
jmp 0xe3b8
movq 0x40(%rsp), %rax
movslq 0x4c(%rsp), %rcx
subq %rcx, %rax
movl %eax, 0xc(%rsp)
movq 0x58(%rsp), %rax
movq 0x588(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x588(%rax)
movq 0x58(%rsp), %rax
movq 0x228(%rax), %rdx
movl 0xc(%rsp), %ecx
movl $0x4, %edi
leaq 0x3edf(%rip), %rsi      # 0x12224
movb $0x0, %al
callq 0xade0
movq 0x58(%rsp), %rax
movl 0x8(%rax), %edi
movslq 0xc(%rsp), %rsi
movl $0x1, %edx
callq 0x33f0
movq %rax, 0x38(%rsp)
cmpq $-0x1, 0x38(%rsp)
jne 0xe3b6
callq 0x3070
movl (%rax), %edi
leaq 0x3e54(%rip), %rsi      # 0x121d2
leaq 0x1a2d(%rip), %rdx      # 0xfdb2
callq 0xb160
movq 0x58(%rsp), %rax
movq 0x228(%rax), %rdx
movl $0x5, %edi
leaq 0x3c63(%rip), %rsi      # 0x12005
movb $0x0, %al
callq 0xade0
movl $0xffffffff, 0x64(%rsp) # imm = 0xFFFFFFFF
jmp 0xe446
jmp 0xe3b8
movq 0x58(%rsp), %rax
movq 0x270(%rax), %rax
shlq $0xa, %rax
movslq 0x1c(%rsp), %rcx
addq %rcx, %rax
movq 0x50(%rsp), %rcx
movslq (%rcx), %rcx
cqto
idivq %rcx
movl %edx, %eax
movl %eax, 0x1c(%rsp)
movslq 0x4c(%rsp), %rcx
movq 0x10(%rsp), %rax
subq %rcx, %rax
movq %rax, 0x10(%rsp)
movslq 0x4c(%rsp), %rcx
movq 0x58(%rsp), %rax
addq 0x340(%rax), %rcx
movq %rcx, 0x340(%rax)
movslq 0x4c(%rsp), %rcx
movq 0x58(%rsp), %rax
addq 0x2f0(%rax), %rcx
movq %rcx, 0x2f0(%rax)
jmp 0xe1da
movq 0x30(%rsp), %rdi
callq 0x3060
movq 0x28(%rsp), %rdi
callq 0x3060
movl $0x0, 0x64(%rsp)
movl 0x64(%rsp), %eax
addq $0x68, %rsp
retq
nop