// File: /workspace/github_c_makefile_star2_O0/barabo[P]advanced-shell-history/src/sqlite3.c
// Function: walIndexRecover
static int walIndexRecover(Wal *pWal){
  int rc;                         /* Return Code */
  i64 nSize;                      /* Size of log file */
  u32 aFrameCksum[2] = {0, 0};
  int iLock;                      /* Lock offset to lock for checkpoint */
  int nLock;                      /* Number of locks to hold */

  /* Obtain an exclusive lock on all byte in the locking range not already
  ** locked by the caller. The caller is guaranteed to have locked the
  ** WAL_WRITE_LOCK byte, and may have also locked the WAL_CKPT_LOCK byte.
  ** If successful, the same bytes that are locked here are unlocked before
  ** this function returns.
  */
  assert( pWal->ckptLock==1 || pWal->ckptLock==0 );
  assert( WAL_ALL_BUT_WRITE==WAL_WRITE_LOCK+1 );
  assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE );
  assert( pWal->writeLock );
  iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock;
  nLock = SQLITE_SHM_NLOCK - iLock;
  rc = walLockExclusive(pWal, iLock, nLock);
  if( rc ){
    return rc;
  }
  WALTRACE(("WAL%p: recovery begin...\n", pWal));

  memset(&pWal->hdr, 0, sizeof(WalIndexHdr));

  rc = sqlite3OsFileSize(pWal->pWalFd, &nSize);
  if( rc!=SQLITE_OK ){
    goto recovery_error;
  }

  if( nSize>WAL_HDRSIZE ){
    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 */
    int iFrame;                   /* Index of last frame read */
    i64 iOffset;                  /* Next offset to read from log file */
    int szPage;                   /* Page size according to the log */
    u32 magic;                    /* Magic value read from WAL header */
    u32 version;                  /* Magic value read from WAL header */
    int isValid;                  /* True if this frame is valid */

    /* Read in the WAL header. */
    rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0);
    if( rc!=SQLITE_OK ){
      goto recovery_error;
    }

    /* If the database page size is not a power of two, or is greater than
    ** SQLITE_MAX_PAGE_SIZE, conclude that the WAL file contains no valid 
    ** data. Similarly, if the 'magic' value is invalid, ignore the whole
    ** WAL file.
    */
    magic = sqlite3Get4byte(&aBuf[0]);
    szPage = sqlite3Get4byte(&aBuf[8]);
    if( (magic&0xFFFFFFFE)!=WAL_MAGIC 
     || szPage&(szPage-1) 
     || szPage>SQLITE_MAX_PAGE_SIZE 
     || szPage<512 
    ){
      goto finished;
    }
    pWal->hdr.bigEndCksum = (u8)(magic&0x00000001);
    pWal->szPage = szPage;
    pWal->nCkpt = sqlite3Get4byte(&aBuf[12]);
    memcpy(&pWal->hdr.aSalt, &aBuf[16], 8);

    /* Verify that the WAL header checksum is correct */
    walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, 
        aBuf, WAL_HDRSIZE-2*4, 0, pWal->hdr.aFrameCksum
    );
    if( pWal->hdr.aFrameCksum[0]!=sqlite3Get4byte(&aBuf[24])
     || pWal->hdr.aFrameCksum[1]!=sqlite3Get4byte(&aBuf[28])
    ){
      goto finished;
    }

    /* Verify that the version number on the WAL format is one that
    ** are able to understand */
    version = sqlite3Get4byte(&aBuf[4]);
    if( version!=WAL_MAX_VERSION ){
      rc = SQLITE_CANTOPEN_BKPT;
      goto finished;
    }

    /* Malloc a buffer to read frames into. */
    szFrame = szPage + WAL_FRAME_HDRSIZE;
    aFrame = (u8 *)sqlite3_malloc(szFrame);
    if( !aFrame ){
      rc = SQLITE_NOMEM;
      goto recovery_error;
    }
    aData = &aFrame[WAL_FRAME_HDRSIZE];

    /* Read all frames from the log file. */
    iFrame = 0;
    for(iOffset=WAL_HDRSIZE; (iOffset+szFrame)<=nSize; iOffset+=szFrame){
      u32 pgno;                   /* Database page number for frame */
      u32 nTruncate;              /* dbsize field from frame header */

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

      /* If nTruncate is non-zero, this is a commit record. */
      if( nTruncate ){
        pWal->hdr.mxFrame = iFrame;
        pWal->hdr.nPage = nTruncate;
        pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16));
        testcase( szPage<=32768 );
        testcase( szPage>=65536 );
        aFrameCksum[0] = pWal->hdr.aFrameCksum[0];
        aFrameCksum[1] = pWal->hdr.aFrameCksum[1];
      }
    }

    sqlite3_free(aFrame);
  }

finished:
  if( rc==SQLITE_OK ){
    volatile WalCkptInfo *pInfo;
    int i;
    pWal->hdr.aFrameCksum[0] = aFrameCksum[0];
    pWal->hdr.aFrameCksum[1] = aFrameCksum[1];
    walIndexWriteHdr(pWal);

    /* Reset the checkpoint-header. This is safe because this thread is 
    ** currently holding locks that exclude all other readers, writers and
    ** checkpointers.
    */
    pInfo = walCkptInfo(pWal);
    pInfo->nBackfill = 0;
    pInfo->aReadMark[0] = 0;
    for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
    if( pWal->hdr.mxFrame ) pInfo->aReadMark[1] = pWal->hdr.mxFrame;

    /* If more than one frame was recovered from the log file, report an
    ** event via sqlite3_log(). This is to help with identifying performance
    ** problems caused by applications routinely shutting down without
    ** checkpointing the log file.
    */
    if( pWal->hdr.nPage ){
      sqlite3_log(SQLITE_NOTICE_RECOVER_WAL,
          "recovered %d frames from WAL file %s",
          pWal->hdr.mxFrame, pWal->zWalName
      );
    }
  }

recovery_error:
  WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok"));
  walUnlockExclusive(pWal, iLock, nLock);
  return rc;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x10(%rbp)
leaq -0x28(%rbp), %rdi
xorl %esi, %esi
movl $0x8, %edx
callq 0x8200
movq -0x10(%rbp), %rax
movzbl 0x41(%rax), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
movl $0x8, %eax
subl -0x2c(%rbp), %eax
movl %eax, -0x30(%rbp)
movq -0x10(%rbp), %rdi
movl -0x2c(%rbp), %esi
movl -0x30(%rbp), %edx
callq 0x23020
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
je 0x239cb
movl -0x14(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x23da7
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
xorl %esi, %esi
movl $0x30, %edx
callq 0x8200
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
leaq -0x20(%rbp), %rsi
callq 0x23e00
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
je 0x239fe
jmp 0x23d92
cmpq $0x20, -0x20(%rbp)
jle 0x23cb9
movq $0x0, -0x58(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
leaq -0x50(%rbp), %rsi
movl $0x20, %edx
xorl %eax, %eax
movl %eax, %ecx
callq 0x23e30
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
je 0x23a39
jmp 0x23d92
leaq -0x50(%rbp), %rdi
callq 0x20a50
movl %eax, -0x80(%rbp)
leaq -0x50(%rbp), %rdi
addq $0x8, %rdi
callq 0x20a50
movl %eax, -0x7c(%rbp)
movl -0x80(%rbp), %eax
andl $-0x2, %eax
cmpl $0x377f0682, %eax       # imm = 0x377F0682
jne 0x23a84
movl -0x7c(%rbp), %eax
movl -0x7c(%rbp), %ecx
subl $0x1, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
jne 0x23a84
cmpl $0x10000, -0x7c(%rbp)   # imm = 0x10000
jg 0x23a84
cmpl $0x200, -0x7c(%rbp)     # imm = 0x200
jge 0x23a89
jmp 0x23cbb
movl -0x80(%rbp), %eax
andl $0x1, %eax
movb %al, %cl
movq -0x10(%rbp), %rax
movb %cl, 0x55(%rax)
movl -0x7c(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x38(%rax)
leaq -0x50(%rbp), %rdi
addq $0xc, %rdi
callq 0x20a50
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x80(%rax)
movq -0x10(%rbp), %rax
movq -0x40(%rbp), %rcx
movq %rcx, 0x68(%rax)
movq -0x10(%rbp), %rax
movzbl 0x55(%rax), %eax
cmpl $0x0, %eax
sete %al
andb $0x1, %al
movzbl %al, %edi
leaq -0x50(%rbp), %rsi
movq -0x10(%rbp), %r8
addq $0x48, %r8
addq $0x18, %r8
movl $0x18, %edx
xorl %eax, %eax
movl %eax, %ecx
callq 0x22b70
movq -0x10(%rbp), %rax
movl 0x60(%rax), %eax
movl %eax, -0xa0(%rbp)
leaq -0x50(%rbp), %rdi
addq $0x18, %rdi
callq 0x20a50
movl %eax, %ecx
movl -0xa0(%rbp), %eax
cmpl %ecx, %eax
jne 0x23b44
movq -0x10(%rbp), %rax
movl 0x64(%rax), %eax
movl %eax, -0xa4(%rbp)
leaq -0x50(%rbp), %rdi
addq $0x1c, %rdi
callq 0x20a50
movl %eax, %ecx
movl -0xa4(%rbp), %eax
cmpl %ecx, %eax
je 0x23b49
jmp 0x23cbb
leaq -0x50(%rbp), %rdi
addq $0x4, %rdi
callq 0x20a50
movl %eax, -0x84(%rbp)
cmpl $0x2de218, -0x84(%rbp)  # imm = 0x2DE218
je 0x23b7a
movl $0xb64b, %edi           # imm = 0xB64B
callq 0x1d9a0
movl %eax, -0x14(%rbp)
jmp 0x23cbb
movl -0x7c(%rbp), %eax
addl $0x18, %eax
movl %eax, -0x5c(%rbp)
movl -0x5c(%rbp), %edi
callq 0xa380
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x58(%rbp)
jne 0x23ba2
movl $0x7, -0x14(%rbp)
jmp 0x23d92
movq -0x58(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x68(%rbp)
movl $0x0, -0x6c(%rbp)
movq $0x20, -0x78(%rbp)
movq -0x78(%rbp), %rax
movslq -0x5c(%rbp), %rcx
addq %rcx, %rax
cmpq -0x20(%rbp), %rax
jg 0x23cb0
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x58(%rbp), %rsi
movl -0x5c(%rbp), %edx
movq -0x78(%rbp), %rcx
callq 0x23e30
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
je 0x23c01
jmp 0x23cb0
movq -0x10(%rbp), %rdi
movq -0x68(%rbp), %rcx
movq -0x58(%rbp), %r8
leaq -0x8c(%rbp), %rsi
leaq -0x90(%rbp), %rdx
callq 0x23e70
movl %eax, -0x88(%rbp)
cmpl $0x0, -0x88(%rbp)
jne 0x23c31
jmp 0x23cb0
movq -0x10(%rbp), %rdi
movl -0x6c(%rbp), %esi
movl -0x8c(%rbp), %edx
callq 0x22e30
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
je 0x23c4e
jmp 0x23cb0
cmpl $0x0, -0x90(%rbp)
je 0x23c9d
movl -0x6c(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x58(%rax)
movl -0x90(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x5c(%rax)
movl -0x7c(%rbp), %eax
andl $0xff00, %eax           # imm = 0xFF00
movl -0x7c(%rbp), %ecx
sarl $0x10, %ecx
orl %ecx, %eax
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x56(%rax)
movq -0x10(%rbp), %rax
movl 0x60(%rax), %eax
movl %eax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movl 0x64(%rax), %eax
movl %eax, -0x24(%rbp)
jmp 0x23c9f
movslq -0x5c(%rbp), %rax
addq -0x78(%rbp), %rax
movq %rax, -0x78(%rbp)
jmp 0x23bbd
movq -0x58(%rbp), %rdi
callq 0xa420
jmp 0x23cbb
cmpl $0x0, -0x14(%rbp)
jne 0x23d90
movl -0x28(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x60(%rax)
movl -0x24(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x64(%rax)
movq -0x10(%rbp), %rdi
callq 0x22f60
movq -0x10(%rbp), %rdi
callq 0x23000
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rax
movl $0x0, (%rax)
movq -0x98(%rbp), %rax
movl $0x0, 0x4(%rax)
movl $0x1, -0x9c(%rbp)
cmpl $0x5, -0x9c(%rbp)
jge 0x23d47
movq -0x98(%rbp), %rax
movslq -0x9c(%rbp), %rcx
movl $0xffffffff, 0x4(%rax,%rcx,4) # imm = 0xFFFFFFFF
movl -0x9c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x9c(%rbp)
jmp 0x23d17
movq -0x10(%rbp), %rax
cmpl $0x0, 0x58(%rax)
je 0x23d62
movq -0x10(%rbp), %rax
movl 0x58(%rax), %ecx
movq -0x98(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x5c(%rax)
je 0x23d8e
movq -0x10(%rbp), %rax
movl 0x58(%rax), %edx
movq -0x10(%rbp), %rax
movq 0x78(%rax), %rcx
movl $0x11b, %edi            # imm = 0x11B
leaq 0x8a545(%rip), %rsi     # 0xae2cc
movb $0x0, %al
callq 0xc5f0
jmp 0x23d90
jmp 0x23d92
movq -0x10(%rbp), %rdi
movl -0x2c(%rbp), %esi
movl -0x30(%rbp), %edx
callq 0x23070
movl -0x14(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xb0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)