// File: /workspace/github_c_makefile_star2_O0/genometools[P]genometools/src/external/sqlite-3.33.0/sqlite3.c
// Function: walBeginShmUnreliable
static int walBeginShmUnreliable(Wal *pWal, int *pChanged){
  i64 szWal;                      /* Size of wal file on disk in bytes */
  i64 iOffset;                    /* Current offset when reading wal file */
  u8 aBuf[WAL_HDRSIZE];           /* Buffer to load WAL header into */
  u8 *aFrame = 0;                 /* Malloc'd buffer to load entire frame */
  int szFrame;                    /* Number of bytes in buffer aFrame[] */
  u8 *aData;                      /* Pointer to data part of aFrame buffer */
  volatile void *pDummy;          /* Dummy argument for xShmMap */
  int rc;                         /* Return code */
  u32 aSaveCksum[2];              /* Saved copy of pWal->hdr.aFrameCksum */

  assert( pWal->bShmUnreliable );
  assert( pWal->readOnly & WAL_SHM_RDONLY );
  assert( pWal->nWiData>0 && pWal->apWiData[0] );

  /* Take WAL_READ_LOCK(0). This has the effect of preventing any
  ** writers from running a checkpoint, but does not stop them
  ** from running recovery.  */
  rc = walLockShared(pWal, WAL_READ_LOCK(0));
  if( rc!=SQLITE_OK ){
    if( rc==SQLITE_BUSY ) rc = WAL_RETRY;
    goto begin_unreliable_shm_out;
  }
  pWal->readLock = 0;

  /* Check to see if a separate writer has attached to the shared-memory area,
  ** thus making the shared-memory "reliable" again.  Do this by invoking
  ** the xShmMap() routine of the VFS and looking to see if the return
  ** is SQLITE_READONLY instead of SQLITE_READONLY_CANTINIT.
  **
  ** If the shared-memory is now "reliable" return WAL_RETRY, which will
  ** cause the heap-memory WAL-index to be discarded and the actual
  ** shared memory to be used in its place.
  **
  ** This step is important because, even though this connection is holding
  ** the WAL_READ_LOCK(0) which prevents a checkpoint, a writer might
  ** have already checkpointed the WAL file and, while the current
  ** is active, wrap the WAL and start overwriting frames that this
  ** process wants to use.
  **
  ** Once sqlite3OsShmMap() has been called for an sqlite3_file and has
  ** returned any SQLITE_READONLY value, it must return only SQLITE_READONLY
  ** or SQLITE_READONLY_CANTINIT or some error for all subsequent invocations,
  ** even if some external agent does a "chmod" to make the shared-memory
  ** writable by us, until sqlite3OsShmUnmap() has been called.
  ** This is a requirement on the VFS implementation.
   */
  rc = sqlite3OsShmMap(pWal->pDbFd, 0, WALINDEX_PGSZ, 0, &pDummy);
  assert( rc!=SQLITE_OK ); /* SQLITE_OK not possible for read-only connection */
  if( rc!=SQLITE_READONLY_CANTINIT ){
    rc = (rc==SQLITE_READONLY ? WAL_RETRY : rc);
    goto begin_unreliable_shm_out;
  }

  /* We reach this point only if the real shared-memory is still unreliable.
  ** Assume the in-memory WAL-index substitute is correct and load it
  ** into pWal->hdr.
  */
  memcpy(&pWal->hdr, (void*)walIndexHdr(pWal), sizeof(WalIndexHdr));

  /* Make sure some writer hasn't come in and changed the WAL file out
  ** from under us, then disconnected, while we were not looking.
  */
  rc = sqlite3OsFileSize(pWal->pWalFd, &szWal);
  if( rc!=SQLITE_OK ){
    goto begin_unreliable_shm_out;
  }
  if( szWal<WAL_HDRSIZE ){
    /* If the wal file is too small to contain a wal-header and the
    ** wal-index header has mxFrame==0, then it must be safe to proceed
    ** reading the database file only. However, the page cache cannot
    ** be trusted, as a read/write connection may have connected, written
    ** the db, run a checkpoint, truncated the wal file and disconnected
    ** since this client's last read transaction.  */
    *pChanged = 1;
    rc = (pWal->hdr.mxFrame==0 ? SQLITE_OK : WAL_RETRY);
    goto begin_unreliable_shm_out;
  }

  /* Check the salt keys at the start of the wal file still match. */
  rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0);
  if( rc!=SQLITE_OK ){
    goto begin_unreliable_shm_out;
  }
  if( memcmp(&pWal->hdr.aSalt, &aBuf[16], 8) ){
    /* Some writer has wrapped the WAL file while we were not looking.
    ** Return WAL_RETRY which will cause the in-memory WAL-index to be
    ** rebuilt. */
    rc = WAL_RETRY;
    goto begin_unreliable_shm_out;
  }

  /* Allocate a buffer to read frames into */
  szFrame = pWal->hdr.szPage + WAL_FRAME_HDRSIZE;
  aFrame = (u8 *)sqlite3_malloc64(szFrame);
  if( aFrame==0 ){
    rc = SQLITE_NOMEM_BKPT;
    goto begin_unreliable_shm_out;
  }
  aData = &aFrame[WAL_FRAME_HDRSIZE];

  /* Check to see if a complete transaction has been appended to the
  ** wal file since the heap-memory wal-index was created. If so, the
  ** heap-memory wal-index is discarded and WAL_RETRY returned to
  ** the caller.  */
  aSaveCksum[0] = pWal->hdr.aFrameCksum[0];
  aSaveCksum[1] = pWal->hdr.aFrameCksum[1];
  for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->hdr.szPage);
      iOffset+szFrame<=szWal;
      iOffset+=szFrame
  ){
    u32 pgno;                   /* Database page number for frame */
    u32 nTruncate;              /* dbsize field from frame header */

    /* Read and decode the next log frame. */
    rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset);
    if( rc!=SQLITE_OK ) break;
    if( !walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame) ) break;

    /* If nTruncate is non-zero, then a complete transaction has been
    ** appended to this wal file. Set rc to WAL_RETRY and break out of
    ** the loop.  */
    if( nTruncate ){
      rc = WAL_RETRY;
      break;
    }
  }
  pWal->hdr.aFrameCksum[0] = aSaveCksum[0];
  pWal->hdr.aFrameCksum[1] = aSaveCksum[1];

 begin_unreliable_shm_out:
  sqlite3_free(aFrame);
  if( rc!=SQLITE_OK ){
    int i;
    for(i=0; i<pWal->nWiData; i++){
      sqlite3_free((void*)pWal->apWiData[i]);
      pWal->apWiData[i] = 0;
    }
    pWal->bShmUnreliable = 0;
    sqlite3WalEndReadTransaction(pWal);
    *pChanged = 1;
  }
  return rc;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq $0x0, -0x48(%rbp)
movq -0x8(%rbp), %rdi
movl $0x3, %esi
callq 0x3ded80
movl %eax, -0x64(%rbp)
cmpl $0x0, -0x64(%rbp)
je 0x3dee14
cmpl $0x5, -0x64(%rbp)
jne 0x3dee0f
movl $0xffffffff, -0x64(%rbp) # imm = 0xFFFFFFFF
jmp 0x3df037
movq -0x8(%rbp), %rax
movw $0x0, 0x3c(%rax)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
xorl %ecx, %ecx
movl $0x8000, %edx           # imm = 0x8000
leaq -0x60(%rbp), %r8
movl %ecx, %esi
callq 0x3dfb90
movl %eax, -0x64(%rbp)
cmpl $0x508, -0x64(%rbp)     # imm = 0x508
je 0x3dee65
cmpl $0x8, -0x64(%rbp)
jne 0x3dee54
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %eax, -0x7c(%rbp)
jmp 0x3dee5a
movl -0x64(%rbp), %eax
movl %eax, -0x7c(%rbp)
movl -0x7c(%rbp), %eax
movl %eax, -0x64(%rbp)
jmp 0x3df037
movq -0x8(%rbp), %rax
addq $0x48, %rax
movq %rax, -0x88(%rbp)
movq -0x8(%rbp), %rdi
callq 0x3ddcf0
movq -0x88(%rbp), %rdi
movq %rax, %rsi
movl $0x30, %edx
callq 0x19610
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rdi
leaq -0x18(%rbp), %rsi
callq 0x3dfbd0
movl %eax, -0x64(%rbp)
cmpl $0x0, -0x64(%rbp)
je 0x3deeb0
jmp 0x3df037
cmpq $0x20, -0x18(%rbp)
jge 0x3deedd
movq -0x10(%rbp), %rax
movl $0x1, (%rax)
movq -0x8(%rbp), %rax
movl 0x58(%rax), %edx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
xorl %ecx, %ecx
cmpl $0x0, %edx
cmovel %ecx, %eax
movl %eax, -0x64(%rbp)
jmp 0x3df037
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rdi
leaq -0x40(%rbp), %rsi
movl $0x20, %edx
xorl %eax, %eax
movl %eax, %ecx
callq 0x3dfc00
movl %eax, -0x64(%rbp)
cmpl $0x0, -0x64(%rbp)
je 0x3def05
jmp 0x3df037
movq -0x8(%rbp), %rax
addq $0x48, %rax
addq $0x20, %rax
leaq -0x40(%rbp), %rcx
addq $0x10, %rcx
movq (%rcx), %rcx
movq (%rax), %rax
subq %rcx, %rax
setne %al
movzbl %al, %eax
cmpl $0x0, %eax
je 0x3def39
movl $0xffffffff, -0x64(%rbp) # imm = 0xFFFFFFFF
jmp 0x3df037
movq -0x8(%rbp), %rax
movzwl 0x56(%rax), %eax
addl $0x18, %eax
movl %eax, -0x4c(%rbp)
movslq -0x4c(%rbp), %rdi
callq 0x3c07c0
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x3def67
movl $0x7, -0x64(%rbp)
jmp 0x3df037
movq -0x48(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x58(%rbp)
movq -0x8(%rbp), %rax
movl 0x60(%rax), %eax
movl %eax, -0x6c(%rbp)
movq -0x8(%rbp), %rax
movl 0x64(%rax), %eax
movl %eax, -0x68(%rbp)
movq -0x8(%rbp), %rax
movl 0x58(%rax), %eax
addl $0x1, %eax
subl $0x1, %eax
movl %eax, %eax
movq -0x8(%rbp), %rcx
movzwl 0x56(%rcx), %ecx
addl $0x18, %ecx
movslq %ecx, %rcx
imulq %rcx, %rax
addq $0x20, %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movslq -0x4c(%rbp), %rcx
addq %rcx, %rax
cmpq -0x18(%rbp), %rax
jg 0x3df023
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x48(%rbp), %rsi
movl -0x4c(%rbp), %edx
movq -0x20(%rbp), %rcx
callq 0x3dfc00
movl %eax, -0x64(%rbp)
cmpl $0x0, -0x64(%rbp)
je 0x3defe4
jmp 0x3df023
movq -0x8(%rbp), %rdi
movq -0x58(%rbp), %rcx
movq -0x48(%rbp), %r8
leaq -0x70(%rbp), %rsi
leaq -0x74(%rbp), %rdx
callq 0x3dfc70
cmpl $0x0, %eax
jne 0x3df004
jmp 0x3df023
cmpl $0x0, -0x74(%rbp)
je 0x3df013
movl $0xffffffff, -0x64(%rbp) # imm = 0xFFFFFFFF
jmp 0x3df023
jmp 0x3df015
movslq -0x4c(%rbp), %rax
addq -0x20(%rbp), %rax
movq %rax, -0x20(%rbp)
jmp 0x3defb0
movl -0x6c(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x60(%rax)
movl -0x68(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x64(%rax)
movq -0x48(%rbp), %rdi
callq 0x3c0800
cmpl $0x0, -0x64(%rbp)
je 0x3df0a8
movl $0x0, -0x78(%rbp)
movl -0x78(%rbp), %eax
movq -0x8(%rbp), %rcx
cmpl 0x28(%rcx), %eax
jge 0x3df08d
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x78(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x3c0800
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movslq -0x78(%rbp), %rcx
movq $0x0, (%rax,%rcx,8)
movl -0x78(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x78(%rbp)
jmp 0x3df04d
movq -0x8(%rbp), %rax
movb $0x0, 0x46(%rax)
movq -0x8(%rbp), %rdi
callq 0x3dfde0
movq -0x10(%rbp), %rax
movl $0x1, (%rax)
movl -0x64(%rbp), %eax
addq $0x90, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)