// File: /workspace/github_c_makefile_star2_O1/koendv[P]stm32duino-raspberrypi/Arduino_Tools/src/stm32flash/parsers/hex.c
// Function: hex_open
parser_err_t hex_open(void *storage, const char *filename, const char write) {
	hex_t *st = storage;
	if (write) {
		return PARSER_ERR_RDONLY;
	} else {
		char mark;
		int fd;
		uint8_t checksum;
		unsigned int c, i;
		uint32_t base = 0;
		unsigned int last_address = 0x0;

		fd = open(filename, O_RDONLY);
		if (fd < 0)
			return PARSER_ERR_SYSTEM;

		/* read in the file */

		while(read(fd, &mark, 1) != 0) {
			if (mark == '\n' || mark == '\r') continue;
			if (mark != ':')
				return PARSER_ERR_INVALID_FILE;

			char buffer[9];
			unsigned int reclen, address, type;
			uint8_t *record = NULL;

			/* get the reclen, address, and type */
			buffer[8] = 0;
			if (read(fd, &buffer, 8) != 8) return PARSER_ERR_INVALID_FILE;
			if (sscanf(buffer, "%2x%4x%2x", &reclen, &address, &type) != 3) {
				close(fd);
				return PARSER_ERR_INVALID_FILE;
			}

			/* setup the checksum */
			checksum =
				reclen +
				((address & 0xFF00) >> 8) +
				((address & 0x00FF) >> 0) +
				type;

			switch(type) {
				/* data record */
				case 0:
					c = address - last_address;
					st->data = realloc(st->data, st->data_len + c + reclen);

					/* if there is a gap, set it to 0xff and increment the length */
					if (c > 0) {
						memset(&st->data[st->data_len], 0xff, c);
						st->data_len += c;
					}

					last_address = address + reclen;
					record = &st->data[st->data_len];
					st->data_len += reclen;
					break;

				/* extended segment address record */
				case 2:
					base = 0;
					break;

				/* extended linear address record */
				case 4:
					base = 0;
					break;
			}

			buffer[2] = 0;
			for(i = 0; i < reclen; ++i) {
				if (read(fd, &buffer, 2) != 2 || sscanf(buffer, "%2x", &c) != 1) {
					close(fd);
					return PARSER_ERR_INVALID_FILE;
				}

				/* add the byte to the checksum */
				checksum += c;

				switch(type) {
					case 0:
						if (record != NULL) {
							record[i] = c;
						} else {
							return PARSER_ERR_INVALID_FILE;
						}
						break;

					case 2:
					case 4:
						base = (base << 8) | c;
						break;
				}
			}

			/* read, scan, and verify the checksum */
			if (
				read(fd, &buffer, 2 ) != 2 ||
				sscanf(buffer, "%2x", &c) != 1 ||
				(uint8_t)(checksum + c) != 0x00
			) {
				close(fd);
				return PARSER_ERR_INVALID_FILE;
			}

			switch(type) {
				/* EOF */
				case 1:
					close(fd);
					return PARSER_ERR_OK;

				/* address record */
				case 4:	base = base << 12;
					/* fall-through */
				case 2: base = base << 4;
					/* Reset last_address since our base changed */
					last_address = 0;

					/* Only assign the program's base address once, and only
					 * do so if we haven't seen any data records yet.
					 * If there are any data records before address records,
					 * the program's base address must be zero.
					 */
					if (st->base == 0 && st->data_len == 0) {
						st->base = base;
						break;
					}

					/* we cant cope with files out of order */
					if (base < st->base) {
						close(fd);
						return PARSER_ERR_INVALID_FILE;
					}

					/* if there is a gap, enlarge and fill with 0xff */
					unsigned int len = base - st->base;
					if (len > st->data_len) {
						st->data = realloc(st->data, len);
						memset(&st->data[st->data_len], 0xff, len - st->data_len);
						st->data_len = len;
					}
					break;
			}
		}

		close(fd);
		return PARSER_ERR_OK;
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movl $0x4, %r12d
testb %dl, %dl
jne 0x723f
movq %rdi, %rbx
movq %rsi, %rdi
xorl %esi, %esi
xorl %eax, %eax
callq 0x2230
testl %eax, %eax
js 0x7231
movl %eax, %ebp
leaq 0x7(%rsp), %r14
leaq 0x37(%rsp), %r13
leaq 0x33d2(%rip), %r15      # 0xa277
movq $0x0, 0x10(%rsp)
movl $0x0, 0x8(%rsp)
movl $0x1, %edx
movl %ebp, %edi
movq %r14, %rsi
callq 0x2140
testq %rax, %rax
je 0x7225
movzbl 0x7(%rsp), %eax
cmpl $0xa, %eax
je 0x6eb6
cmpl $0xd, %eax
je 0x6eb6
cmpl $0x3a, %eax
jne 0x7239
movb $0x0, 0x3f(%rsp)
movl $0x8, %edx
movl %ebp, %edi
movq %r13, %rsi
callq 0x2140
movl $0x2, %r12d
cmpq $0x8, %rax
jne 0x6fea
movq %r13, %rdi
movq %r15, %rsi
leaq 0x20(%rsp), %rdx
leaq 0x30(%rsp), %rcx
leaq 0x24(%rsp), %r8
xorl %eax, %eax
callq 0x21e0
cmpl $0x3, %eax
jne 0x6fe3
movl 0x20(%rsp), %r15d
movl 0x30(%rsp), %esi
movl 0x24(%rsp), %r13d
cmpl $0x4, %r13d
je 0x7007
cmpl $0x2, %r13d
je 0x7007
testl %r13d, %r13d
jne 0x700d
movl %esi, 0x28(%rsp)
subl 0x8(%rsp), %esi
movl %esi, 0xc(%rsp)
movq 0x10(%rbx), %rdi
addq %r15, %rsi
addq (%rbx), %rsi
callq 0x21f0
movq %rax, 0x10(%rbx)
movl 0xc(%rsp), %ecx
testq %rcx, %rcx
je 0x6fbe
movl %r13d, 0x8(%rsp)
movq (%rbx), %r13
leaq (%rax,%r13), %rdi
movl $0xff, %esi
movq %r15, %r14
movq %rax, %r15
movq %rcx, %rdx
movq %rcx, 0x40(%rsp)
callq 0x2100
movq %r15, %rax
movq %r14, %r15
leaq 0x7(%rsp), %r14
addq 0x40(%rsp), %r13
movq %r13, (%rbx)
movl 0x8(%rsp), %r13d
movl 0x20(%rsp), %edx
movl 0x30(%rsp), %ecx
addl %edx, %ecx
movl %ecx, 0x8(%rsp)
movq (%rbx), %rcx
addq %rcx, %rax
addq %rdx, %rcx
movq %rcx, (%rbx)
movq 0x10(%rsp), %rcx
movl 0x28(%rsp), %esi
jmp 0x7014
movl %ebp, %edi
callq 0x2120
xorl %r15d, %r15d
movl %r12d, 0x1c(%rsp)
testb %r15b, %r15b
leaq 0x327b(%rip), %r15      # 0xa277
jne 0x6eb6
jmp 0x723f
xorl %ecx, %ecx
xorl %eax, %eax
jmp 0x7014
xorl %eax, %eax
movq 0x10(%rsp), %rcx
movq %rbx, 0x28(%rsp)
movl %esi, %edx
shrl $0x8, %edx
addl %esi, %r15d
addl %edx, %r15d
addl %r13d, %r15d
movb $0x0, 0x39(%rsp)
cmpl $0x0, 0x20(%rsp)
movq %rcx, 0x10(%rsp)
je 0x70df
xorl %ebx, %ebx
movq %r15, %r14
movq %rax, %r15
movl $0x2, %edx
movl %ebp, %edi
leaq 0x37(%rsp), %r13
movq %r13, %rsi
callq 0x2140
cmpq $0x2, %rax
jne 0x712f
movq %r13, %rdi
leaq 0x2a08(%rip), %rsi      # 0x9a74
leaq 0xc(%rsp), %rdx
xorl %eax, %eax
callq 0x21e0
cmpl $0x1, %eax
jne 0x712f
movl 0xc(%rsp), %edx
movl 0x24(%rsp), %ecx
cmpl $0x4, %ecx
movq %r15, %rax
je 0x70b5
cmpl $0x2, %ecx
je 0x70b5
testl %ecx, %ecx
movq 0x10(%rsp), %rcx
movq %r14, %r15
jne 0x70c2
testq %rax, %rax
leaq 0x7(%rsp), %r14
je 0x717d
movb %dl, (%rax,%rbx)
jmp 0x70c7
movq 0x10(%rsp), %rcx
shll $0x8, %ecx
orl %edx, %ecx
movq %r14, %r15
leaq 0x7(%rsp), %r14
movq %rcx, 0x10(%rsp)
addl %edx, %r15d
incq %rbx
movl 0x20(%rsp), %ecx
cmpq %rcx, %rbx
jb 0x703e
movl $0x2, %edx
movl %ebp, %edi
leaq 0x37(%rsp), %r13
movq %r13, %rsi
callq 0x2140
cmpq $0x2, %rax
jne 0x711b
movq %r13, %rdi
leaq 0x2971(%rip), %rsi      # 0x9a74
leaq 0xc(%rsp), %rdx
xorl %eax, %eax
callq 0x21e0
cmpl $0x1, %eax
jne 0x711b
addb 0xc(%rsp), %r15b
je 0x7148
movl %ebp, %edi
callq 0x2120
xorl %r15d, %r15d
movq 0x28(%rsp), %rbx
jmp 0x6fed
movl %ebp, %edi
callq 0x2120
xorl %r15d, %r15d
movq 0x28(%rsp), %rbx
leaq 0x7(%rsp), %r14
jmp 0x6fed
movb $0x1, %r15b
movl 0x24(%rsp), %eax
cmpl $0x4, %eax
movq 0x28(%rsp), %rbx
je 0x718e
cmpl $0x2, %eax
movl 0x1c(%rsp), %edx
je 0x7187
cmpl $0x1, %eax
jne 0x721d
movl %ebp, %edi
callq 0x2120
xorl %r15d, %r15d
xorl %r12d, %r12d
jmp 0x6fed
xorl %r15d, %r15d
leaq 0x37(%rsp), %r13
jmp 0x7125
movq 0x10(%rsp), %rcx
jmp 0x719a
movq 0x10(%rsp), %rcx
shll $0xc, %ecx
movl 0x1c(%rsp), %edx
shll $0x4, %ecx
movl 0x18(%rbx), %eax
testl %eax, %eax
movq %rcx, 0x10(%rsp)
jne 0x71af
cmpq $0x0, (%rbx)
je 0x7212
subl %eax, %ecx
jae 0x71ca
movl %ebp, %edi
callq 0x2120
xorl %r15d, %r15d
movl $0x0, 0x8(%rsp)
jmp 0x6fed
movl $0x0, 0x8(%rsp)
cmpq %rcx, (%rbx)
jae 0x721d
movq 0x10(%rbx), %rdi
movq %rcx, %r12
movq %rcx, %rsi
movl %edx, 0x1c(%rsp)
callq 0x21f0
movq %rax, 0x10(%rbx)
movq (%rbx), %rcx
leaq (%rax,%rcx), %rdi
movq %r12, %rdx
subq %rcx, %rdx
movl $0xff, %esi
callq 0x2100
movq %r12, (%rbx)
movl 0x1c(%rsp), %r12d
jmp 0x6fed
movl %ecx, 0x18(%rbx)
movl $0x0, 0x8(%rsp)
movl %edx, %r12d
jmp 0x6fed
movl %ebp, %edi
callq 0x2120
xorl %r12d, %r12d
jmp 0x723f
movl $0x1, %r12d
jmp 0x723f
movl $0x2, %r12d
movl %r12d, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq