// File: /workspace/github_c_makefile_star2_O1/evilwombat[P]gopro-fw-tools/h4-section-patch.c
// Function: parse_firmware
int parse_firmware(unsigned char *buf, int size, struct section_info *output, unsigned int max_sections)
{
	unsigned int section_offset, num = 0;
	unsigned int global_header_crc, global_actual_crc;
	int length;
	int offset = 0;
	
	if (size < GLOBAL_HEADER_SIZE) {
		printf("Invalid firmware size: %d\n", size);
		return -1;
	}
	
	global_header_crc = read_word_le(buf, 0);
	global_actual_crc = get_global_crc(buf, size);
	
	printf("Global header CRC: %08x\n", global_header_crc);
	printf("Global actual CRC: %08x (%s)\n", global_actual_crc,
		(global_header_crc == global_actual_crc) ? "OK" : "MISMATCH!");
	
	if (global_header_crc != global_actual_crc) {
		printf("DANGER!!! Firmware global CRC does not match the CRC listed in the header!\n");
		printf("This is a bad thing. This firmware looks invalid.\n");
		return -1;
	}
	
	while (1) {
		if (num >= max_sections) {
			printf("Firmware contains more than %d sections. Something must be wrong.\n", max_sections);
			return -1;
		}
		
		offset = find_magic(buf, size, offset);
		if (offset < 0) {
			return num;
		}
	
		offset -= 28;
		output[num].header_crc = read_word_le(buf, offset);
		offset += 4;

		output[num].version = read_word_le(buf, offset);
		offset += 4;

		output[num].build_date = read_word_le(buf, offset);
		offset += 4;
		
		length = read_word_le(buf, offset);
		offset += 4;
		offset += 4;

		output[num].flags = read_word_le(buf, offset);
		offset += 4;

		output[num].magic = read_word_le(buf, offset);
		offset += 4;

		offset += 0x100 - 28;

		section_offset = offset;

		output[num].length = length;
		output[num].offset = section_offset;
		
		if (length < 0)
			continue;

		output[num].actual_crc = crc32(buf + section_offset, length);

		if (output[num].header_crc != output[num].actual_crc) {
			printf("WARNING!!! CRC MISMATCH WHILE PARSING SECTION %d\n", num);
			printf("Header CRC = %08x, Actual CRC = %08x\n",
			       output[num].header_crc, output[num].actual_crc);
			return -1;
		}
		
		offset += length;
		
		num++;
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
cmpl $0xdf, %esi
jg 0x1417
leaq 0xcb9(%rip), %rdi       # 0x20c4
xorl %eax, %eax
callq 0x1080
jmp 0x1616
movl %ecx, %ebp
movq %rdx, %rbx
movq %rdi, %r15
movl (%rdi), %r12d
movl %esi, (%rsp)
callq 0x13ba
movl %eax, %r13d
leaq 0xcab(%rip), %rdi       # 0x20df
movl %r12d, %esi
xorl %eax, %eax
callq 0x1080
cmpl %r13d, %r12d
leaq 0xc6f(%rip), %rax       # 0x20b7
leaq 0xc6b(%rip), %rdx       # 0x20ba
cmoveq %rax, %rdx
leaq 0xc9e(%rip), %rdi       # 0x20f8
movl %r13d, %esi
xorl %eax, %eax
callq 0x1080
cmpl %r13d, %r12d
jne 0x15fe
movq %rbx, 0x10(%rsp)
testl %ebp, %ebp
movl (%rsp), %edi
je 0x15f0
movl %edi, %r14d
negl %r14d
leaq 0xb7a(%rip), %rbx       # 0x2004
movl $0x1, %r9d
xorl %r8d, %r8d
xorl %r13d, %r13d
movl %ebp, 0x4(%rsp)
movq %r8, %rbp
shlq $0x5, %rbp
addq 0x10(%rsp), %rbp
movl %r13d, %r12d
cmpl %edi, %r12d
jge 0x1516
movslq %r12d, %rax
addq %r15, %rax
incl %r12d
xorl %edx, %edx
cmpl $0x3, %edx
ja 0x1588
movb (%rax), %cl
movl %edx, %edx
movslq (%rbx,%rdx,4), %rdx
addq %rbx, %rdx
jmpq *%rdx
xorl %edx, %edx
cmpb $-0x70, %cl
sete %dl
jmp 0x14f9
xorl %edx, %edx
cmpb $0x24, %cl
sete %dl
leal (%rdx,%rdx,2), %edx
jmp 0x14f9
xorl %edx, %edx
cmpb $-0x5d, %cl
jne 0x14f9
jmp 0x151c
xorl %edx, %edx
cmpb $-0x15, %cl
sete %dl
addl %edx, %edx
cmpb $-0x70, %cl
cmovel %r9d, %edx
incq %rax
leal (%r14,%r12), %ecx
incl %ecx
movl %r12d, %esi
incl %esi
movl %esi, %r12d
cmpl $0x1, %ecx
jne 0x14b9
movl $0xffffffff, %r12d      # imm = 0xFFFFFFFF
testl %r12d, %r12d
js 0x161c
movl %r12d, %eax
movl -0x1c(%r15,%rax), %ecx
movl %ecx, (%rbp)
movl -0x18(%r15,%rax), %ecx
movl %ecx, 0x8(%rbp)
movl -0x14(%r15,%rax), %ecx
movl %ecx, 0xc(%rbp)
movzwl -0x10(%r15,%rax), %ecx
movzbl -0xe(%r15,%rax), %r13d
shll $0x10, %r13d
orl %ecx, %r13d
movzbl -0xd(%r15,%rax), %ecx
shll $0x18, %ecx
orl %ecx, %r13d
movl -0x8(%r15,%rax), %edx
movl %edx, 0x10(%rbp)
movl -0x4(%r15,%rax), %eax
movl %eax, 0x14(%rbp)
addl $0xe4, %r12d
movl %r13d, 0x1c(%rbp)
movl %r12d, 0x18(%rbp)
testl %ecx, %ecx
js 0x14a9
jmp 0x15b4
movq 0x3a69(%rip), %rax      # 0x4ff8
movq (%rax), %rdi
leaq 0xf8b(%rip), %rsi       # 0x2524
xorl %eax, %eax
movq %r8, %r12
callq 0x10b0
movl $0x1, %r9d
movq %r12, %r8
movl (%rsp), %edi
jmp 0x1516
movq %r8, 0x8(%rsp)
movl %r12d, %edi
addq %r15, %rdi
movl %r13d, %esi
callq 0x1bc4
movl %eax, 0x4(%rbp)
cmpl %eax, (%rbp)
jne 0x162e
addl %r12d, %r13d
movq 0x8(%rsp), %r8
incq %r8
movl 0x4(%rsp), %ebp
cmpl %ebp, %r8d
movl (%rsp), %edi
movl $0x1, %r9d
jne 0x149a
leaq 0xb1f(%rip), %rdi       # 0x2116
movl %ebp, %esi
jmp 0x140b
leaq 0x1010(%rip), %rdi      # 0x2615
callq 0x1050
leaq 0x104f(%rip), %rdi      # 0x2660
callq 0x1050
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
movl %r8d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xb24(%rip), %rdi       # 0x2159
movq 0x8(%rsp), %rsi
xorl %eax, %eax
callq 0x1080
movl (%rbp), %esi
movl 0x4(%rbp), %edx
leaq 0xb3d(%rip), %rdi       # 0x218b
xorl %eax, %eax
callq 0x1080
jmp 0x1616