// File: /workspace/github_c_makefile_star2_O3/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 $0x58, %rsp
movl $0x4, %r13d
testb %dl, %dl
jne 0x79e8
movq %rdi, %r12
movq %rsi, %rdi
xorl %esi, %esi
xorl %eax, %eax
callq 0x2230
testl %eax, %eax
js 0x79ce
movl %eax, %ebx
leaq 0x7(%rsp), %rsi
movl $0x1, %edx
movl %eax, %edi
callq 0x2140
testq %rax, %rax
je 0x79c2
leaq 0x7(%rsp), %r15
leaq 0x3f(%rsp), %r14
leaq 0x2c70(%rip), %r13      # 0xa337
leaq 0x8(%rsp), %rbp
movl $0x0, 0x20(%rsp)
movq $0x0, 0x10(%rsp)
movzbl 0x7(%rsp), %eax
cmpl $0xa, %eax
je 0x76ec
cmpl $0xd, %eax
jne 0x7705
movl $0x1, %edx
movl %ebx, %edi
movq %r15, %rsi
callq 0x2140
testq %rax, %rax
jne 0x76dd
jmp 0x79c2
cmpl $0x3a, %eax
jne 0x79d6
movb $0x0, 0x47(%rsp)
movl $0x8, %edx
movl %ebx, %edi
movq %r14, %rsi
callq 0x2140
cmpq $0x8, %rax
jne 0x79d6
movq %r14, %rdi
movq %r13, %rsi
movq %rbp, %rdx
leaq 0x2c(%rsp), %rcx
leaq 0x1c(%rsp), %r8
xorl %eax, %eax
callq 0x21e0
movl $0x2, %r13d
cmpl $0x3, %eax
jne 0x79e1
movl 0x8(%rsp), %ebp
movl 0x2c(%rsp), %esi
movl 0x1c(%rsp), %edx
cmpl $0x4, %edx
movq %r12, 0x48(%rsp)
je 0x77c7
cmpl $0x2, %edx
je 0x77c7
testl %edx, %edx
jne 0x77d0
movl %edx, 0x54(%rsp)
movl %esi, 0x50(%rsp)
subl 0x20(%rsp), %esi
movl %esi, 0xc(%rsp)
movq 0x10(%r12), %rdi
addq %rbp, %rsi
addq (%r12), %rsi
callq 0x21f0
movq %rax, 0x10(%r12)
movl 0xc(%rsp), %ecx
movq (%r12), %r12
testq %rcx, %rcx
je 0x77dd
leaq (%rax,%r12), %rdi
movl $0xff, %esi
movq %rcx, %rdx
movq %rcx, 0x20(%rsp)
movq %rax, %r14
callq 0x2100
addq 0x20(%rsp), %r12
jmp 0x77e0
movq $0x0, 0x10(%rsp)
movl %ebp, %eax
movq $0x0, 0x30(%rsp)
jmp 0x7809
movq %rax, %r14
movl 0x8(%rsp), %eax
movl 0x2c(%rsp), %ecx
addl %eax, %ecx
movl %ecx, 0x20(%rsp)
addq %r12, %r14
movq %r14, 0x30(%rsp)
addq %rax, %r12
movq 0x48(%rsp), %r14
movq %r12, (%r14)
movl 0x54(%rsp), %edx
movl 0x50(%rsp), %esi
movl %esi, %ecx
shrl $0x8, %ecx
addl %esi, %ebp
addl %ecx, %ebp
addl %edx, %ebp
movb $0x0, 0x41(%rsp)
testl %eax, %eax
je 0x78ac
xorl %r12d, %r12d
movl $0x2, %edx
movl %ebx, %edi
leaq 0x3f(%rsp), %r14
movq %r14, %rsi
callq 0x2140
cmpq $0x2, %rax
jne 0x79e1
movq %r14, %rdi
leaq 0x22ec(%rip), %rsi      # 0x9b38
leaq 0xc(%rsp), %rdx
xorl %eax, %eax
callq 0x21e0
cmpl $0x1, %eax
jne 0x79e1
movl 0xc(%rsp), %eax
movl 0x1c(%rsp), %ecx
cmpl $0x4, %ecx
je 0x788b
cmpl $0x2, %ecx
je 0x788b
testl %ecx, %ecx
jne 0x789a
movq 0x30(%rsp), %rcx
testq %rcx, %rcx
je 0x79d6
movb %al, (%rcx,%r12)
jmp 0x789a
movq 0x10(%rsp), %rcx
shll $0x8, %ecx
orl %eax, %ecx
movq %rcx, 0x10(%rsp)
addl %eax, %ebp
incq %r12
movl 0x8(%rsp), %eax
cmpq %rax, %r12
jb 0x7824
movl $0x2, %edx
movl %ebx, %edi
leaq 0x3f(%rsp), %r14
movq %r14, %rsi
callq 0x2140
cmpq $0x2, %rax
jne 0x79e1
movq %r14, %rdi
leaq 0x2264(%rip), %rsi      # 0x9b38
leaq 0xc(%rsp), %rdx
xorl %eax, %eax
callq 0x21e0
cmpl $0x1, %eax
jne 0x79e1
addb 0xc(%rsp), %bpl
jne 0x79e1
movl 0x1c(%rsp), %eax
cmpl $0x2, %eax
je 0x792b
cmpl $0x4, %eax
movq 0x48(%rsp), %r12
leaq 0x8(%rsp), %rbp
je 0x7921
cmpl $0x1, %eax
leaq 0x2a21(%rip), %r13      # 0xa337
jne 0x76ec
jmp 0x79de
movq 0x10(%rsp), %rcx
shll $0xc, %ecx
jmp 0x793a
movq 0x48(%rsp), %r12
leaq 0x8(%rsp), %rbp
movq 0x10(%rsp), %rcx
shll $0x4, %ecx
movl 0x18(%r12), %eax
testl %eax, %eax
movq %rcx, 0x10(%rsp)
jne 0x7952
cmpq $0x0, (%r12)
je 0x79a9
movl %ecx, %ebp
subl %eax, %ebp
jb 0x79e1
movl $0x0, 0x20(%rsp)
cmpq %rbp, (%r12)
leaq 0x29c8(%rip), %r13      # 0xa337
jae 0x799f
movq 0x10(%r12), %rdi
movq %rbp, %rsi
callq 0x21f0
movq %rax, 0x10(%r12)
movq (%r12), %rcx
leaq (%rax,%rcx), %rdi
movq %rbp, %rdx
subq %rcx, %rdx
movl $0xff, %esi
callq 0x2100
movq %rbp, (%r12)
leaq 0x8(%rsp), %rbp
jmp 0x76ec
movl %ecx, 0x18(%r12)
movl $0x0, 0x20(%rsp)
leaq 0x297a(%rip), %r13      # 0xa337
jmp 0x76ec
movl %ebx, %edi
callq 0x2120
xorl %r13d, %r13d
jmp 0x79e8
movl $0x1, %r13d
jmp 0x79e8
movl $0x2, %r13d
jmp 0x79e8
xorl %r13d, %r13d
movl %ebx, %edi
callq 0x2120
movl %r13d, %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq