// File: jvanns[P]verbatim/sub/lmdb/libraries/liblmdb/mdb.c
// Function: mdb_env_map
static int ESECT
mdb_env_map(MDB_env *env, void *addr)
{
	MDB_page *p;
	unsigned int flags = env->me_flags;
#ifdef _WIN32
	int rc;
	HANDLE mh;
	LONG sizelo, sizehi;
	size_t msize;

	if (flags & MDB_RDONLY) {
		/* Don't set explicit map size, use whatever exists */
		msize = 0;
		sizelo = 0;
		sizehi = 0;
	} else {
		msize = env->me_mapsize;
		sizelo = msize & 0xffffffff;
		sizehi = msize >> 16 >> 16; /* only needed on Win64 */

		/* Windows won't create mappings for zero length files.
		 * and won't map more than the file size.
		 * Just set the maxsize right now.
		 */
		if (SetFilePointer(env->me_fd, sizelo, &sizehi, 0) != (DWORD)sizelo
			|| !SetEndOfFile(env->me_fd)
			|| SetFilePointer(env->me_fd, 0, NULL, 0) != 0)
			return ErrCode();
	}

	mh = CreateFileMapping(env->me_fd, NULL, flags & MDB_WRITEMAP ?
		PAGE_READWRITE : PAGE_READONLY,
		sizehi, sizelo, NULL);
	if (!mh)
		return ErrCode();
	env->me_map = MapViewOfFileEx(mh, flags & MDB_WRITEMAP ?
		FILE_MAP_WRITE : FILE_MAP_READ,
		0, 0, msize, addr);
	rc = env->me_map ? 0 : ErrCode();
	CloseHandle(mh);
	if (rc)
		return rc;
#else
	int prot = PROT_READ;
	if (flags & MDB_WRITEMAP) {
		prot |= PROT_WRITE;
		if (ftruncate(env->me_fd, env->me_mapsize) < 0)
			return ErrCode();
	}
	env->me_map = mmap(addr, env->me_mapsize, prot, MAP_SHARED,
		env->me_fd, 0);
	if (env->me_map == MAP_FAILED) {
		env->me_map = NULL;
		return ErrCode();
	}

	if (flags & MDB_NORDAHEAD) {
		/* Turn off readahead. It's harmful when the DB is larger than RAM. */
#ifdef MADV_RANDOM
		madvise(env->me_map, env->me_mapsize, MADV_RANDOM);
#else
#ifdef POSIX_MADV_RANDOM
		posix_madvise(env->me_map, env->me_mapsize, POSIX_MADV_RANDOM);
#endif /* POSIX_MADV_RANDOM */
#endif /* MADV_RANDOM */
	}
#endif /* _WIN32 */

	/* Can happen because the address argument to mmap() is just a
	 * hint.  mmap() can pick another, e.g. if the range is in use.
	 * The MAP_FIXED flag would prevent that, but then mmap could
	 * instead unmap existing pages to make room for the new map.
	 */
	if (addr && env->me_map != addr)
		return EBUSY;	/* TODO: Make a new MDB_* error code? */

	p = (MDB_page *)env->me_map;
	env->me_metas[0] = METADATA(p);
	env->me_metas[1] = (MDB_meta *)((char *)env->me_metas[0] + env->me_psize);

	return MDB_SUCCESS;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rax
movl 0xc(%rax), %eax
movl %eax, -0x24(%rbp)
movl $0x1, -0x28(%rbp)
movl -0x24(%rbp), %eax
andl $0x80000, %eax          # imm = 0x80000
cmpl $0x0, %eax
je 0x13680
movl -0x28(%rbp), %eax
orl $0x2, %eax
movl %eax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %edi
movq -0x10(%rbp), %rax
movq 0x70(%rax), %rsi
callq 0x2140
cmpl $0x0, %eax
jge 0x1367e
callq 0x2050
movl (%rax), %eax
movl %eax, -0x4(%rbp)
jmp 0x1375e
jmp 0x13680
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x70(%rax), %rsi
movl -0x28(%rbp), %edx
movq -0x10(%rbp), %rax
movl (%rax), %r8d
movl $0x1, %ecx
xorl %eax, %eax
movl %eax, %r9d
callq 0x2110
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x10(%rbp), %rax
movq $-0x1, %rcx
cmpq %rcx, 0x38(%rax)
jne 0x136dc
movq -0x10(%rbp), %rax
movq $0x0, 0x38(%rax)
callq 0x2050
movl (%rax), %eax
movl %eax, -0x4(%rbp)
jmp 0x1375e
movl -0x24(%rbp), %eax
andl $0x800000, %eax         # imm = 0x800000
cmpl $0x0, %eax
je 0x13703
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x70(%rax), %rsi
movl $0x1, %edx
callq 0x22b0
cmpq $0x0, -0x18(%rbp)
je 0x13721
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
cmpq -0x18(%rbp), %rax
je 0x13721
movl $0x10, -0x4(%rbp)
jmp 0x1375e
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rcx
addq $0x10, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x48(%rax)
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rcx
movq -0x10(%rbp), %rax
movl 0x10(%rax), %eax
addq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x50(%rax)
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x30, %rsp
popq %rbp
retq
nopw (%rax,%rax)