// File: /workspace/github_c_makefile_star2_O1/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:
movq 0x28(%rdi), %rax
movq (%rax), %rdx
movq 0x8(%rax), %rcx
movq %rdx, 0x8(%rcx)
movl 0x30(%rdi), %eax
cmpl $0x6, %eax
ja 0xd066
movl $0x61, %edx
btl %eax, %edx
jae 0xd066
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movl %esi, %r13d
movq %rdi, %r12
movq 0x8(%rdi), %rdi
movq 0x8(%rdi), %rdx
cmpq $0x0, (%r12)
je 0xcba4
cmpb $0x2, 0x24(%rcx)
jne 0xcba4
movl $0x5, %eax
xorl %esi, %esi
jmp 0xcba9
xorl %eax, %eax
movb $0x1, %sil
movq (%rcx), %rcx
movq %rcx, -0x70(%rbp)
movq (%rdx), %rcx
movq %rcx, -0x40(%rbp)
testb %sil, %sil
je 0xcc01
xorl %eax, %eax
cmpl $0x0, 0x14(%r12)
jne 0xcc01
movl $0x2, %esi
callq 0xd067
testl %eax, %eax
jne 0xcc01
movl $0x1, 0x14(%r12)
movq 0x8(%r12), %rax
movq (%rax), %rcx
movq 0x8(%rax), %rax
movq %rcx, 0x8(%rax)
movq 0x18(%rax), %rax
movq 0x50(%rax), %rax
movl 0x28(%rax), %eax
bswapl %eax
movl %eax, 0x10(%r12)
xorl %eax, %eax
movb $0x1, %bl
testl %eax, %eax
jne 0xcc1d
movq 0x28(%r12), %rdi
xorl %eax, %eax
cmpb $0x0, 0x10(%rdi)
jne 0xcc1d
xorl %ebx, %ebx
xorl %esi, %esi
callq 0xd067
movl %ebx, -0x5c(%rbp)
movq 0x8(%r12), %rcx
movq 0x28(%r12), %rdx
movq 0x8(%rdx), %rdx
movslq 0x30(%rdx), %rsi
movq 0x8(%rcx), %rcx
movl 0x30(%rcx), %edi
xorl %r9d, %r9d
movq %rsi, -0x68(%rbp)
movl %edi, -0x4c(%rbp)
cmpl %edi, %esi
setne %r9b
movq (%rcx), %rcx
movb 0x9(%rcx), %cl
shll $0x3, %r9d
movb %cl, -0x38(%rbp)
cmpb $0x5, %cl
cmovnel %eax, %r9d
testl %eax, %eax
cmovnel %eax, %r9d
movl 0x3c(%rdx), %r8d
testl %r13d, %r13d
je 0xcd13
movl $0x1, %ebx
movq %r12, -0x48(%rbp)
movl 0x18(%r12), %r15d
cmpl %r8d, %r15d
ja 0xcd13
testl %r9d, %r9d
jne 0xcd13
movl 0x87baa(%rip), %eax     # 0x94840
movq 0x28(%r12), %rcx
movq 0x8(%rcx), %rcx
xorl %edx, %edx
divl 0x30(%rcx)
incl %eax
cmpl %eax, %r15d
je 0xccf6
movq %r8, %r14
movq -0x70(%rbp), %rdi
movl %r15d, %esi
leaq -0x30(%rbp), %rdx
movl $0x2, %ecx
callq 0xd803
movl %eax, %r9d
testl %eax, %eax
jne 0xccf3
movq -0x30(%rbp), %r12
movq 0x8(%r12), %rdx
movq -0x48(%rbp), %rdi
movl %r15d, %esi
xorl %ecx, %ecx
callq 0xdb66
movl %eax, %r15d
movq %r12, %rdi
movq -0x48(%rbp), %r12
callq 0xdcd4
movl %r15d, %r9d
movq %r14, %r8
testl %r13d, %r13d
sets %al
incl 0x18(%r12)
cmpl %r13d, %ebx
setl %cl
orb %al, %cl
incl %ebx
testb %cl, %cl
jne 0xcc79
testl %r9d, %r9d
movq -0x68(%rbp), %r15
jne 0xcd66
movl %r8d, 0x38(%r12)
movl %r8d, %eax
movl $0x65, %r9d
subl 0x18(%r12), %eax
leal 0x1(%rax), %eax
movl %eax, 0x34(%r12)
jb 0xcd66
xorl %r9d, %r9d
cmpl $0x0, 0x3c(%r12)
jne 0xcd66
movq 0x28(%r12), %rax
movq 0x8(%rax), %rax
movq (%rax), %rax
movq 0x70(%rax), %rcx
movq %rcx, 0x40(%r12)
movq %r12, 0x70(%rax)
movl $0x1, 0x3c(%r12)
cmpl $0x65, %r9d
jne 0xd01f
movl $0x65, %r9d
testl %r8d, %r8d
jne 0xcda0
movq 0x8(%r12), %rax
movq (%rax), %rcx
movq 0x8(%rax), %rdi
movq %rcx, 0x8(%rdi)
movl $0x0, 0x3c(%rdi)
callq 0x1fcda
movl %eax, %r9d
movl $0x1, %r8d
cmpl $0x65, %r9d
je 0xcdab
testl %r9d, %r9d
jne 0xcdca
movq 0x8(%r12), %rdi
movl 0x10(%r12), %edx
incl %edx
movl $0x1, %esi
movq %r8, %rbx
callq 0xdd57
movq %rbx, %r8
movl %eax, %r9d
testl %r9d, %r9d
jne 0xce04
movq (%r12), %rdi
testq %rdi, %rdi
je 0xcde3
movq %r8, %rbx
callq 0xdda5
movq %rbx, %r8
xorl %r9d, %r9d
cmpb $0x5, -0x38(%rbp)
jne 0xce04
movq 0x8(%r12), %rdi
movl $0x2, %esi
movq %r8, %rbx
callq 0xde32
movq %rbx, %r8
movl %eax, %r9d
testl %r9d, %r9d
jne 0xd01f
movl -0x4c(%rbp), %esi
cmpl %esi, %r15d
jge 0xce4c
movl %esi, %eax
cltd
idivl %r15d
movl %eax, %ecx
leal (%r8,%rcx), %eax
decl %eax
cltd
idivl %ecx
movl %eax, %r13d
movl 0x87a11(%rip), %eax     # 0x94840
movq 0x8(%r12), %rcx
movq 0x8(%rcx), %rcx
xorl %edx, %edx
divl 0x30(%rcx)
incl %eax
xorl %ecx, %ecx
cmpl %eax, %r13d
sete %cl
subl %ecx, %r13d
jmp 0xce59
movl %r15d, %eax
cltd
idivl %esi
movl %eax, %r13d
imull %r8d, %r13d
cmpl %esi, %r15d
jge 0xce87
movq %r12, -0x48(%rbp)
movslq %r8d, %rax
movq %rax, -0x58(%rbp)
movq -0x40(%rbp), %rax
movq 0x48(%rax), %rcx
movq %rcx, -0x38(%rbp)
movl 0x1c(%rax), %ebx
cmpl %ebx, %r13d
jbe 0xce9d
movb $0x1, %al
xorl %r9d, %r9d
jmp 0xcf0b
movq -0x40(%rbp), %rdi
movl %r13d, 0x1c(%rdi)
xorl %esi, %esi
xorl %edx, %edx
callq 0xe086
jmp 0xcfff
leaq -0x30(%rbp), %r12
movl 0x87999(%rip), %eax     # 0x94840
movq -0x48(%rbp), %rcx
movq 0x8(%rcx), %rcx
movq 0x8(%rcx), %rcx
xorl %edx, %edx
divl 0x30(%rcx)
incl %eax
movl $0x0, %r9d
cmpl %eax, %r13d
je 0xcefb
movq -0x40(%rbp), %rdi
movl %r13d, %esi
movq %r12, %rdx
xorl %ecx, %ecx
callq 0xd803
movl %eax, %r9d
testl %eax, %eax
jne 0xcefb
movq -0x30(%rbp), %r15
movq %r15, %rdi
callq 0xdebf
movl %eax, %r14d
movq %r15, %rdi
movq -0x68(%rbp), %r15
callq 0xdcd4
movl %r14d, %r9d
testl %r9d, %r9d
sete %al
jne 0xcf0b
incl %r13d
cmpl %ebx, %r13d
jbe 0xcea1
movq -0x58(%rbp), %r14
imulq %r15, %r14
testb %al, %al
je 0xcf2a
movq -0x40(%rbp), %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0xe086
movl %eax, %r9d
movl 0x87910(%rip), %ecx     # 0x94840
movl -0x4c(%rbp), %eax
addl %ecx, %eax
movslq %eax, %rbx
cmpq %rbx, %r14
movq %r14, -0x58(%rbp)
cmovlq %r14, %rbx
testl %r9d, %r9d
sete %al
jne 0xcfb6
addl %r15d, %ecx
movslq %ecx, %r12
cmpq %r12, %rbx
jle 0xcfb6
leaq -0x30(%rbp), %r13
movq $0x0, -0x30(%rbp)
movq %r12, %rax
cqto
idivq %r15
leal 0x1(%rax), %esi
movq -0x70(%rbp), %rdi
movq %r13, %rdx
xorl %ecx, %ecx
callq 0xd803
testl %eax, %eax
jne 0xcf97
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x38(%rbp), %rdi
movq (%rdi), %rax
movl %r15d, %edx
movq %r12, %rcx
callq *0x18(%rax)
movq -0x30(%rbp), %rdi
movl %eax, %r14d
callq 0xdcd4
movl %r14d, %r9d
testl %r14d, %r14d
sete %al
jne 0xcfb6
addq %r15, %r12
cmpq %rbx, %r12
jl 0xcf5a
testb %al, %al
movq -0x48(%rbp), %r12
je 0xcff1
movq -0x38(%rbp), %rdi
movq (%rdi), %rax
leaq -0x30(%rbp), %rsi
callq *0x30(%rax)
movl %eax, %r9d
testl %eax, %eax
jne 0xcff1
xorl %r9d, %r9d
movq -0x58(%rbp), %rax
cmpq %rax, -0x30(%rbp)
jle 0xcff1
movq -0x38(%rbp), %rdi
movq (%rdi), %rax
movq -0x58(%rbp), %rsi
callq *0x20(%rax)
movl %eax, %r9d
testl %r9d, %r9d
jne 0xd002
movq -0x40(%rbp), %rdi
callq 0xe28c
movl %eax, %r9d
testl %r9d, %r9d
jne 0xd01f
movq 0x8(%r12), %rdi
xorl %esi, %esi
callq 0xe2d0
testl %eax, %eax
movl $0x65, %r9d
cmovnel %eax, %r9d
cmpb $0x0, -0x5c(%rbp)
jne 0xd043
movq 0x28(%r12), %rdi
xorl %esi, %esi
movl %r9d, %ebx
callq 0xe383
movq 0x28(%r12), %rdi
xorl %esi, %esi
callq 0xe2d0
movl %ebx, %r9d
cmpl $0xc0a, %r9d            # imm = 0xC0A
movl $0x7, %eax
cmovnel %r9d, %eax
movl %eax, 0x30(%r12)
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq