// File: /workspace/github_c_makefile_star2_O0/jsummers[P]deark/modules/lzexe.c
// Function: de_run_lzexe
static void de_run_lzexe(deark *c, de_module_params *mparams)
{
	lctx *d = NULL;
	const char *s;
	struct fmtutil_specialexe_detection_data edd;

	d = de_malloc(c, sizeof(lctx));

	d->host_ei = de_malloc(c, sizeof(struct fmtutil_exe_info));

	d->raw_mode = (u8)de_get_ext_option_bool(c, "lzexe:raw", 0xff);

	s = de_get_ext_option(c, "execomp:align");
	if(s) {
		d->final_code_alignment = de_atoi(s);
	}
	if(d->final_code_alignment != 512) {
		d->final_code_alignment = 16;
	}

	fmtutil_collect_exe_info(c, c->infile, d->host_ei);

	de_zeromem(&edd, sizeof(struct fmtutil_specialexe_detection_data));
	edd.restrict_to_fmt = DE_SPECIALEXEFMT_LZEXE;
	fmtutil_detect_execomp(c, d->host_ei, &edd);
	if(edd.detected_fmt!=DE_SPECIALEXEFMT_LZEXE) {
		de_err(c, "Not an LZEXE-compressed file");
		goto done;
	}
	de_declare_fmt(c, "LZEXE-compressed EXE");
	d->ver = (int)edd.detected_subfmt;
	de_dbg(c, "LZEXE variant: %s", get_lzexe_subfmt_name(d->ver));
	if(d->ver<=3) {
		d->can_decompress_to_exe = 1;
		d->can_decompress_to_raw = 1;
	}
	else if(d->ver==LZEXE_VER_LHARK_SFX || d->ver==LZEXE_VER_PCX2EXE) {
		d->host_ei->regCS = edd.regCS_2;
		d->host_ei->regIP = edd.regIP_2;
		d->host_ei->entry_point = d->host_ei->start_of_dos_code + d->host_ei->regCS*16 +
			d->host_ei->regIP;
		d->can_decompress_to_exe = 0;
		d->can_decompress_to_raw = 1;
	}

	if(!d->can_decompress_to_raw ||
		(d->raw_mode==0 && !d->can_decompress_to_exe))
	{
		de_err(c, "Unsupported LZEXE variant");
		goto done;
	}

	if(d->raw_mode==0xff && !d->can_decompress_to_exe) {
		de_err(c, "This LZEXE variant is not fully supported");
		de_info(c, "Note: Try \"-opt lzexe:raw\" to decompress the raw data");
		goto done;
	}

	d->guest_reloc_table = dbuf_create_membuf(c, 0, 0);
	d->dcmpr_code = dbuf_create_membuf(c, 0, 0);
	dbuf_enable_wbuffer(d->dcmpr_code);

	do_read_header(c, d);
	if(d->errflag) goto done;

	d->ephdr_pos = d->host_ei->start_of_dos_code + d->host_ei->regCS*16;
	if(d->ephdr_pos > c->infile->len) {
		d->errflag = 1;
		return;
	}
	read_special_hdr(c, d, d->ephdr_pos);
	if(d->errflag) goto done;

	// TODO? Should we do this even if raw_mode==1?
	read_reloc_tbl(c, d);
	if(d->errflag) goto done;

	do_decompress_code(c, d);
	dbuf_flush(d->dcmpr_code);
	if(d->errflag) goto done;

	if(d->raw_mode==1) {
		do_write_data_only(c, d);
	}
	else {
		do_write_dcmpr(c, d);
	}

done:

	if(d) {
		if(d->errflag && !d->errmsg_handled) {
			de_err(c, "LZEXE decompression failed");
		}

		dbuf_close(d->guest_reloc_table);
		dbuf_close(d->dcmpr_code);
		de_free(c, d->host_ei);
		de_free(c, d);
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq $0x0, -0x18(%rbp)
movq -0x8(%rbp), %rdi
movl $0xa8, %esi
callq 0x15b780
movq %rax, -0x18(%rbp)
movq -0x8(%rbp), %rdi
movl $0xf0, %esi
callq 0x15b780
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x8(%rbp), %rdi
leaq 0xe5fd5(%rip), %rsi     # 0x1bac06
movl $0xff, %edx
callq 0x15cbc0
movb %al, %cl
movq -0x18(%rbp), %rax
movb %cl, 0x10(%rax)
movq -0x8(%rbp), %rdi
leaq 0xd4a05(%rip), %rsi     # 0x1a9654
callq 0x15cb30
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0xd4c71
movq -0x20(%rbp), %rdi
callq 0x15cca0
movl %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0xc(%rax)
movq -0x18(%rbp), %rax
cmpl $0x200, 0xc(%rax)       # imm = 0x200
je 0xd4c89
movq -0x18(%rbp), %rax
movl $0x10, 0xc(%rax)
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rdx
callq 0x188930
leaq -0x98(%rbp), %rdi
xorl %esi, %esi
movl $0x78, %edx
callq 0x19140
movb $0x1, -0x98(%rbp)
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rsi
leaq -0x98(%rbp), %rdx
callq 0x188c80
movzbl -0x97(%rbp), %eax
cmpl $0x1, %eax
je 0xd4cf7
movq -0x8(%rbp), %rdi
leaq 0xe5f25(%rip), %rsi     # 0x1bac10
movb $0x0, %al
callq 0x15bfb0
jmp 0xd4f96
movq -0x8(%rbp), %rdi
leaq 0xe5eef(%rip), %rsi     # 0x1babf1
callq 0x15e380
movzbl -0x96(%rbp), %ecx
movq -0x18(%rbp), %rax
movl %ecx, (%rax)
movq -0x8(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq -0x18(%rbp), %rax
movl (%rax), %edi
callq 0xd5050
movq -0xa0(%rbp), %rdi
movq %rax, %rdx
leaq 0xe5ef2(%rip), %rsi     # 0x1bac2d
movb $0x0, %al
callq 0x15b0d0
movq -0x18(%rbp), %rax
cmpl $0x3, (%rax)
jg 0xd4d5d
movq -0x18(%rbp), %rax
movb $0x1, 0x11(%rax)
movq -0x18(%rbp), %rax
movb $0x1, 0x12(%rax)
jmp 0xd4ddb
movq -0x18(%rbp), %rax
cmpl $0x66, (%rax)
je 0xd4d72
movq -0x18(%rbp), %rax
cmpl $0xca, (%rax)
jne 0xd4dd9
movq -0x68(%rbp), %rcx
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rax
movq %rcx, 0x20(%rax)
movq -0x60(%rbp), %rcx
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rax
movq %rcx, 0x28(%rax)
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x38(%rax), %rcx
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x20(%rax), %rax
shlq $0x4, %rax
addq %rax, %rcx
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rax
addq 0x28(%rax), %rcx
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rax
movq %rcx, 0x40(%rax)
movq -0x18(%rbp), %rax
movb $0x0, 0x11(%rax)
movq -0x18(%rbp), %rax
movb $0x1, 0x12(%rax)
jmp 0xd4ddb
movq -0x18(%rbp), %rax
cmpb $0x0, 0x12(%rax)
je 0xd4dfc
movq -0x18(%rbp), %rax
movzbl 0x10(%rax), %eax
cmpl $0x0, %eax
jne 0xd4e13
movq -0x18(%rbp), %rax
cmpb $0x0, 0x11(%rax)
jne 0xd4e13
movq -0x8(%rbp), %rdi
leaq 0xe5e38(%rip), %rsi     # 0x1bac3f
movb $0x0, %al
callq 0x15bfb0
jmp 0xd4f96
movq -0x18(%rbp), %rax
movzbl 0x10(%rax), %eax
cmpl $0xff, %eax
jne 0xd4e55
movq -0x18(%rbp), %rax
cmpb $0x0, 0x11(%rax)
jne 0xd4e55
movq -0x8(%rbp), %rdi
leaq 0xe5e22(%rip), %rsi     # 0x1bac59
movb $0x0, %al
callq 0x15bfb0
movq -0x8(%rbp), %rdi
leaq 0xe5e3a(%rip), %rsi     # 0x1bac83
movb $0x0, %al
callq 0x15c0c0
jmp 0xd4f96
movq -0x8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x168020
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x80(%rax)
movq -0x8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x168020
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x88(%rax)
movq -0x18(%rbp), %rax
movq 0x88(%rax), %rdi
callq 0x167b90
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xd5100
movq -0x18(%rbp), %rax
cmpl $0x0, 0x4(%rax)
je 0xd4ebb
jmp 0xd4f96
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x38(%rax), %rcx
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x20(%rax), %rax
shlq $0x4, %rax
addq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x8(%rbp), %rcx
movq 0x18(%rcx), %rcx
cmpq 0x18(%rcx), %rax
jle 0xd4f08
movq -0x18(%rbp), %rax
movl $0x1, 0x4(%rax)
jmp 0xd5001
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rdx
callq 0xd5170
movq -0x18(%rbp), %rax
cmpl $0x0, 0x4(%rax)
je 0xd4f29
jmp 0xd4f96
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xd53e0
movq -0x18(%rbp), %rax
cmpl $0x0, 0x4(%rax)
je 0xd4f42
jmp 0xd4f96
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xd5460
movq -0x18(%rbp), %rax
movq 0x88(%rax), %rdi
callq 0x167c30
movq -0x18(%rbp), %rax
cmpl $0x0, 0x4(%rax)
je 0xd4f6b
jmp 0xd4f96
movq -0x18(%rbp), %rax
movzbl 0x10(%rax), %eax
cmpl $0x1, %eax
jne 0xd4f87
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xd5750
jmp 0xd4f94
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xd57b0
jmp 0xd4f96
cmpq $0x0, -0x18(%rbp)
je 0xd5001
movq -0x18(%rbp), %rax
cmpl $0x0, 0x4(%rax)
je 0xd4fc3
movq -0x18(%rbp), %rax
cmpl $0x0, 0x8(%rax)
jne 0xd4fc3
movq -0x8(%rbp), %rdi
leaq 0xe5cfd(%rip), %rsi     # 0x1bacb9
movb $0x0, %al
callq 0x15bfb0
movq -0x18(%rbp), %rax
movq 0x80(%rax), %rdi
callq 0x1676a0
movq -0x18(%rbp), %rax
movq 0x88(%rax), %rdi
callq 0x1676a0
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rsi
callq 0x15b820
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x15b820
addq $0xa0, %rsp
popq %rbp
retq
nopw (%rax,%rax)