// File: ksherlock[P]wdc-utils/link.cpp
// Function: one_module(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, int, std::set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>*)
bool one_module(const std::string &name, int fd, std::set<std::string> *local_undefined = nullptr) {
	Mod_head h;
	ssize_t ok;

	ok = read(fd, &h, sizeof(h));
	if (ok == 0) return false;

	if (ok < sizeof(h)) {
		warnx("Invalid object file: %s", name.c_str());
		return false;;
	}

	le_to_host(h.h_magic);
	le_to_host(h.h_version);
	le_to_host(h.h_filtyp);
	le_to_host(h.h_namlen);
	le_to_host(h.h_recsize);
	le_to_host(h.h_secsize);
	le_to_host(h.h_symsize);
	le_to_host(h.h_optsize);
	le_to_host(h.h_tot_secs);
	le_to_host(h.h_num_secs);
	le_to_host(h.h_num_syms);

	assert(h.h_magic == MOD_MAGIC);
	assert(h.h_version == 1);
	assert(h.h_filtyp == 1);


	std::string module_name;
	{
		// now read the name (h_namlen includes 0 terminator.)
		std::vector<char> tmp;
		tmp.resize(h.h_namlen);
		ok = read(fd, tmp.data(), h.h_namlen);
		if (ok != h.h_namlen) {
			warnx("Invalid object file: %s", name.c_str());
			return false;
		}
		module_name.assign(tmp.data());
	}

	std::vector<uint8_t> record_data;
	std::vector<uint8_t> symbol_data;
	std::vector<uint8_t> section_data;

	record_data.resize(h.h_recsize);
	ok = read(fd, record_data.data(), h.h_recsize);
	if (ok != h.h_recsize) {
		warnx("Truncated object file: %s", name.c_str());
		return false;
	}

	section_data.resize(h.h_secsize);
	ok = read(fd, section_data.data(), h.h_secsize);
	if (ok != h.h_secsize) {
		warnx("Truncated object file: %s", name.c_str());
		return false;
	}

	symbol_data.resize(h.h_symsize);
	ok = read(fd, symbol_data.data(), h.h_symsize);
	if (ok != h.h_symsize)  {
		warnx("Truncated object file: %s", name.c_str());
		return false;
	}

	if (flags.v) {
		printf("Processing %s:%s\n", name.c_str(), module_name.c_str());
	}

	// should probably pass in name and module....
	one_module(record_data, section_data, symbol_data, local_undefined);
	

	if (h.h_optsize) lseek(fd, h.h_optsize, SEEK_CUR);

	return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x130, %rsp            # imm = 0x130
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movl -0x14(%rbp), %edi
leaq -0x38(%rbp), %rsi
movl $0x18, %edx
callq 0x3480
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
jne 0x6fdb
movb $0x0, -0x1(%rbp)
jmp 0x74c9
cmpq $0x18, -0x40(%rbp)
jae 0x7005
movq -0x10(%rbp), %rdi
callq 0x3130
movq %rax, %rsi
leaq 0x245ba(%rip), %rdi     # 0x2b5af
movb $0x0, %al
callq 0x3360
movb $0x0, -0x1(%rbp)
jmp 0x74c9
leaq -0x38(%rbp), %rdi
callq 0xc9b0
leaq -0x38(%rbp), %rdi
addq $0x4, %rdi
callq 0xc9d0
leaq -0x38(%rbp), %rdi
addq $0x6, %rdi
callq 0xc9f0
leaq -0x38(%rbp), %rdi
addq $0x7, %rdi
callq 0xc9f0
leaq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0xc9b0
leaq -0x38(%rbp), %rdi
addq $0xc, %rdi
callq 0xc9d0
leaq -0x38(%rbp), %rdi
addq $0xe, %rdi
callq 0xc9b0
leaq -0x38(%rbp), %rdi
addq $0x12, %rdi
callq 0xc9d0
leaq -0x38(%rbp), %rdi
addq $0x14, %rdi
callq 0xc9f0
leaq -0x38(%rbp), %rdi
addq $0x15, %rdi
callq 0xc9f0
leaq -0x38(%rbp), %rdi
addq $0x16, %rdi
callq 0xc9d0
cmpl $0x5a44525a, -0x38(%rbp) # imm = 0x5A44525A
jne 0x709b
jmp 0x70ba
leaq 0x24525(%rip), %rdi     # 0x2b5c7
leaq 0x241db(%rip), %rsi     # 0x2b284
movl $0x4ff, %edx            # imm = 0x4FF
leaq 0x24529(%rip), %rcx     # 0x2b5de
callq 0x3220
movzwl -0x34(%rbp), %eax
cmpl $0x1, %eax
jne 0x70c5
jmp 0x70e4
leaq 0x24555(%rip), %rdi     # 0x2b621
leaq 0x241b1(%rip), %rsi     # 0x2b284
movl $0x500, %edx            # imm = 0x500
leaq 0x244ff(%rip), %rcx     # 0x2b5de
callq 0x3220
movzbl -0x32(%rbp), %eax
cmpl $0x1, %eax
jne 0x70ef
jmp 0x710e
leaq 0x2453c(%rip), %rdi     # 0x2b632
leaq 0x24187(%rip), %rsi     # 0x2b284
movl $0x501, %edx            # imm = 0x501
leaq 0x244d5(%rip), %rcx     # 0x2b5de
callq 0x3220
leaq -0x60(%rbp), %rdi
callq 0x3460
leaq -0x78(%rbp), %rdi
movq %rdi, -0xd8(%rbp)
callq 0xca10
movq -0xd8(%rbp), %rdi
movzbl -0x31(%rbp), %eax
movl %eax, %esi
callq 0xca30
jmp 0x713b
movl -0x14(%rbp), %eax
movl %eax, -0xe4(%rbp)
leaq -0x78(%rbp), %rdi
callq 0xcac0
movl -0xe4(%rbp), %edi
movq %rax, %rsi
movzbl -0x31(%rbp), %eax
movl %eax, %edx
callq 0x3480
movq %rax, -0xe0(%rbp)
jmp 0x716a
movq -0xe0(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movzbl -0x31(%rbp), %ecx
cmpq %rcx, %rax
je 0x71cb
movq -0x10(%rbp), %rdi
callq 0x3130
movq %rax, %rsi
leaq 0x2441a(%rip), %rdi     # 0x2b5af
xorl %eax, %eax
callq 0x3360
jmp 0x719e
movb $0x0, -0x1(%rbp)
movl $0x1, -0x88(%rbp)
jmp 0x71ec
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x78(%rbp), %rdi
callq 0xcae0
jmp 0x74be
leaq -0x78(%rbp), %rdi
callq 0xcac0
movq %rax, %rsi
leaq -0x60(%rbp), %rdi
callq 0x35e0
jmp 0x71e2
movl $0x0, -0x88(%rbp)
leaq -0x78(%rbp), %rdi
callq 0xcae0
movl -0x88(%rbp), %eax
testl %eax, %eax
jne 0x74b3
jmp 0x7205
leaq -0xa0(%rbp), %rdi
movq %rdi, -0xf0(%rbp)
callq 0xcb40
leaq -0xb8(%rbp), %rdi
callq 0xcb40
leaq -0xd0(%rbp), %rdi
callq 0xcb40
movq -0xf0(%rbp), %rdi
movl -0x30(%rbp), %eax
movl %eax, %esi
callq 0xcb60
jmp 0x7243
movl -0x14(%rbp), %eax
movl %eax, -0xfc(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0xcbf0
movl -0xfc(%rbp), %edi
movq %rax, %rsi
movl -0x30(%rbp), %eax
movl %eax, %edx
callq 0x3480
movq %rax, -0xf8(%rbp)
jmp 0x7274
movq -0xf8(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movl -0x30(%rbp), %ecx
cmpq %rcx, %rax
je 0x72f2
movq -0x10(%rbp), %rdi
callq 0x3130
movq %rax, %rsi
leaq 0x243a4(%rip), %rdi     # 0x2b642
xorl %eax, %eax
callq 0x3360
jmp 0x72a7
movb $0x0, -0x1(%rbp)
movl $0x1, -0x88(%rbp)
jmp 0x748f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0xd0(%rbp), %rdi
callq 0xcc10
leaq -0xb8(%rbp), %rdi
callq 0xcc10
leaq -0xa0(%rbp), %rdi
callq 0xcc10
jmp 0x74be
movzwl -0x2c(%rbp), %eax
movl %eax, %esi
leaq -0xd0(%rbp), %rdi
callq 0xcb60
jmp 0x7306
movl -0x14(%rbp), %eax
movl %eax, -0x10c(%rbp)
leaq -0xd0(%rbp), %rdi
callq 0xcbf0
movl -0x10c(%rbp), %edi
movq %rax, %rsi
movzwl -0x2c(%rbp), %eax
movl %eax, %edx
callq 0x3480
movq %rax, -0x108(%rbp)
jmp 0x7338
movq -0x108(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movzwl -0x2c(%rbp), %ecx
cmpq %rcx, %rax
je 0x737f
movq -0x10(%rbp), %rdi
callq 0x3130
movq %rax, %rsi
leaq 0x242df(%rip), %rdi     # 0x2b642
xorl %eax, %eax
callq 0x3360
jmp 0x736c
movb $0x0, -0x1(%rbp)
movl $0x1, -0x88(%rbp)
jmp 0x748f
movl -0x2a(%rbp), %eax
movl %eax, %esi
leaq -0xb8(%rbp), %rdi
callq 0xcb60
jmp 0x7392
movl -0x14(%rbp), %eax
movl %eax, -0x11c(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0xcbf0
movl -0x11c(%rbp), %edi
movq %rax, %rsi
movl -0x2a(%rbp), %eax
movl %eax, %edx
callq 0x3480
movq %rax, -0x118(%rbp)
jmp 0x73c3
movq -0x118(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movl -0x2a(%rbp), %ecx
cmpq %rcx, %rax
je 0x7409
movq -0x10(%rbp), %rdi
callq 0x3130
movq %rax, %rsi
leaq 0x24255(%rip), %rdi     # 0x2b642
xorl %eax, %eax
callq 0x3360
jmp 0x73f6
movb $0x0, -0x1(%rbp)
movl $0x1, -0x88(%rbp)
jmp 0x748f
testb $0x1, 0x37f30(%rip)     # 0x3f340
je 0x7447
movq -0x10(%rbp), %rdi
callq 0x3130
movq %rax, -0x128(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x3130
movq -0x128(%rbp), %rsi
movq %rax, %rdx
leaq 0x24220(%rip), %rdi     # 0x2b65c
xorl %eax, %eax
callq 0x3060
jmp 0x7445
jmp 0x7447
movq -0x20(%rbp), %rcx
leaq -0xa0(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
leaq -0xb8(%rbp), %rdx
callq 0x4090
jmp 0x7467
cmpw $0x0, -0x26(%rbp)
je 0x7481
movl -0x14(%rbp), %edi
movzwl -0x26(%rbp), %eax
movl %eax, %esi
movl $0x1, %edx
callq 0x35a0
movb $0x1, -0x1(%rbp)
movl $0x1, -0x88(%rbp)
leaq -0xd0(%rbp), %rdi
callq 0xcc10
leaq -0xb8(%rbp), %rdi
callq 0xcc10
leaq -0xa0(%rbp), %rdi
callq 0xcc10
leaq -0x60(%rbp), %rdi
callq 0x31f0
jmp 0x74c9
leaq -0x60(%rbp), %rdi
callq 0x31f0
jmp 0x74d7
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x130, %rsp            # imm = 0x130
popq %rbp
retq
movq -0x80(%rbp), %rdi
callq 0x3540