// File: /workspace/github_c_makefile_star2_O2/barabo[P]advanced-shell-history/src/sqlite3.c
// Function: sqlite3_backup_step
SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
  int rc;
  int destMode;       /* Destination journal mode */
  int pgszSrc = 0;    /* Source page size */
  int pgszDest = 0;   /* Destination page size */

  sqlite3_mutex_enter(p->pSrcDb->mutex);
  sqlite3BtreeEnter(p->pSrc);
  if( p->pDestDb ){
    sqlite3_mutex_enter(p->pDestDb->mutex);
  }

  rc = p->rc;
  if( !isFatalError(rc) ){
    Pager * const pSrcPager = sqlite3BtreePager(p->pSrc);     /* Source pager */
    Pager * const pDestPager = sqlite3BtreePager(p->pDest);   /* Dest pager */
    int ii;                            /* Iterator variable */
    int nSrcPage = -1;                 /* Size of source db in pages */
    int bCloseTrans = 0;               /* True if src db requires unlocking */

    /* If the source pager is currently in a write-transaction, return
    ** SQLITE_BUSY immediately.
    */
    if( p->pDestDb && p->pSrc->pBt->inTransaction==TRANS_WRITE ){
      rc = SQLITE_BUSY;
    }else{
      rc = SQLITE_OK;
    }

    /* Lock the destination database, if it is not locked already. */
    if( SQLITE_OK==rc && p->bDestLocked==0
     && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) 
    ){
      p->bDestLocked = 1;
      sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema);
    }

    /* If there is no open read-transaction on the source database, open
    ** one now. If a transaction is opened here, then it will be closed
    ** before this function exits.
    */
    if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){
      rc = sqlite3BtreeBeginTrans(p->pSrc, 0);
      bCloseTrans = 1;
    }

    /* Do not allow backup if the destination database is in WAL mode
    ** and the page sizes are different between source and destination */
    pgszSrc = sqlite3BtreeGetPageSize(p->pSrc);
    pgszDest = sqlite3BtreeGetPageSize(p->pDest);
    destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(p->pDest));
    if( SQLITE_OK==rc && destMode==PAGER_JOURNALMODE_WAL && pgszSrc!=pgszDest ){
      rc = SQLITE_READONLY;
    }
  
    /* Now that there is a read-lock on the source database, query the
    ** source pager for the number of pages in the database.
    */
    nSrcPage = (int)sqlite3BtreeLastPage(p->pSrc);
    assert( nSrcPage>=0 );
    for(ii=0; (nPage<0 || ii<nPage) && p->iNext<=(Pgno)nSrcPage && !rc; ii++){
      const Pgno iSrcPg = p->iNext;                 /* Source page number */
      if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
        DbPage *pSrcPg;                             /* Source page object */
        rc = sqlite3PagerAcquire(pSrcPager, iSrcPg, &pSrcPg,
                                 PAGER_GET_READONLY);
        if( rc==SQLITE_OK ){
          rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0);
          sqlite3PagerUnref(pSrcPg);
        }
      }
      p->iNext++;
    }
    if( rc==SQLITE_OK ){
      p->nPagecount = nSrcPage;
      p->nRemaining = nSrcPage+1-p->iNext;
      if( p->iNext>(Pgno)nSrcPage ){
        rc = SQLITE_DONE;
      }else if( !p->isAttached ){
        attachBackupObject(p);
      }
    }
  
    /* Update the schema version field in the destination database. This
    ** is to make sure that the schema-version really does change in
    ** the case where the source and destination databases have the
    ** same schema version.
    */
    if( rc==SQLITE_DONE ){
      if( nSrcPage==0 ){
        rc = sqlite3BtreeNewDb(p->pDest);
        nSrcPage = 1;
      }
      if( rc==SQLITE_OK || rc==SQLITE_DONE ){
        rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1);
      }
      if( rc==SQLITE_OK ){
        if( p->pDestDb ){
          sqlite3ResetAllSchemasOfConnection(p->pDestDb);
        }
        if( destMode==PAGER_JOURNALMODE_WAL ){
          rc = sqlite3BtreeSetVersion(p->pDest, 2);
        }
      }
      if( rc==SQLITE_OK ){
        int nDestTruncate;
        /* Set nDestTruncate to the final number of pages in the destination
        ** database. The complication here is that the destination page
        ** size may be different to the source page size. 
        **
        ** If the source page size is smaller than the destination page size, 
        ** round up. In this case the call to sqlite3OsTruncate() below will
        ** fix the size of the file. However it is important to call
        ** sqlite3PagerTruncateImage() here so that any pages in the 
        ** destination file that lie beyond the nDestTruncate page mark are
        ** journalled by PagerCommitPhaseOne() before they are destroyed
        ** by the file truncation.
        */
        assert( pgszSrc==sqlite3BtreeGetPageSize(p->pSrc) );
        assert( pgszDest==sqlite3BtreeGetPageSize(p->pDest) );
        if( pgszSrc<pgszDest ){
          int ratio = pgszDest/pgszSrc;
          nDestTruncate = (nSrcPage+ratio-1)/ratio;
          if( nDestTruncate==(int)PENDING_BYTE_PAGE(p->pDest->pBt) ){
            nDestTruncate--;
          }
        }else{
          nDestTruncate = nSrcPage * (pgszSrc/pgszDest);
        }
        assert( nDestTruncate>0 );

        if( pgszSrc<pgszDest ){
          /* If the source page-size is smaller than the destination page-size,
          ** two extra things may need to happen:
          **
          **   * The destination may need to be truncated, and
          **
          **   * Data stored on the pages immediately following the 
          **     pending-byte page in the source database may need to be
          **     copied into the destination database.
          */
          const i64 iSize = (i64)pgszSrc * (i64)nSrcPage;
          sqlite3_file * const pFile = sqlite3PagerFile(pDestPager);
          Pgno iPg;
          int nDstPage;
          i64 iOff;
          i64 iEnd;

          assert( pFile );
          assert( nDestTruncate==0 
              || (i64)nDestTruncate*(i64)pgszDest >= iSize || (
                nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1)
             && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest
          ));

          /* This block ensures that all data required to recreate the original
          ** database has been stored in the journal for pDestPager and the
          ** journal synced to disk. So at this point we may safely modify
          ** the database file in any way, knowing that if a power failure
          ** occurs, the original database will be reconstructed from the 
          ** journal file.  */
          sqlite3PagerPagecount(pDestPager, &nDstPage);
          for(iPg=nDestTruncate; rc==SQLITE_OK && iPg<=(Pgno)nDstPage; iPg++){
            if( iPg!=PENDING_BYTE_PAGE(p->pDest->pBt) ){
              DbPage *pPg;
              rc = sqlite3PagerGet(pDestPager, iPg, &pPg);
              if( rc==SQLITE_OK ){
                rc = sqlite3PagerWrite(pPg);
                sqlite3PagerUnref(pPg);
              }
            }
          }
          if( rc==SQLITE_OK ){
            rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1);
          }

          /* Write the extra pages and truncate the database file as required */
          iEnd = MIN(PENDING_BYTE + pgszDest, iSize);
          for(
            iOff=PENDING_BYTE+pgszSrc; 
            rc==SQLITE_OK && iOff<iEnd; 
            iOff+=pgszSrc
          ){
            PgHdr *pSrcPg = 0;
            const Pgno iSrcPg = (Pgno)((iOff/pgszSrc)+1);
            rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
            if( rc==SQLITE_OK ){
              u8 *zData = sqlite3PagerGetData(pSrcPg);
              rc = sqlite3OsWrite(pFile, zData, pgszSrc, iOff);
            }
            sqlite3PagerUnref(pSrcPg);
          }
          if( rc==SQLITE_OK ){
            rc = backupTruncateFile(pFile, iSize);
          }

          /* Sync the database file to disk. */
          if( rc==SQLITE_OK ){
            rc = sqlite3PagerSync(pDestPager);
          }
        }else{
          sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
          rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 0);
        }
    
        /* Finish committing the transaction to the destination database. */
        if( SQLITE_OK==rc
         && SQLITE_OK==(rc = sqlite3BtreeCommitPhaseTwo(p->pDest, 0))
        ){
          rc = SQLITE_DONE;
        }
      }
    }
  
    /* If bCloseTrans is true, then this function opened a read transaction
    ** on the source database. Close the read transaction here. There is
    ** no need to check the return values of the btree methods here, as
    ** "committing" a read-only transaction cannot fail.
    */
    if( bCloseTrans ){
      TESTONLY( int rc2 );
      TESTONLY( rc2  = ) sqlite3BtreeCommitPhaseOne(p->pSrc, 0);
      TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc, 0);
      assert( rc2==SQLITE_OK );
    }
  
    if( rc==SQLITE_IOERR_NOMEM ){
      rc = SQLITE_NOMEM;
    }
    p->rc = rc;
  }
  if( p->pDestDb ){
    sqlite3_mutex_leave(p->pDestDb->mutex);
  }
  sqlite3BtreeLeave(p->pSrc);
  sqlite3_mutex_leave(p->pSrcDb->mutex);
  return rc;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rdi, %r15
movq 0x28(%rdi), %rdi
movq (%rdi), %rax
movq 0x8(%rdi), %rcx
movq %rax, 0x8(%rcx)
movl 0x30(%r15), %eax
cmpl $0x6, %eax
ja 0xc436
pushq $0x61
popq %rdx
btl %eax, %edx
jae 0xc436
movl %esi, %r13d
movq (%rcx), %rax
movq %rax, -0x70(%rbp)
movq 0x8(%r15), %rax
movq 0x8(%rax), %rdx
movq (%rdx), %rdx
movq %rdx, -0x40(%rbp)
cmpq $0x0, (%r15)
je 0xc031
cmpb $0x2, 0x24(%rcx)
jne 0xc031
pushq $0x5
popq %rax
jmp 0xc059
cmpl $0x0, 0x14(%r15)
je 0xc046
cmpb $0x0, 0x10(%rdi)
je 0xc18f
xorl %eax, %eax
jmp 0xc059
pushq $0x2
popq %rsi
movq %rax, %rdi
callq 0xc487
testl %eax, %eax
je 0xc2f6
movb $0x1, %cl
movl %ecx, -0x2c(%rbp)
movq 0x8(%r15), %rcx
movq 0x28(%r15), %rdx
movq 0x8(%rdx), %rdx
movslq 0x30(%rdx), %rsi
movq 0x8(%rcx), %rcx
movl 0x30(%rcx), %edi
xorl %r8d, %r8d
movq %rsi, -0x68(%rbp)
movl %edi, -0x44(%rbp)
cmpl %edi, %esi
setne %r8b
movq (%rcx), %rcx
movb 0x9(%rcx), %cl
shll $0x3, %r8d
movb %cl, -0x50(%rbp)
cmpb $0x5, %cl
cmovnel %eax, %r8d
testl %eax, %eax
cmovnel %eax, %r8d
movl 0x3c(%rdx), %esi
xorl %ebx, %ebx
movq %r15, -0x58(%rbp)
testl %r13d, %r13d
sets %al
cmpl %r13d, %ebx
setl %cl
orb %al, %cl
cmpb $0x1, %cl
jne 0xc144
movl 0x18(%r15), %r12d
cmpl %esi, %r12d
ja 0xc144
testl %r8d, %r8d
jne 0xc144
movl 0x7b76d(%rip), %eax     # 0x87840
movq 0x28(%r15), %rcx
movq 0x8(%rcx), %rcx
xorl %edx, %edx
divl 0x30(%rcx)
xorl %r8d, %r8d
incl %eax
cmpl %eax, %r12d
je 0xc136
movq %rsi, %r14
movq -0x70(%rbp), %rdi
movl %r12d, %esi
leaq -0x38(%rbp), %rdx
pushq $0x2
popq %rcx
callq 0xca7d
movl %eax, %r8d
testl %eax, %eax
jne 0xc12f
movq -0x38(%rbp), %r15
movq 0x8(%r15), %rdx
movq -0x58(%rbp), %rdi
movl %r12d, %esi
xorl %ecx, %ecx
callq 0xce23
movl %eax, %r12d
movq %r15, %rdi
movq -0x58(%rbp), %r15
callq 0xcf6e
movl %r12d, %r8d
movl 0x18(%r15), %r12d
movq %r14, %rsi
incl %r12d
movl %r12d, 0x18(%r15)
incl %ebx
jmp 0xc0a8
cmpl $0x65, %r8d
je 0xc166
testl %r8d, %r8d
jne 0xc402
movl %esi, 0x38(%r15)
movl %esi, %eax
subl 0x18(%r15), %eax
leal 0x1(%rax), %eax
movl %eax, 0x34(%r15)
jae 0xc1d5
testl %esi, %esi
je 0xc1a2
movq %rsi, %rbx
movq 0x8(%r15), %rdi
movl 0x10(%r15), %edx
incl %edx
pushq $0x1
popq %rsi
callq 0xcfd5
testl %eax, %eax
je 0xc207
movl %eax, %r8d
jmp 0xc402
movl $0x0, -0x2c(%rbp)
xorl %esi, %esi
callq 0xc487
jmp 0xc05e
pushq $0x1
popq %rbx
movq 0x8(%r15), %rax
movq (%rax), %rcx
movq 0x8(%rax), %rdi
movq %rcx, 0x8(%rdi)
andl $0x0, 0x3c(%rdi)
callq 0x1d141
cmpl $0x65, %eax
je 0xc317
movl %eax, %r8d
testl %eax, %eax
movq %rbx, %rsi
je 0xc16a
jmp 0xc402
xorl %r8d, %r8d
cmpl $0x0, 0x3c(%r15)
jne 0xc402
movq 0x28(%r15), %rax
movq 0x8(%rax), %rax
movq (%rax), %rax
movq 0x70(%rax), %rcx
movq %rcx, 0x40(%r15)
movq %r15, 0x70(%rax)
movl $0x1, 0x3c(%r15)
jmp 0xc402
movq (%r15), %rdi
testq %rdi, %rdi
je 0xc214
callq 0xd023
cmpb $0x5, -0x50(%rbp)
jne 0xc22e
movq 0x8(%r15), %rdi
pushq $0x2
popq %rsi
callq 0xd07e
testl %eax, %eax
jne 0xc187
movq -0x68(%rbp), %rcx
movl -0x44(%rbp), %esi
cmpl %esi, %ecx
jge 0xc31f
movl %esi, %eax
cltd
idivl %ecx
movl %eax, %ecx
leal (%rbx,%rcx), %eax
decl %eax
cltd
idivl %ecx
movl %eax, %r12d
movl 0x7b5eb(%rip), %eax     # 0x87840
movq 0x8(%r15), %rcx
movq 0x8(%rcx), %rcx
xorl %r8d, %r8d
xorl %edx, %edx
divl 0x30(%rcx)
incl %eax
xorl %ecx, %ecx
cmpl %eax, %r12d
sete %cl
subl %ecx, %r12d
movslq %ebx, %rax
movq %rax, -0x60(%rbp)
movq -0x40(%rbp), %rax
movq 0x48(%rax), %rcx
movq %rcx, -0x50(%rbp)
movl 0x1c(%rax), %ebx
leaq -0x38(%rbp), %r15
testl %r8d, %r8d
jne 0xc35c
cmpl %ebx, %r12d
ja 0xc35c
movl 0x7b59c(%rip), %eax     # 0x87840
movq -0x58(%rbp), %rcx
movq 0x8(%rcx), %rcx
movq 0x8(%rcx), %rcx
xorl %edx, %edx
divl 0x30(%rcx)
xorl %r8d, %r8d
incl %eax
cmpl %eax, %r12d
je 0xc2f1
movq -0x40(%rbp), %rdi
movl %r12d, %esi
movq %r15, %rdx
xorl %ecx, %ecx
callq 0xca7d
movl %eax, %r8d
testl %eax, %eax
jne 0xc2f1
movq -0x38(%rbp), %r13
movq %r13, %rdi
callq 0xd10b
movl %eax, %r14d
movq %r13, %rdi
callq 0xcf6e
movl %r14d, %r8d
incl %r12d
jmp 0xc28c
movl $0x1, 0x14(%r15)
movq 0x8(%r15), %rdi
leaq 0x10(%r15), %rdx
pushq $0x1
popq %rsi
callq 0xca45
movq 0x28(%r15), %rdi
jmp 0xc038
movq %rbx, %rsi
jmp 0xc16a
movl %ecx, %eax
cltd
idivl %esi
imull %ebx, %eax
movq -0x40(%rbp), %rdi
movl %eax, 0x1c(%rdi)
xorl %esi, %esi
xorl %edx, %edx
callq 0xd2a7
movl %eax, %r8d
testl %eax, %eax
jne 0xc402
movq 0x8(%r15), %rdi
xorl %esi, %esi
callq 0xd5eb
testl %eax, %eax
pushq $0x65
popq %r8
cmovnel %eax, %r8d
jmp 0xc402
movq -0x68(%rbp), %r12
movq -0x60(%rbp), %r14
imulq %r12, %r14
testl %r8d, %r8d
jne 0xc382
pushq $0x1
popq %rdx
movq -0x40(%rbp), %rdi
xorl %esi, %esi
callq 0xd2a7
movq -0x68(%rbp), %r12
movl %eax, %r8d
movl 0x7b4b8(%rip), %eax     # 0x87840
movl -0x44(%rbp), %ecx
addl %eax, %ecx
movslq %ecx, %rbx
cmpq %rbx, %r14
movq %r14, -0x60(%rbp)
cmovlq %r14, %rbx
addl %r12d, %eax
movslq %eax, %r15
testl %r8d, %r8d
jne 0xc3f9
cmpq %rbx, %r15
jge 0xc3f9
andq $0x0, -0x38(%rbp)
movq %r15, %rax
cqto
idivq %r12
leal 0x1(%rax), %esi
movq -0x70(%rbp), %rdi
leaq -0x38(%rbp), %rdx
xorl %ecx, %ecx
callq 0xca7d
movq -0x38(%rbp), %r13
testl %eax, %eax
jne 0xc3e6
movq 0x8(%r13), %rsi
movq -0x50(%rbp), %rdi
movq (%rdi), %rax
movl %r12d, %edx
movq %r15, %rcx
callq *0x18(%rax)
movq %r13, %rdi
movl %eax, %r14d
callq 0xcf6e
movl %r14d, %r8d
addq %r12, %r15
jmp 0xc3a1
testl %r8d, %r8d
movq -0x58(%rbp), %r15
je 0xc445
cmpb $0x0, -0x2c(%rbp)
jne 0xc424
movq 0x28(%r15), %rdi
xorl %esi, %esi
movl %r8d, %ebx
callq 0xd695
movq 0x28(%r15), %rdi
xorl %esi, %esi
callq 0xd5eb
movl %ebx, %r8d
cmpl $0xc0a, %r8d            # imm = 0xC0A
pushq $0x7
popq %rax
cmovnel %r8d, %eax
movl %eax, 0x30(%r15)
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq -0x50(%rbp), %rbx
movq (%rbx), %rax
leaq -0x38(%rbp), %rsi
movq %rbx, %rdi
callq *0x30(%rax)
testl %eax, %eax
jne 0xc187
movq -0x60(%rbp), %rsi
cmpq %rsi, -0x38(%rbp)
jle 0xc479
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x20(%rax)
testl %eax, %eax
jne 0xc187
movq -0x40(%rbp), %rdi
callq 0xd5a9
jmp 0xc337