// File: /workspace/github_c_makefile_star2_O0/jsummers[P]deark/modules/exe.c
// Function: do_identify_exe_format
static void do_identify_exe_format(deark *c, lctx *d)
{
	u8 buf[4];

	if(d->ext_header_offset < 64 || d->ext_header_offset >= c->infile->len) {
		// Give up if ext_header_offset is obviously bad.
		identify_as_dos(c, d);
		goto done;
	}

	// TODO: Can we assume a real ext_header_offset is a multiple of 2? 4? 16?

	// If the ext hdr pointer overlaps another segment, assume DOS format.
	if(d->file_hdr_size<=60 && d->end_of_dos_code>60) {
		identify_as_dos(c, d);
		goto done;
	}
	if(d->reloc_tbl_offset>=61 && d->reloc_tbl_offset<=63) {
		identify_as_dos(c, d);
		goto done;
	}
	if(d->num_relocs>0 && d->reloc_tbl_offset<64 && d->reloc_tbl_endpos>60) {
		identify_as_dos(c, d);
		goto done;
	}

	de_read(buf, d->ext_header_offset, 4);
	if(!de_memcmp(buf, "PE\0\0", 4)) {
		d->fmt = EXE_FMT_PE;
		goto done;
	}

	if(!de_memcmp(buf, "NE", 2)) {
		// TODO: I've heard that d->ext_header_offset can be at most 64K for
		// (at least) NE format.
		d->fmt = EXE_FMT_NE;
		goto done;
	}

	if(!de_memcmp(buf, "LX", 2)) {
		d->fmt = EXE_FMT_LX;
		goto done;
	}

	if(!de_memcmp(buf, "LE", 2)) {
		d->fmt = EXE_FMT_LE;
		goto done;
	}

	if((buf[0]>='A' && buf[0]<='Z') &&
		((buf[1]>='0' && buf[1]<='9') || (buf[1]>='A' && buf[1]<='Z')))
	{
		// An unrecognized ext hdr signature that looks vaguely real...
		de_declare_fmt(c, "Unknown EXE format (maybe DOS)");
		goto done;
	}

	identify_as_dos(c, d);

done:
	;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rax
cmpq $0x40, 0x38(%rax)
jl 0x60521
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movq -0x8(%rbp), %rcx
movq 0x18(%rcx), %rcx
cmpq 0x18(%rcx), %rax
jl 0x60533
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x608f0
jmp 0x606ab
movq -0x10(%rbp), %rax
cmpq $0x3c, 0x20(%rax)
jg 0x6055b
movq -0x10(%rbp), %rax
cmpq $0x3c, 0x30(%rax)
jle 0x6055b
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x608f0
jmp 0x606ab
movq -0x10(%rbp), %rax
cmpq $0x3d, 0x10(%rax)
jl 0x60583
movq -0x10(%rbp), %rax
cmpq $0x3f, 0x10(%rax)
jg 0x60583
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x608f0
jmp 0x606ab
movq -0x10(%rbp), %rax
cmpq $0x0, 0x28(%rax)
jle 0x605b6
movq -0x10(%rbp), %rax
cmpq $0x40, 0x10(%rax)
jge 0x605b6
movq -0x10(%rbp), %rax
cmpq $0x3c, 0x18(%rax)
jle 0x605b6
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x608f0
jmp 0x606ab
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
leaq -0x14(%rbp), %rsi
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rdx
movl $0x4, %ecx
callq 0x164d10
leaq -0x14(%rbp), %rax
movl (%rax), %eax
subl $0x4550, %eax           # imm = 0x4550
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x605f6
movq -0x10(%rbp), %rax
movb $0x3, (%rax)
jmp 0x606ab
leaq -0x14(%rbp), %rax
movw (%rax), %ax
subw $0x454e, %ax            # imm = 0x454E
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x60618
movq -0x10(%rbp), %rax
movb $0x2, (%rax)
jmp 0x606ab
leaq -0x14(%rbp), %rax
movw (%rax), %ax
subw $0x584c, %ax            # imm = 0x584C
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x60637
movq -0x10(%rbp), %rax
movb $0x5, (%rax)
jmp 0x606ab
leaq -0x14(%rbp), %rax
movw (%rax), %ax
subw $0x454c, %ax            # imm = 0x454C
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x60656
movq -0x10(%rbp), %rax
movb $0x6, (%rax)
jmp 0x606ab
movzbl -0x14(%rbp), %eax
cmpl $0x41, %eax
jl 0x6069e
movzbl -0x14(%rbp), %eax
cmpl $0x5a, %eax
jg 0x6069e
movzbl -0x13(%rbp), %eax
cmpl $0x30, %eax
jl 0x6067a
movzbl -0x13(%rbp), %eax
cmpl $0x39, %eax
jle 0x6068c
movzbl -0x13(%rbp), %eax
cmpl $0x41, %eax
jl 0x6069e
movzbl -0x13(%rbp), %eax
cmpl $0x5a, %eax
jg 0x6069e
movq -0x8(%rbp), %rdi
leaq 0x147eea(%rip), %rsi    # 0x1a8581
callq 0x15e380
jmp 0x606ab
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x608f0
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)