// File: jvanns[P]verbatim/sub/lmdb/libraries/liblmdb/mdb.c
// Function: mdb_env_open2
static int ESECT
mdb_env_open2(MDB_env *env)
{
	unsigned int flags = env->me_flags;
	int i, newenv = 0, rc;
	MDB_meta meta;

#ifdef _WIN32
	/* See if we should use QueryLimited */
	rc = GetVersion();
	if ((rc & 0xff) > 5)
		env->me_pidquery = MDB_PROCESS_QUERY_LIMITED_INFORMATION;
	else
		env->me_pidquery = PROCESS_QUERY_INFORMATION;
#endif /* _WIN32 */

#ifdef BROKEN_FDATASYNC
	/* ext3/ext4 fdatasync is broken on some older Linux kernels.
	 * https://lkml.org/lkml/2012/9/3/83
	 * Kernels after 3.6-rc6 are known good.
	 * https://lkml.org/lkml/2012/9/10/556
	 * See if the DB is on ext3/ext4, then check for new enough kernel
	 * Kernels 2.6.32.60, 2.6.34.15, 3.2.30, and 3.5.4 are also known
	 * to be patched.
	 */
	{
		struct statfs st;
		fstatfs(env->me_fd, &st);
		while (st.f_type == 0xEF53) {
			struct utsname uts;
			int i;
			uname(&uts);
			if (uts.release[0] < '3') {
				if (!strncmp(uts.release, "2.6.32.", 7)) {
					i = atoi(uts.release+7);
					if (i >= 60)
						break;	/* 2.6.32.60 and newer is OK */
				} else if (!strncmp(uts.release, "2.6.34.", 7)) {
					i = atoi(uts.release+7);
					if (i >= 15)
						break;	/* 2.6.34.15 and newer is OK */
				}
			} else if (uts.release[0] == '3') {
				i = atoi(uts.release+2);
				if (i > 5)
					break;	/* 3.6 and newer is OK */
				if (i == 5) {
					i = atoi(uts.release+4);
					if (i >= 4)
						break;	/* 3.5.4 and newer is OK */
				} else if (i == 2) {
					i = atoi(uts.release+4);
					if (i >= 30)
						break;	/* 3.2.30 and newer is OK */
				}
			} else {	/* 4.x and newer is OK */
				break;
			}
			env->me_flags |= MDB_FSYNCONLY;
			break;
		}
	}
#endif

	if ((i = mdb_env_read_header(env, &meta)) != 0) {
		if (i != ENOENT)
			return i;
		DPUTS("new mdbenv");
		newenv = 1;
		env->me_psize = env->me_os_psize;
		if (env->me_psize > MAX_PAGESIZE)
			env->me_psize = MAX_PAGESIZE;
		memset(&meta, 0, sizeof(meta));
		mdb_env_init_meta0(env, &meta);
		meta.mm_mapsize = DEFAULT_MAPSIZE;
	} else {
		env->me_psize = meta.mm_psize;
	}

	/* Was a mapsize configured? */
	if (!env->me_mapsize) {
		env->me_mapsize = meta.mm_mapsize;
	}
	{
		/* Make sure mapsize >= committed data size.  Even when using
		 * mm_mapsize, which could be broken in old files (ITS#7789).
		 */
		size_t minsize = (meta.mm_last_pg + 1) * meta.mm_psize;
		if (env->me_mapsize < minsize)
			env->me_mapsize = minsize;
	}
	meta.mm_mapsize = env->me_mapsize;

	if (newenv && !(flags & MDB_FIXEDMAP)) {
		/* mdb_env_map() may grow the datafile.  Write the metapages
		 * first, so the file will be valid if initialization fails.
		 * Except with FIXEDMAP, since we do not yet know mm_address.
		 * We could fill in mm_address later, but then a different
		 * program might end up doing that - one with a memory layout
		 * and map address which does not suit the main program.
		 */
		rc = mdb_env_init_meta(env, &meta);
		if (rc)
			return rc;
		newenv = 0;
	}

	rc = mdb_env_map(env, (flags & MDB_FIXEDMAP) ? meta.mm_address : NULL);
	if (rc)
		return rc;

	if (newenv) {
		if (flags & MDB_FIXEDMAP)
			meta.mm_address = env->me_map;
		i = mdb_env_init_meta(env, &meta);
		if (i != MDB_SUCCESS) {
			return i;
		}
	}

	env->me_maxfree_1pg = (env->me_psize - PAGEHDRSZ) / sizeof(pgno_t) - 1;
	env->me_nodemax = (((env->me_psize - PAGEHDRSZ) / MDB_MINKEYS) & -2)
		- sizeof(indx_t);
#if !(MDB_MAXKEYSIZE)
	env->me_maxkey = env->me_nodemax - (NODESIZE + sizeof(MDB_db));
#endif
	env->me_maxpg = env->me_mapsize / env->me_psize;

#if MDB_DEBUG
	{
		MDB_meta *meta = mdb_env_pick_meta(env);
		MDB_db *db = &meta->mm_dbs[MAIN_DBI];

		DPRINTF(("opened database version %u, pagesize %u",
			meta->mm_version, env->me_psize));
		DPRINTF(("using meta page %d",    (int) (meta->mm_txnid & 1)));
		DPRINTF(("depth: %u",             db->md_depth));
		DPRINTF(("entries: %"Z"u",        db->md_entries));
		DPRINTF(("branch pages: %"Z"u",   db->md_branch_pages));
		DPRINTF(("leaf pages: %"Z"u",     db->md_leaf_pages));
		DPRINTF(("overflow pages: %"Z"u", db->md_overflow_pages));
		DPRINTF(("root: %"Z"u",           db->md_root));
	}
#endif

	return MDB_SUCCESS;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2d0, %rsp            # imm = 0x2D0
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movl 0xc(%rax), %eax
movl %eax, -0x14(%rbp)
movl $0x0, -0x1c(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %edi
leaq -0x120(%rbp), %rsi
callq 0x2330
cmpq $0xef53, -0x120(%rbp) # imm = 0xEF53
jne 0x1420e
leaq -0x2a6(%rbp), %rdi
callq 0x2150
movsbl -0x224(%rbp), %eax
cmpl $0x33, %eax
jge 0x14158
leaq -0x2a6(%rbp), %rdi
addq $0x82, %rdi
leaq 0x3985(%rip), %rsi      # 0x17a49
movl $0x7, %edx
callq 0x2070
cmpl $0x0, %eax
jne 0x14100
leaq -0x2a6(%rbp), %rdi
addq $0x82, %rdi
addq $0x7, %rdi
callq 0x2340
movl %eax, -0x2ac(%rbp)
cmpl $0x3c, -0x2ac(%rbp)
jl 0x140fe
jmp 0x1420e
jmp 0x14153
leaq -0x2a6(%rbp), %rdi
addq $0x82, %rdi
leaq 0x393c(%rip), %rsi      # 0x17a51
movl $0x7, %edx
callq 0x2070
cmpl $0x0, %eax
jne 0x14151
leaq -0x2a6(%rbp), %rdi
addq $0x82, %rdi
addq $0x7, %rdi
callq 0x2340
movl %eax, -0x2ac(%rbp)
cmpl $0xf, -0x2ac(%rbp)
jl 0x1414f
jmp 0x1420e
jmp 0x14151
jmp 0x14153
jmp 0x141fe
movsbl -0x224(%rbp), %eax
cmpl $0x33, %eax
jne 0x141fa
leaq -0x2a6(%rbp), %rdi
addq $0x82, %rdi
addq $0x2, %rdi
callq 0x2340
movl %eax, -0x2ac(%rbp)
cmpl $0x5, -0x2ac(%rbp)
jle 0x14190
jmp 0x1420e
cmpl $0x5, -0x2ac(%rbp)
jne 0x141c3
leaq -0x2a6(%rbp), %rdi
addq $0x82, %rdi
addq $0x4, %rdi
callq 0x2340
movl %eax, -0x2ac(%rbp)
cmpl $0x4, -0x2ac(%rbp)
jl 0x141c1
jmp 0x1420e
jmp 0x141f8
cmpl $0x2, -0x2ac(%rbp)
jne 0x141f6
leaq -0x2a6(%rbp), %rdi
addq $0x82, %rdi
addq $0x4, %rdi
callq 0x2340
movl %eax, -0x2ac(%rbp)
cmpl $0x1e, -0x2ac(%rbp)
jl 0x141f4
jmp 0x1420e
jmp 0x141f6
jmp 0x141f8
jmp 0x141fc
jmp 0x1420e
jmp 0x141fe
movq -0x10(%rbp), %rax
movl 0xc(%rax), %ecx
orl $0x8000000, %ecx        # imm = 0x8000000
movl %ecx, 0xc(%rax)
movq -0x10(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x15ae0
movl %eax, -0x18(%rbp)
cmpl $0x0, %eax
je 0x14294
cmpl $0x2, -0x18(%rbp)
je 0x14237
movl -0x18(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x14444
movl $0x1, -0x1c(%rbp)
movq -0x10(%rbp), %rax
movl 0x14(%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x10(%rax)
movq -0x10(%rbp), %rax
cmpl $0x8000, 0x10(%rax)     # imm = 0x8000
jbe 0x14264
movq -0x10(%rbp), %rax
movl $0x8000, 0x10(%rax)     # imm = 0x8000
leaq -0xa8(%rbp), %rdi
xorl %esi, %esi
movl $0x88, %edx
callq 0x2180
movq -0x10(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x15c90
movq $0x100000, -0x98(%rbp) # imm = 0x100000
jmp 0x142a1
movl -0x90(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x10(%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x70(%rax)
jne 0x142bb
movq -0x98(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x70(%rax)
movq -0x30(%rbp), %rax
addq $0x1, %rax
movl -0x90(%rbp), %ecx
imulq %rcx, %rax
movq %rax, -0x2b8(%rbp)
movq -0x10(%rbp), %rax
movq 0x70(%rax), %rax
cmpq -0x2b8(%rbp), %rax
jae 0x142f4
movq -0x2b8(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x70(%rax)
movq -0x10(%rbp), %rax
movq 0x70(%rax), %rax
movq %rax, -0x98(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x1433f
movl -0x14(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x1433f
movq -0x10(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x15d20
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x20(%rbp)
je 0x14338
movl -0x20(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x14444
movl $0x0, -0x1c(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x2c0(%rbp)
movl -0x14(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x14365
movq -0xa0(%rbp), %rax
movq %rax, -0x2c8(%rbp)
jmp 0x14370
xorl %eax, %eax
movq %rax, -0x2c8(%rbp)
jmp 0x14370
movq -0x2c0(%rbp), %rdi
movq -0x2c8(%rbp), %rsi
callq 0x13620
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x20(%rbp)
je 0x14397
movl -0x20(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x14444
cmpl $0x0, -0x1c(%rbp)
je 0x143da
movl -0x14(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x143b7
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movq %rax, -0xa0(%rbp)
movq -0x10(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x15d20
movl %eax, -0x18(%rbp)
cmpl $0x0, -0x18(%rbp)
je 0x143d8
movl -0x18(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x14444
jmp 0x143da
movq -0x10(%rbp), %rax
movl 0x10(%rax), %eax
subl $0x10, %eax
movl %eax, %eax
shrq $0x3, %rax
subq $0x1, %rax
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0xd8(%rax)
movq -0x10(%rbp), %rax
movl 0x10(%rax), %eax
subl $0x10, %eax
shrl %eax
andl $-0x2, %eax
movl %eax, %eax
subq $0x2, %rax
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0xdc(%rax)
movq -0x10(%rbp), %rax
movq 0x70(%rax), %rax
movq -0x10(%rbp), %rcx
movl 0x10(%rcx), %ecx
xorl %edx, %edx
divq %rcx
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x80(%rax)
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x2d0, %rsp            # imm = 0x2D0
popq %rbp
retq