// File: /workspace/github_c_makefile_star2_O0/jsummers[P]deark/modules/exepack.c
// Function: decide_output_structure
static void decide_output_structure(deark *c, lctx *d, struct exepack_output_structure *ostr)
{
	i64 cdata2_len_withpadding = 0;
	u8 have_valid_host_formatting;
	u8 cdata2_has_nonzero_bytes;
	i64 min_padding_added;
	i64 cdata2_max_len;
	i64 alignment = (i64)d->default_code_alignment;

	if(d->guest_reloc_table->len==0) {
		have_valid_host_formatting = (d->host_ei->reloc_table_pos <=
			d->host_ei->start_of_dos_code);
	}
	else {
		have_valid_host_formatting = (d->host_ei->reloc_table_pos >= 28 &&
			(d->host_ei->reloc_table_pos <= d->host_ei->start_of_dos_code));
	}

	if(!have_valid_host_formatting) {
		ostr->final_reloc_pos = 28;
		ostr->final_reloc_pos_field = ostr->final_reloc_pos;
		ostr->cdata2_pos_in_host = ostr->final_reloc_pos;
		goto done;
	}

	// If an empty reloc table is at offset < 28, pretend it's
	// at offset 28 (but we'll copy the actual position to the new file).
	ostr->final_reloc_pos_field = d->host_ei->reloc_table_pos;
	ostr->final_reloc_pos = d->host_ei->reloc_table_pos;
	if(ostr->final_reloc_pos < 28) {
		ostr->final_reloc_pos = 28;
	}

	// Notes:
	// * EXEPACK (at least ~4.05) seems to essentially delete the original
	// relocation table, and move the custom data after it ("cdata2") to
	// fill the gap. But, in most cases, it also replaces cdata2 with all
	// zero bytes. But, sometimes it leaves it intact, possibly if the
	// reloc table was at exactly offset 28.
	// * In a compressed file, the start_of_dos_code is always bumped up to
	// be at least 512. But if it needs to be larger than that, it seems to
	// only be padded to the next multiple of 16 bytes.

	// cdata2_pos_in_host always equals final_reloc_pos, but it's a separate
	// variable for clarity.
	ostr->cdata2_pos_in_host = ostr->final_reloc_pos;

	// When EXEPACK deleted the relocation table, it likely had to add some
	// padding to get back to a multiple of 16 bytes.
	// (It may add more than this, but we can't always tell how much.)
	cdata2_len_withpadding = d->host_ei->start_of_dos_code - ostr->cdata2_pos_in_host;
	min_padding_added = d->guest_reloc_table->len % 16;

	cdata2_max_len = cdata2_len_withpadding - min_padding_added;
	if(cdata2_max_len<0) cdata2_max_len = 0;

	cdata2_has_nonzero_bytes = !dbuf_is_all_zeroes(c->infile, ostr->cdata2_pos_in_host,
		cdata2_max_len);

	// If start_of_dos_code>512, we think we can figure out the exact layout
	// of the original file.
	// But if cdata2 is all 0-valued (EXEPACK may erase it like this), we deem
	// it to be better to *not* to write it all to the decompressed file.
	if(d->host_ei->start_of_dos_code > 512 && cdata2_has_nonzero_bytes) {
		ostr->cdata2_len_nopadding = cdata2_max_len;
		alignment = 16;
		goto done;
	}

	if(cdata2_has_nonzero_bytes) {
		ostr->cdata2_len_nopadding = cdata2_max_len;
	}
	else {
		ostr->cdata2_len_nopadding = 0;
	}

	if(d->host_ei->start_of_dos_code > 512) {
		// TODO? There may be applicable cases where the original alignment
		// could have been 512, and so we should respect the user's setting,
		// instead of forcing it to 16. But that's not common.
		alignment = 16;
	}

done:
	ostr->final_start_of_code = de_pad_to_n(ostr->final_reloc_pos + d->guest_reloc_table->len +
		ostr->cdata2_len_nopadding, alignment);
	ostr->final_file_size = ostr->final_start_of_code + d->dcmpr_code->len;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x10(%rbp), %rax
movslq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
cmpq $0x0, 0x18(%rax)
jne 0x6482c
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x30(%rax), %rax
movq -0x10(%rbp), %rcx
movq 0x10(%rcx), %rcx
cmpq 0x38(%rcx), %rax
setle %al
andb $0x1, %al
movzbl %al, %eax
movb %al, -0x21(%rbp)
jmp 0x64869
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rcx
xorl %eax, %eax
cmpq $0x1c, 0x30(%rcx)
movb %al, -0x41(%rbp)
jl 0x6485e
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x30(%rax), %rax
movq -0x10(%rbp), %rcx
movq 0x10(%rcx), %rcx
cmpq 0x38(%rcx), %rax
setle %al
movb %al, -0x41(%rbp)
movb -0x41(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
movb %al, -0x21(%rbp)
cmpb $0x0, -0x21(%rbp)
jne 0x6489f
movq -0x18(%rbp), %rax
movq $0x1c, 0x18(%rax)
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
jmp 0x649ce
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x30(%rax), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x30(%rax), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x18(%rbp), %rax
cmpq $0x1c, 0x18(%rax)
jge 0x648de
movq -0x18(%rbp), %rax
movq $0x1c, 0x18(%rax)
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x38(%rax), %rax
movq -0x18(%rbp), %rcx
subq (%rcx), %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movq 0x18(%rax), %rax
movl $0x10, %ecx
cqto
idivq %rcx
movq %rdx, -0x30(%rbp)
movq -0x20(%rbp), %rax
subq -0x30(%rbp), %rax
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jge 0x64939
movq $0x0, -0x38(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x18(%rbp), %rax
movq (%rax), %rsi
movq -0x38(%rbp), %rdx
callq 0x169d30
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movb %al, -0x22(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
cmpq $0x200, 0x38(%rax)      # imm = 0x200
jle 0x64992
movzbl -0x22(%rbp), %eax
cmpl $0x0, %eax
je 0x64992
movq -0x38(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movq $0x10, -0x40(%rbp)
jmp 0x649ce
cmpb $0x0, -0x22(%rbp)
je 0x649a6
movq -0x38(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
jmp 0x649b2
movq -0x18(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
cmpq $0x200, 0x38(%rax)      # imm = 0x200
jle 0x649cc
movq $0x10, -0x40(%rbp)
jmp 0x649ce
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
addq 0x18(%rax), %rdi
movq -0x18(%rbp), %rax
addq 0x8(%rax), %rdi
movq -0x40(%rbp), %rsi
callq 0x15ce90
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rcx
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rax
addq 0x18(%rax), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x28(%rax)
addq $0x50, %rsp
popq %rbp
retq