// File: /workspace/github_c_makefile_star2_O0/sheheryarbutt[P]Ext2-File-System/ext2_checker.c
// Function: main
int main(int argc, char **argv) {

    if(argc != 2) {
        fprintf(stderr, "Usage: ext2_checker <image file name>\n");
        exit(1);
    }
    int fd = open(argv[1], O_RDWR);

    disk = mmap(NULL, 128 * 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(disk == MAP_FAILED) {
	perror("mmap");
	exit(1);
    }
    int fixes=0;
    sb = (struct ext2_super_block *)(disk + EXT2_BLOCK_SIZE);
    gd = (struct ext2_group_desc *)(disk + (2*EXT2_BLOCK_SIZE));
	inode_table = (struct ext2_inode *)(disk + (5*EXT2_BLOCK_SIZE));

	int actual_free_inodes=0;
	int actual_free_blocks=0;
	unsigned int * bb=(unsigned int *)(disk + (EXT2_BLOCK_SIZE*3));

	for (int i=0; i<4; i++){ //4= 128/32 because 128 is the total block and 32 is 4 bytes=unsigned int
		int j=0;	
		while(j<32){
			if (bb[i]&(1<<j)){
				actual_free_blocks++;
			}	
			j++;
		}	
	}
	int j=0;
	unsigned int * ib = (unsigned int *)(disk+(EXT2_BLOCK_SIZE*4));
	while(j<32){
			if (ib[0]&(1<<j)){
				actual_free_inodes++;
			}
			j++;
	}
	int diff;
	if (sb->s_free_blocks_count!=actual_free_blocks){
		diff=abs(sb->s_free_blocks_count-actual_free_blocks);
		sb->s_free_blocks_count=actual_free_blocks;
		fixes+=diff;
		printf("Fixed: superblock's free blocks counter was off by %d compared to the bitmap\n",diff);
	}
	if (sb->s_free_inodes_count!=actual_free_inodes){
		diff=abs(sb->s_free_inodes_count-actual_free_inodes);
		sb->s_free_inodes_count=actual_free_inodes;
		fixes+=diff;
		printf("Fixed: superblock's free inodes counter was off by %d compared to the bitmap\n",diff);
	}
	if (gd->bg_free_blocks_count!=actual_free_blocks){
		diff=abs(gd->bg_free_blocks_count-actual_free_blocks);
		gd->bg_free_blocks_count=actual_free_blocks;
		fixes+=diff;
		printf("Fixed: block group's free blocks counter was off by %d compared to the bitmap\n",diff);
	}
	if (gd->bg_free_inodes_count!=actual_free_inodes){
		diff=abs(gd->bg_free_inodes_count-actual_free_inodes);
		gd->bg_free_inodes_count=actual_free_inodes;
		fixes+=diff;
		printf("Fixed: block group's free inodes counter was off by %d compared to the bitmap\n",diff);
	}
	if(fixes!=0){
		printf("%d file system inconsistencies repaired!\n",fixes);
	}else{
		printf("No file system inconsistencies detected!\n");
	}			   	   
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x2, -0x8(%rbp)
je 0x125e
movq 0x2db5(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
leaq 0xdb7(%rip), %rsi       # 0x2004
movb $0x0, %al
callq 0x10a0
movl $0x1, %edi
callq 0x1110
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x2, %esi
movb $0x0, %al
callq 0x10f0
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %r8d
xorl %eax, %eax
movl %eax, %r9d
movl $0x20000, %esi          # imm = 0x20000
movl $0x3, %edx
movl $0x1, %ecx
movq %r9, %rdi
callq 0x1070
movq %rax, 0x2e0c(%rip)      # 0x40a8
movq $-0x1, %rax
cmpq %rax, 0x2dfe(%rip)      # 0x40a8
jne 0x12c2
leaq 0xd78(%rip), %rdi       # 0x202b
callq 0x1100
movl $0x1, %edi
callq 0x1110
movl $0x0, -0x18(%rbp)
movq 0x2dd8(%rip), %rax      # 0x40a8
addq $0x400, %rax            # imm = 0x400
movq %rax, 0x2dd3(%rip)      # 0x40b0
movq 0x2dc4(%rip), %rax      # 0x40a8
addq $0x800, %rax            # imm = 0x800
movq %rax, 0x2dc7(%rip)      # 0x40b8
movq 0x2db0(%rip), %rax      # 0x40a8
addq $0x1400, %rax           # imm = 0x1400
movq %rax, 0x2dbb(%rip)      # 0x40c0
movl $0x0, -0x1c(%rbp)
movl $0x0, -0x20(%rbp)
movq 0x2d8e(%rip), %rax      # 0x40a8
addq $0xc00, %rax            # imm = 0xC00
movq %rax, -0x28(%rbp)
movl $0x0, -0x2c(%rbp)
cmpl $0x4, -0x2c(%rbp)
jge 0x137d
movl $0x0, -0x30(%rbp)
cmpl $0x20, -0x30(%rbp)
jge 0x1370
movq -0x28(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl -0x30(%rbp), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x1365
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x1338
jmp 0x1372
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x132b
movl $0x0, -0x34(%rbp)
movq 0x2d1d(%rip), %rax      # 0x40a8
addq $0x1000, %rax           # imm = 0x1000
movq %rax, -0x40(%rbp)
cmpl $0x20, -0x34(%rbp)
jge 0x13c8
movq -0x40(%rbp), %rax
movl (%rax), %eax
movl -0x34(%rbp), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x13bd
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x1395
movq 0x2ce1(%rip), %rax      # 0x40b0
movl 0xc(%rax), %eax
cmpl -0x20(%rbp), %eax
je 0x1415
movq 0x2cd2(%rip), %rax      # 0x40b0
movl 0xc(%rax), %eax
subl -0x20(%rbp), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
movl %eax, -0x44(%rbp)
movl -0x20(%rbp), %ecx
movq 0x2cb8(%rip), %rax      # 0x40b0
movl %ecx, 0xc(%rax)
movl -0x44(%rbp), %eax
addl -0x18(%rbp), %eax
movl %eax, -0x18(%rbp)
movl -0x44(%rbp), %esi
leaq 0xc22(%rip), %rdi       # 0x2030
movb $0x0, %al
callq 0x1080
movq 0x2c94(%rip), %rax      # 0x40b0
movl 0x10(%rax), %eax
cmpl -0x1c(%rbp), %eax
je 0x1462
movq 0x2c85(%rip), %rax      # 0x40b0
movl 0x10(%rax), %eax
subl -0x1c(%rbp), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
movl %eax, -0x44(%rbp)
movl -0x1c(%rbp), %ecx
movq 0x2c6b(%rip), %rax      # 0x40b0
movl %ecx, 0x10(%rax)
movl -0x44(%rbp), %eax
addl -0x18(%rbp), %eax
movl %eax, -0x18(%rbp)
movl -0x44(%rbp), %esi
leaq 0xc23(%rip), %rdi       # 0x207e
movb $0x0, %al
callq 0x1080
movq 0x2c4f(%rip), %rax      # 0x40b8
movzwl 0xc(%rax), %eax
cmpl -0x20(%rbp), %eax
je 0x14b5
movq 0x2c3f(%rip), %rax      # 0x40b8
movzwl 0xc(%rax), %eax
subl -0x20(%rbp), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
movl %eax, -0x44(%rbp)
movl -0x20(%rbp), %eax
movw %ax, %cx
movq 0x2c21(%rip), %rax      # 0x40b8
movw %cx, 0xc(%rax)
movl -0x44(%rbp), %eax
addl -0x18(%rbp), %eax
movl %eax, -0x18(%rbp)
movl -0x44(%rbp), %esi
leaq 0xc1e(%rip), %rdi       # 0x20cc
movb $0x0, %al
callq 0x1080
movq 0x2bfc(%rip), %rax      # 0x40b8
movzwl 0xe(%rax), %eax
cmpl -0x1c(%rbp), %eax
je 0x1508
movq 0x2bec(%rip), %rax      # 0x40b8
movzwl 0xe(%rax), %eax
subl -0x1c(%rbp), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
movl %eax, -0x44(%rbp)
movl -0x1c(%rbp), %eax
movw %ax, %cx
movq 0x2bce(%rip), %rax      # 0x40b8
movw %cx, 0xe(%rax)
movl -0x44(%rbp), %eax
addl -0x18(%rbp), %eax
movl %eax, -0x18(%rbp)
movl -0x44(%rbp), %esi
leaq 0xc1a(%rip), %rdi       # 0x211b
movb $0x0, %al
callq 0x1080
cmpl $0x0, -0x18(%rbp)
je 0x1521
movl -0x18(%rbp), %esi
leaq 0xc52(%rip), %rdi       # 0x216a
movb $0x0, %al
callq 0x1080
jmp 0x152f
leaq 0xc6c(%rip), %rdi       # 0x2194
movb $0x0, %al
callq 0x1080
xorl %eax, %eax
addq $0x50, %rsp
popq %rbp
retq
nopw (%rax,%rax)