// File: /workspace/github_c_makefile_star2_O1/genometools[P]genometools/src/external/sqlite-3.33.0/sqlite3.c
// Function: pager_playback
static int pager_playback(Pager *pPager, int isHot){
  sqlite3_vfs *pVfs = pPager->pVfs;
  i64 szJ;                 /* Size of the journal file in bytes */
  u32 nRec;                /* Number of Records in the journal */
  u32 u;                   /* Unsigned loop counter */
  Pgno mxPg = 0;           /* Size of the original file in pages */
  int rc;                  /* Result code of a subroutine */
  int res = 1;             /* Value returned by sqlite3OsAccess() */
  char *zSuper = 0;        /* Name of super-journal file if any */
  int needPagerReset;      /* True to reset page prior to first page rollback */
  int nPlayback = 0;       /* Total number of pages restored from journal */
  u32 savedPageSize = pPager->pageSize;

  /* Figure out how many records are in the journal.  Abort early if
  ** the journal is empty.
  */
  assert( isOpen(pPager->jfd) );
  rc = sqlite3OsFileSize(pPager->jfd, &szJ);
  if( rc!=SQLITE_OK ){
    goto end_playback;
  }

  /* Read the super-journal name from the journal, if it is present.
  ** If a super-journal file name is specified, but the file is not
  ** present on disk, then the journal is not hot and does not need to be
  ** played back.
  **
  ** TODO: Technically the following is an error because it assumes that
  ** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that
  ** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c,
  ** mxPathname is 512, which is the same as the minimum allowable value
  ** for pageSize.
  */
  zSuper = pPager->pTmpSpace;
  rc = readSuperJournal(pPager->jfd, zSuper, pPager->pVfs->mxPathname+1);
  if( rc==SQLITE_OK && zSuper[0] ){
    rc = sqlite3OsAccess(pVfs, zSuper, SQLITE_ACCESS_EXISTS, &res);
  }
  zSuper = 0;
  if( rc!=SQLITE_OK || !res ){
    goto end_playback;
  }
  pPager->journalOff = 0;
  needPagerReset = isHot;

  /* This loop terminates either when a readJournalHdr() or
  ** pager_playback_one_page() call returns SQLITE_DONE or an IO error
  ** occurs.
  */
  while( 1 ){
    /* Read the next journal header from the journal file.  If there are
    ** not enough bytes left in the journal file for a complete header, or
    ** it is corrupted, then a process must have failed while writing it.
    ** This indicates nothing more needs to be rolled back.
    */
    rc = readJournalHdr(pPager, isHot, szJ, &nRec, &mxPg);
    if( rc!=SQLITE_OK ){
      if( rc==SQLITE_DONE ){
        rc = SQLITE_OK;
      }
      goto end_playback;
    }

    /* If nRec is 0xffffffff, then this journal was created by a process
    ** working in no-sync mode. This means that the rest of the journal
    ** file consists of pages, there are no more journal headers. Compute
    ** the value of nRec based on this assumption.
    */
    if( nRec==0xffffffff ){
      assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) );
      nRec = (int)((szJ - JOURNAL_HDR_SZ(pPager))/JOURNAL_PG_SZ(pPager));
    }

    /* If nRec is 0 and this rollback is of a transaction created by this
    ** process and if this is the final header in the journal, then it means
    ** that this part of the journal was being filled but has not yet been
    ** synced to disk.  Compute the number of pages based on the remaining
    ** size of the file.
    **
    ** The third term of the test was added to fix ticket #2565.
    ** When rolling back a hot journal, nRec==0 always means that the next
    ** chunk of the journal contains zero pages to be rolled back.  But
    ** when doing a ROLLBACK and the nRec==0 chunk is the last chunk in
    ** the journal, it means that the journal might contain additional
    ** pages that need to be rolled back and that the number of pages
    ** should be computed based on the journal file size.
    */
    if( nRec==0 && !isHot &&
        pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){
      nRec = (int)((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager));
    }

    /* If this is the first header read from the journal, truncate the
    ** database file back to its original size.
    */
    if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){
      rc = pager_truncate(pPager, mxPg);
      if( rc!=SQLITE_OK ){
        goto end_playback;
      }
      pPager->dbSize = mxPg;
    }

    /* Copy original pages out of the journal and back into the
    ** database file and/or page cache.
    */
    for(u=0; u<nRec; u++){
      if( needPagerReset ){
        pager_reset(pPager);
        needPagerReset = 0;
      }
      rc = pager_playback_one_page(pPager,&pPager->journalOff,0,1,0);
      if( rc==SQLITE_OK ){
        nPlayback++;
      }else{
        if( rc==SQLITE_DONE ){
          pPager->journalOff = szJ;
          break;
        }else if( rc==SQLITE_IOERR_SHORT_READ ){
          /* If the journal has been truncated, simply stop reading and
          ** processing the journal. This might happen if the journal was
          ** not completely written and synced prior to a crash.  In that
          ** case, the database should have never been written in the
          ** first place so it is OK to simply abandon the rollback. */
          rc = SQLITE_OK;
          goto end_playback;
        }else{
          /* If we are unable to rollback, quit and return the error
          ** code.  This will cause the pager to enter the error state
          ** so that no further harm will be done.  Perhaps the next
          ** process to come along will be able to rollback the database.
          */
          goto end_playback;
        }
      }
    }
  }
  /*NOTREACHED*/
  assert( 0 );

end_playback:
  if( rc==SQLITE_OK ){
    rc = sqlite3PagerSetPagesize(pPager, &savedPageSize, -1);
  }
  /* Following a rollback, the database file should be back in its original
  ** state prior to the start of the transaction, so invoke the
  ** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the
  ** assertion that the transaction counter was modified.
  */
#ifdef SQLITE_DEBUG
  sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0);
#endif

  /* If this playback is happening automatically as a result of an IO or
  ** malloc error that occurred after the change-counter was updated but
  ** before the transaction was committed, then the change-counter
  ** modification may just have been reverted. If this happens in exclusive
  ** mode, then subsequent transactions performed by the connection will not
  ** update the change-counter at all. This may lead to cache inconsistency
  ** problems for other processes at some point in the future. So, just
  ** in case this has happened, clear the changeCountDone flag now.
  */
  pPager->changeCountDone = pPager->tempFile;

  if( rc==SQLITE_OK ){
    zSuper = pPager->pTmpSpace;
    rc = readSuperJournal(pPager->jfd, zSuper, pPager->pVfs->mxPathname+1);
    testcase( rc!=SQLITE_OK );
  }
  if( rc==SQLITE_OK
   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
  ){
    rc = sqlite3PagerSync(pPager, 0);
  }
  if( rc==SQLITE_OK ){
    rc = pager_end_transaction(pPager, zSuper[0]!='\0', 0);
    testcase( rc!=SQLITE_OK );
  }
  if( rc==SQLITE_OK && zSuper[0] && res ){
    /* If there was a super-journal and this routine will return success,
    ** see if it is possible to delete the super-journal.
    */
    rc = pager_delsuper(pPager, zSuper);
    testcase( rc!=SQLITE_OK );
  }
  if( isHot && nPlayback ){
    sqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s",
                nPlayback, pPager->zJournal);
  }

  /* The Pager.sectorSize variable may have been updated while rolling
  ** back a journal created by a process with a different sector size
  ** value. Reset it to the correct value for this process.
  */
  setSectorSize(pPager);
  return rc;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movl %esi, %ebp
movq %rdi, %rbx
movq (%rdi), %r12
movl $0x0, 0x2c(%rsp)
movl $0x1, 0x28(%rsp)
movl 0xbc(%rdi), %eax
movl %eax, 0x60(%rsp)
movq 0x50(%rdi), %rdi
movq (%rdi), %rax
leaq 0x38(%rsp), %rsi
callq *0x30(%rax)
xorl %r14d, %r14d
testl %eax, %eax
je 0x293cea
movl %eax, %r15d
testl %r15d, %r15d
jne 0x293cda
leaq 0x60(%rsp), %rsi
movq %rbx, %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x28f528
movl %eax, %r15d
movb 0x10(%rbx), %al
movb %al, 0x16(%rbx)
testl %r15d, %r15d
je 0x293d35
xorl %r12d, %r12d
jmp 0x293d53
movq 0x110(%rbx), %r13
movq (%rbx), %rax
movq 0x50(%rbx), %rdi
movl 0x8(%rax), %edx
incl %edx
movq %r13, %rsi
callq 0x294a90
movl %eax, %r15d
testl %eax, %eax
jne 0x293ea1
cmpb $0x0, (%r13)
je 0x293e9e
leaq 0x28(%rsp), %rcx
movq %r12, %rdi
movq %r13, %rsi
xorl %edx, %edx
callq *0x38(%r12)
movl %eax, %r15d
jmp 0x293ea1
movq 0x110(%rbx), %r12
movq (%rbx), %rax
movq 0x50(%rbx), %rdi
movl 0x8(%rax), %edx
incl %edx
movq %r12, %rsi
callq 0x294a90
movl %eax, %r15d
testl %r15d, %r15d
jne 0x293d71
movb 0x14(%rbx), %al
addb $-0x4, %al
xorl %r15d, %r15d
cmpb $-0x4, %al
ja 0x293d71
movq %rbx, %rdi
xorl %esi, %esi
callq 0x281055
movl %eax, %r15d
testl %r15d, %r15d
jne 0x293d8e
xorl %esi, %esi
cmpb $0x0, (%r12)
setne %sil
movq %rbx, %rdi
xorl %edx, %edx
callq 0x29336a
movl %eax, %r15d
testl %r15d, %r15d
je 0x293dd3
testl %ebp, %ebp
je 0x293db9
testl %r14d, %r14d
je 0x293db9
movq 0xd8(%rbx), %rcx
leaq 0x14b6b4(%rip), %rsi    # 0x3df45e
movl $0x21b, %edi            # imm = 0x21B
movl %r14d, %edx
xorl %eax, %eax
callq 0x27e637
movq %rbx, %rdi
callq 0x28f82e
movl %r15d, %eax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %r15d, %r15d
cmpb $0x0, (%r12)
je 0x293d93
cmpl $0x0, 0x28(%rsp)
je 0x293d93
movq %r14, 0x10(%rsp)
movq (%rbx), %r13
movslq 0x4(%r13), %r15
addq %r15, %r15
movq %r15, %rdi
callq 0x27c381
movq %rax, %r14
testq %rax, %rax
movq %r13, 0x48(%rsp)
je 0x293e36
movq %r14, %rdi
xorl %esi, %esi
movq %r15, %rdx
callq 0x173a0
movq %r13, %rdi
movq %r12, %rsi
movq %r14, %rdx
movl $0x4001, %ecx           # imm = 0x4001
xorl %r8d, %r8d
callq *0x28(%r13)
movl %eax, %r15d
movslq 0x4(%r13), %rax
addq %r14, %rax
jmp 0x293e3e
movl $0x7, %r15d
xorl %eax, %eax
movq %r14, %r13
testl %r15d, %r15d
movq 0x10(%rsp), %r14
jne 0x293e6a
movq %rax, 0x58(%rsp)
movq (%r13), %rax
leaq 0x40(%rsp), %rsi
movq %r13, %rdi
callq *0x30(%rax)
testl %eax, %eax
je 0x294041
movl %eax, %r15d
xorl %edi, %edi
callq 0x27c490
testq %r13, %r13
je 0x293d93
movq (%r13), %rax
testq %rax, %rax
je 0x293e91
movq %r13, %rdi
callq *0x8(%rax)
movq $0x0, (%r13)
movq %r13, %rdi
callq 0x27c490
jmp 0x293d93
xorl %r15d, %r15d
testl %r15d, %r15d
jne 0x293cc0
cmpl $0x0, 0x28(%rsp)
je 0x293cc0
movq $0x0, 0x60(%rbx)
movq 0x38(%rsp), %rdx
leaq 0xc(%rsp), %rcx
leaq 0x2c(%rsp), %r8
movq %rbx, %rdi
movl %ebp, %esi
callq 0x2945ed
xorl %r15d, %r15d
testl %eax, %eax
je 0x293eec
xorl %r14d, %r14d
cmpl $0x65, %eax
cmovnel %eax, %r15d
jmp 0x293cc0
leaq 0x60(%rbx), %r12
xorl %r14d, %r14d
movl %ebp, %r13d
movl %ebp, 0x1c(%rsp)
cmpl $-0x1, 0xc(%rsp)
jne 0x293f23
movq 0x38(%rsp), %rax
movl 0xb8(%rbx), %ecx
subq %rcx, %rax
movslq 0xbc(%rbx), %rcx
addq $0x8, %rcx
cqto
idivq %rcx
movl %eax, 0xc(%rsp)
movl 0xc(%rsp), %eax
orl %ebp, %eax
jne 0x293f5a
movl 0xb8(%rbx), %eax
addq 0x68(%rbx), %rax
movq 0x60(%rbx), %rcx
cmpq %rcx, %rax
jne 0x293f5a
movq 0x38(%rsp), %rax
subq %rcx, %rax
movslq 0xbc(%rbx), %rcx
addq $0x8, %rcx
cqto
idivq %rcx
movl %eax, 0xc(%rsp)
movl 0xb8(%rbx), %eax
cmpq %rax, 0x60(%rbx)
jne 0x293f95
movq %r14, 0x10(%rsp)
movl %ebp, %r14d
movl %r13d, %ebp
movl 0x2c(%rsp), %r13d
movq %rbx, %rdi
movl %r13d, %esi
callq 0x294bbf
testl %eax, %eax
jne 0x294244
movl %r13d, 0x1c(%rbx)
movl %ebp, %r13d
movq 0x10(%rsp), %r14
movl 0xc(%rsp), %ebp
testl %ebp, %ebp
je 0x293fe9
leal (%r14,%rbp), %eax
movl %eax, 0x10(%rsp)
testl %r13d, %r13d
sete %al
negl %ebp
xorl %r13d, %r13d
testb $0x1, %al
jne 0x293fbc
movq %rbx, %rdi
callq 0x294c73
movq %rbx, %rdi
movq %r12, %rsi
xorl %edx, %edx
movl $0x1, %ecx
xorl %r8d, %r8d
callq 0x2942cd
testl %eax, %eax
jne 0x293fef
decl %r13d
movb $0x1, %al
cmpl %r13d, %ebp
jne 0x293fb0
xorl %r13d, %r13d
movl 0x10(%rsp), %eax
movl %eax, %r14d
movl 0x1c(%rsp), %ebp
jmp 0x294007
cmpl $0x65, %eax
movl 0x1c(%rsp), %ebp
jne 0x29402d
movq 0x38(%rsp), %rax
movq %rax, (%r12)
subl %r13d, %r14d
xorl %r13d, %r13d
movq 0x38(%rsp), %rdx
movq %rbx, %rdi
movl %ebp, %esi
leaq 0xc(%rsp), %rcx
leaq 0x2c(%rsp), %r8
callq 0x2945ed
testl %eax, %eax
je 0x293efa
jmp 0x293ee0
xorl %r15d, %r15d
cmpl $0x20a, %eax            # imm = 0x20A
cmovnel %eax, %r15d
subl %r13d, %r14d
jmp 0x293cc0
movq %r13, 0x30(%rsp)
movq 0x48(%rsp), %r13
movslq 0x8(%r13), %r14
movq 0x40(%rsp), %rax
leaq (%rax,%r14), %rdi
addq $0x3, %rdi
callq 0x27c381
testq %rax, %rax
je 0x294098
movq %r14, 0x68(%rsp)
movq 0x40(%rsp), %r13
movq 0x30(%rsp), %rdi
movq (%rdi), %r8
movq %rax, %r14
movq %rax, %rsi
movl %r13d, %edx
xorl %ecx, %ecx
callq *0x10(%r8)
testl %eax, %eax
je 0x2940af
movl %eax, %r15d
movq 0x30(%rsp), %r13
movq %r14, %rdi
jmp 0x2940a5
movl $0x7, %r15d
xorl %edi, %edi
movq 0x30(%rsp), %r13
movq 0x10(%rsp), %r14
jmp 0x293e6c
incq 0x68(%rsp)
leaq (%r14,%r13), %rax
addq $0x2, %rax
movq %rax, 0x70(%rsp)
movq 0x40(%rsp), %rax
xorl %ecx, %ecx
movb %cl, (%r14,%rax)
movq 0x40(%rsp), %rax
movb %cl, 0x1(%r14,%rax)
movq %r14, %rdi
leaq 0x64(%rsp), %r14
movq %rdi, %r13
movq %rdi, 0x20(%rsp)
movl %ebp, 0x1c(%rsp)
movq %r13, %rax
subq %rdi, %rax
cmpq 0x40(%rsp), %rax
jge 0x294254
movq 0x48(%rsp), %rdi
movq %r13, %rsi
xorl %edx, %edx
movq %r14, %rcx
callq *0x38(%rdi)
testl %eax, %eax
je 0x294121
movl %eax, %r15d
movl $0x2, %eax
movq 0x20(%rsp), %rdi
jmp 0x294229
cmpl $0x0, 0x64(%rsp)
je 0x29416c
movq %r13, %rsi
movq %r14, %r13
xorl %ebp, %ebp
movq 0x48(%rsp), %rdi
movq %rsi, 0x50(%rsp)
movq 0x58(%rsp), %r14
movq %r14, %rdx
movl $0x4001, %ecx           # imm = 0x4001
xorl %r8d, %r8d
callq *0x28(%rdi)
movl %eax, %r15d
movl $0x2, %eax
testl %r15d, %r15d
je 0x294179
movq 0x20(%rsp), %rdi
movq %r13, %r14
movq 0x50(%rsp), %r13
jmp 0x2941fa
xorl %r15d, %r15d
movq 0x20(%rsp), %rdi
jmp 0x294203
movq %r14, %rdi
movq 0x70(%rsp), %rbp
movq %rbp, %rsi
movq 0x68(%rsp), %rdx
callq 0x294a90
movl %eax, %r15d
movq (%r14), %rax
testq %rax, %rax
je 0x2941ad
movq 0x58(%rsp), %rdi
callq *0x8(%rax)
movq 0x58(%rsp), %rax
movq $0x0, (%rax)
testl %r15d, %r15d
movq %r13, %r14
je 0x2941c8
xorl %ebp, %ebp
movq 0x20(%rsp), %rdi
movq 0x50(%rsp), %r13
movl $0x2, %eax
jmp 0x2941fa
xorl %r15d, %r15d
cmpb $0x0, (%rbp)
movq 0x50(%rsp), %r13
je 0x2941e9
movq %rbp, %rdi
movq %r12, %rsi
callq 0x17a40
testl %eax, %eax
sete %bpl
jmp 0x2941eb
xorl %ebp, %ebp
movzbl %bpl, %eax
xorb $0x1, %bpl
addl %eax, %eax
movq 0x20(%rsp), %rdi
testb %bpl, %bpl
movl 0x1c(%rsp), %ebp
je 0x294229
testq %r13, %r13
je 0x29421f
movq %r13, %rdi
callq 0x172f0
movq 0x20(%rsp), %rdi
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
incq %rax
jmp 0x294224
movl $0x1, %eax
addq %rax, %r13
xorl %eax, %eax
testl %eax, %eax
je 0x2940ea
cmpl $0x2, %eax
je 0x2940a0
movq 0x10(%rsp), %r14
jmp 0x293d93
movl %eax, %r15d
movl %r14d, %ebp
movq 0x10(%rsp), %r14
jmp 0x293cc0
movq 0x30(%rsp), %r13
movq (%r13), %rax
testq %rax, %rax
movq 0x48(%rsp), %r15
je 0x294275
movq %r13, %rdi
callq *0x8(%rax)
movq $0x0, (%r13)
movq %r15, %rdi
movq %r12, %rsi
xorl %edx, %edx
callq *0x30(%r15)
movl %eax, %r15d
movq 0x10(%rsp), %r14
movq 0x20(%rsp), %rdi
jmp 0x293e6c