upstream-sqlite: Update sqlite to version 3.37.1

This commit is contained in:
Joel16 2022-01-01 01:31:38 -05:00
parent 4169489865
commit ffb34be7e8
6 changed files with 12620 additions and 317 deletions

View File

@ -16,6 +16,7 @@ set(VITA_TITLEID "VITAHBSRT")
set(VITA_VERSION "01.24")
add_definitions(-DAPP_VERSION="${VITA_VERSION}")
add_definitions(-DVHBS_DEBUG=0)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -ffast-math -mtune=cortex-a9 -mfpu=neon -Wall -Wno-psabi -std=gnu++17")
set(VITA_MKSFOEX_FLAGS "${VITA_MKSFOEX_FLAGS} -d PARENTAL_LEVEL=1")
@ -54,6 +55,7 @@ add_executable(${PROJECT_NAME}
target_link_libraries(${PROJECT_NAME}
freetype
png
sqlite3
pthread
lzma
z
@ -70,7 +72,6 @@ target_link_libraries(${PROJECT_NAME}
SceLibKernel_stub
ScePower_stub
SceShaccCg_stub
SceSqlite_stub
SceSysmodule_stub
SceTouch_stub
)

View File

@ -1,9 +0,0 @@
#ifndef _VITA_HB_SORTER_SQLITE_H_
#define _VITA_HB_SORTER_SQLITE_H_
namespace SQLite {
int Init(void);
int Exit(void);
}
#endif

File diff suppressed because it is too large Load Diff

BIN
libs/lib/libsqlite3.a Normal file

Binary file not shown.

View File

@ -6,7 +6,6 @@
#include "gui.h"
#include "log.h"
#include "power.h"
#include "sqlite.h"
#include "textures.h"
#include "utils.h"
@ -87,7 +86,6 @@ namespace Services {
SCE_CTRL_CANCEL = Utils::GetCancelButton();
sceSysmoduleLoadModule(SCE_SYSMODULE_SQLITE);
SQLite::Init();
if (!FS::DirExists("ux0:data/VITAHomebrewSorter/backup"))
FS::MakeDir("ux0:data/VITAHomebrewSorter/backup");
@ -105,7 +103,6 @@ namespace Services {
// Clean up
Textures::Exit();
Log::Exit();
SQLite::Exit();
sceSysmoduleUnloadModule(SCE_SYSMODULE_SQLITE);
Utils::EndAppUtil();
ImGui_ImplVitaGL_Shutdown();

View File

@ -1,311 +1,244 @@
#include "sqlite3.h"
#include <psp2/io/fcntl.h>
#include <psp2/io/stat.h>
#include <psp2/kernel/clib.h>
#include <psp2/sqlite.h>
#include <cstdlib>
#include <psp2/kernel/threadmgr.h>
#include <psp2/rtc.h>
#include "sqlite.h"
// Heavily based on https://github.com/VitaSmith/libsqlite/blob/master/libsqlite/sqlite.c with c++ style casting and sceClib usage.
/*
* From sqlite3.h
*/
#ifndef SQLITE_EXTERN
# define SQLITE_EXTERN extern
#endif
#ifndef SQLITE_API
# define SQLITE_API
#endif
#define SQLITE_OK 0
#define SQLITE_IOERR 10
#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8))
#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8))
#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8))
#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8))
#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8))
#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8))
#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8))
#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8))
#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8))
#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8))
#define SQLITE_IOERR_ACCESS (SQLITE_IOERR | (13<<8))
#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
#define SQLITE_IOERR_LOCK (SQLITE_IOERR | (15<<8))
#define SQLITE_IOERR_CLOSE (SQLITE_IOERR | (16<<8))
#define SQLITE_IOERR_DIR_CLOSE (SQLITE_IOERR | (17<<8))
#define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8))
#define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8))
#define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8))
#define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8))
#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
#define SQLITE_OPEN_READONLY 0x00000001
#define SQLITE_OPEN_READWRITE 0x00000002
#define SQLITE_OPEN_CREATE 0x00000004
#define SQLITE_OPEN_URI 0x00000040
#define SQLITE_OPEN_NOMUTEX 0x00008000
#define SQLITE_OPEN_FULLMUTEX 0x00010000
#define SQLITE_OPEN_SHAREDCACHE 0x00020000
#define SQLITE_OPEN_PRIVATECACHE 0x00040000
#ifdef SQLITE_INT64_TYPE
typedef SQLITE_INT64_TYPE sqlite_int64;
typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
#if VHBS_DEBUG
#define DEBUG sceClibPrintf
#else
typedef long long int sqlite_int64;
typedef unsigned long long int sqlite_uint64;
#endif
typedef sqlite_int64 sqlite3_int64;
typedef sqlite_uint64 sqlite3_uint64;
typedef struct sqlite3_file sqlite3_file;
struct sqlite3_file {
const struct sqlite3_io_methods *pMethods;
};
typedef struct sqlite3_io_methods sqlite3_io_methods;
struct sqlite3_io_methods {
int iVersion;
int(*xClose)(sqlite3_file*);
int(*xRead)(sqlite3_file *, void *, int, sqlite3_int64);
int(*xWrite)(sqlite3_file *, const void *, int, sqlite3_int64);
int(*xTruncate)(sqlite3_file *, sqlite3_int64);
int(*xSync)(sqlite3_file *, int);
int(*xFileSize)(sqlite3_file *, sqlite3_int64 *);
int(*xLock)(sqlite3_file *, int);
int(*xUnlock)(sqlite3_file *, int);
int(*xCheckReservedLock)(sqlite3_file *, int *);
int(*xFileControl)(sqlite3_file *, int, void *);
int(*xSectorSize)(sqlite3_file *);
int(*xDeviceCharacteristics)(sqlite3_file *);
int(*xShmMap)(sqlite3_file *, int, int, int, void volatile **);
int(*xShmLock)(sqlite3_file *, int, int, int);
void(*xShmBarrier)(sqlite3_file *);
int(*xShmUnmap)(sqlite3_file *, int);
};
typedef struct sqlite3_vfs sqlite3_vfs;
typedef void(*sqlite3_syscall_ptr)(void);
struct sqlite3_vfs {
int iVersion;
int szOsFile;
int mxPathname;
sqlite3_vfs *pNext;
const char *zName;
void *pAppData;
int(*xOpen)(sqlite3_vfs *, const char *zName, sqlite3_file *, int flags, int *pOutFlags);
int(*xDelete)(sqlite3_vfs *, const char *zName, int syncDir);
int(*xAccess)(sqlite3_vfs *, const char *zName, int flags, int *pResOut);
int(*xFullPathname)(sqlite3_vfs *, const char *zName, int nOut, char *zOut);
void *(*xDlOpen)(sqlite3_vfs *, const char *zFilename);
void(*xDlError)(sqlite3_vfs *, int nByte, char *zErrMsg);
void(*(*xDlSym)(sqlite3_vfs *, void *, const char *zSymbol))(void);
void(*xDlClose)(sqlite3_vfs *, void *);
int(*xRandomness)(sqlite3_vfs *, int nByte, char *zOut);
int(*xSleep)(sqlite3_vfs *, int microseconds);
int(*xCurrentTime)(sqlite3_vfs *, double *);
int(*xGetLastError)(sqlite3_vfs *, int, char *);
int(*xCurrentTimeInt64)(sqlite3_vfs *, sqlite3_int64 *);
int(*xSetSystemCall)(sqlite3_vfs *, const char *zName, sqlite3_syscall_ptr);
sqlite3_syscall_ptr(*xGetSystemCall)(sqlite3_vfs *, const char *zName);
const char *(*xNextSystemCall)(sqlite3_vfs *, const char *zName);
};
extern "C" {
SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *);
SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *, int);
SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *);
}
/*
* End of data from sqlite3.h
*/
//#define VERBOSE 1
#if VERBOSE
extern int sceClibPrintf(const char *format, ...);
#define LOG sceClibPrintf
#else
#define LOG(...)
#define DEBUG(...)
#endif
#define IS_ERROR(x) ((unsigned)x & 0x80000000)
typedef struct VITAFile {
sqlite3_file base = {0};
SceUID file = 0;
} VITAFile;
namespace SQLite {
static sqlite3_io_methods *rw_methods = nullptr;
static sqlite3_vfs *rw_vfs = nullptr;
// Internal file structure used by Sony's VFS
typedef struct {
sqlite3_file file;
SceUID *fd;
} vfs_file;
static int Write(sqlite3_file *file, const void *buf, int count, sqlite_int64 offset) {
vfs_file *p = reinterpret_cast<vfs_file *>(file);
int seek = sceIoLseek(*p->fd, offset, SCE_SEEK_SET);
/* Incomplete impl of sqlite3_vfs heavily based on https://github.com/alpakeno/vita-savemgr/blob/master/src/vita_sqlite.c
with minor changes, (C++ style casting, usage of sceClib etc)
Based on sqlite version-3.37.1 with -DSQLITE_OS_OTHER=1 -DSQLITE_TEMP_STORE=3 -DSQLITE_THREADSAFE=0 -DDSQLITE_OMIT_WAL
TODO: Use https://github.com/sqlite/sqlite/blob/master/src/test_vfs.c as a template
*/
namespace VITAVFS {
static int xClose(sqlite3_file *file) {
VITAFile *ptr = reinterpret_cast<VITAFile*>(file);
LOG("seek %08x %x => %x\n", *p->fd, offset, seek);
if (seek != offset)
return SQLITE_IOERR_WRITE;
int write = sceIoWrite(*p->fd, buf, count);
LOG("write %08x %08x %x => %x\n", *p->fd, buf, count, write);
if (write != count) {
LOG("write error %08x\n", write);
return SQLITE_IOERR_WRITE;
}
sceIoClose(ptr->file);
DEBUG("close %x\n", ptr->file);
return SQLITE_OK;
}
static int Sync(sqlite3_file *file, int flags) {
vfs_file *p = reinterpret_cast<vfs_file *>(file);
int ret = sceIoSyncByFd(*p->fd, 0);
static int xRead(sqlite3_file *file, void *zBuf, int iAmt, sqlite_int64 iOfst) {
VITAFile *ptr = reinterpret_cast<VITAFile*>(file);
LOG("sync %x, %x => %x\n", *p->fd, flags, r);
sceClibMemset(zBuf, 0, iAmt);
sceIoLseek(ptr->file, iOfst, SCE_SEEK_SET);
int read = sceIoRead(ptr->file, zBuf, iAmt);
DEBUG("read %x %x %x => %x\n", ptr->file, zBuf, iAmt, read);
if (IS_ERROR(ret))
return SQLITE_IOERR_FSYNC;
return SQLITE_OK;
}
static int Open(sqlite3_vfs *vfs, const char *name, sqlite3_file *file, int flags, int *out_flags) {
// sqlite can call open with a NULL name, we need to create a temporary file then
char tempbuf[] = "ux0:data/sqlite-tmp-XXXXXX";
if (name == nullptr)
mkstemp(tempbuf);
sqlite3_vfs *org_vfs = reinterpret_cast<sqlite3_vfs *>(vfs->pAppData);
LOG("open %s: flags = %08x, ", (name == nullptr)? tempbuf : name, flags);
// Default xOpen() does not create files => do that ourselves
// TODO: handle SQLITE_OPEN_EXCLUSIVE
if (flags & SQLITE_OPEN_CREATE) {
SceUID fd = sceIoOpen((name == nullptr)? tempbuf : name, SCE_O_RDONLY, 0777);
if (IS_ERROR(fd))
fd = sceIoOpen((name == nullptr)? tempbuf : name, SCE_O_WRONLY | SCE_O_CREAT, 0777);
if (!IS_ERROR(fd))
sceIoClose(fd);
else
LOG("create error: %08x\n", fd);
}
// Call the original xOpen()
int ret = org_vfs->xOpen(org_vfs, (name == nullptr)? tempbuf : name, file, flags, out_flags);
vfs_file *p = reinterpret_cast<vfs_file *>(file);
LOG("fd = %08x, r = %d\n", (p == nullptr) ? 0 : *p->fd, r);
// Default xOpen() also forces read-only on SQLITE_OPEN_READWRITE files
if ((file->pMethods != nullptr) && (flags & SQLITE_OPEN_READWRITE)) {
if (!IS_ERROR(*p->fd)) {
// Reopen the file with write access
sceIoClose(*p->fd);
*p->fd = sceIoOpen((name == nullptr)? tempbuf : name, SCE_O_RDWR, 0777);
LOG("override fd = %08x\n", *p->fd);
if (IS_ERROR(*p->fd))
return SQLITE_IOERR_WRITE;
}
// Need to override xWrite() and xSync() as well
if (rw_methods == nullptr) {
rw_methods = static_cast<sqlite3_io_methods *>(std::malloc(sizeof(sqlite3_io_methods)));
if (rw_methods != nullptr) {
sceClibMemcpy(rw_methods, file->pMethods, sizeof(sqlite3_io_methods));
rw_methods->xWrite = SQLite::Write;
rw_methods->xSync = SQLite::Sync;
}
}
if (rw_methods != nullptr)
file->pMethods = rw_methods;
}
return ret;
}
static int Delete(sqlite3_vfs *vfs, const char *name, int syncDir) {
int ret = sceIoRemove(name);
LOG("delete %s: 0x%08x\n", name, ret);
if (IS_ERROR(ret))
return SQLITE_IOERR_DELETE;
return SQLITE_OK;
}
int Init(void) {
int ret = SQLITE_OK;
if (rw_vfs != nullptr)
if (read == iAmt)
return SQLITE_OK;
else if (read >= 0)
return SQLITE_IOERR_SHORT_READ;
SceSqliteMallocMethods mf = {
(void* (*) (int)) std::malloc,
(void* (*) (void*, int)) std::realloc,
std::free
return SQLITE_IOERR_READ;
}
static int xWrite(sqlite3_file *file, const void *zBuf, int iAmt, sqlite_int64 iOfst) {
VITAFile *ptr = reinterpret_cast<VITAFile*>(file);
int ofst = sceIoLseek(ptr->file, iOfst, SCE_SEEK_SET);
DEBUG("seek %x %x => %x\n", ptr->file, iOfst, ofst);
if (ofst != iOfst)
return SQLITE_IOERR_WRITE;
int write = sceIoWrite(ptr->file, zBuf, iAmt);
DEBUG("write %x %x %x => %x\n", ptr->file, zBuf, iAmt);
if (write != iAmt)
return SQLITE_IOERR_WRITE;
return SQLITE_OK;
}
static int xTruncate(sqlite3_file *file, sqlite_int64 size) {
DEBUG("truncate\n");
return SQLITE_OK;
}
static int xSync(sqlite3_file *file, int flags) {
return SQLITE_OK;
}
static int xFileSize(sqlite3_file *file, sqlite_int64 *pSize) {
VITAFile *ptr = reinterpret_cast<VITAFile*>(file);
SceIoStat stat = {0};
sceIoGetstatByFd(ptr->file, &stat);
DEBUG("filesize %x => %x\n", ptr->file, stat.st_size);
*pSize = stat.st_size;
return SQLITE_OK;
}
static int xLock(sqlite3_file *file, int eLock) {
return SQLITE_OK;
}
static int xUnlock(sqlite3_file *file, int eLock) {
return SQLITE_OK;
}
static int xCheckReservedLock(sqlite3_file *file, int *pResOut) {
*pResOut = 0;
return SQLITE_OK;
}
static int xFileControl(sqlite3_file *file, int op, void *pArg) {
return SQLITE_OK;
}
static int xSectorSize(sqlite3_file *file) {
return 0;
}
static int xDeviceCharacteristics(sqlite3_file *file) {
return 0;
}
static int xOpen(sqlite3_vfs *vfs, const char *name, sqlite3_file *file, int flags, int *outFlags) {
static const sqlite3_io_methods vitaio = {
1,
VITAVFS::xClose,
VITAVFS::xRead,
VITAVFS::xWrite,
VITAVFS::xTruncate,
VITAVFS::xSync,
VITAVFS::xFileSize,
VITAVFS::xLock,
VITAVFS::xUnlock,
VITAVFS::xCheckReservedLock,
VITAVFS::xFileControl,
VITAVFS::xSectorSize,
VITAVFS::xDeviceCharacteristics,
};
sceSqliteConfigMallocMethods(&mf);
rw_vfs = static_cast<sqlite3_vfs *>(std::malloc(sizeof(sqlite3_vfs)));
sqlite3_vfs *vfs = sqlite3_vfs_find(nullptr);
VITAFile *ptr = reinterpret_cast<VITAFile*>(file);
unsigned int oflags = 0;
if ((vfs != nullptr) && (rw_vfs != nullptr)) {
// Override xOpen() and xDelete()
sceClibMemcpy(rw_vfs, vfs, sizeof(sqlite3_vfs));
rw_vfs->zName = "psp2_rw";
rw_vfs->xOpen = SQLite::Open;
rw_vfs->xDelete = SQLite::Delete;
// Keep a copy of the original VFS pointer
rw_vfs->pAppData = vfs;
ret = sqlite3_vfs_register(rw_vfs, 1);
if (flags & SQLITE_OPEN_EXCLUSIVE)
oflags |= SCE_O_EXCL;
if (flags & SQLITE_OPEN_CREATE)
oflags |= SCE_O_CREAT;
if (flags & SQLITE_OPEN_READONLY)
oflags |= SCE_O_RDONLY;
if (flags & SQLITE_OPEN_READWRITE)
oflags |= SCE_O_RDWR;
if (ret != SQLITE_OK) {
LOG("sqlite_rw_init: could not register vfs: %d\n", ret);
return ret;
}
}
// TODO(xyz): sqlite tries to open inexistant journal and then tries to read from it, wtf?
// so force O_CREAT here
if (flags & SQLITE_OPEN_MAIN_JOURNAL && !(flags & SQLITE_OPEN_EXCLUSIVE))
oflags |= SCE_O_CREAT;
sceClibMemset(ptr, 0, sizeof(*ptr));
ptr->file = sceIoOpen(name, oflags, 7);
DEBUG("open %s %x orig flags %x => %x\n", name, oflags, flags, ptr->file);
if (ptr->file < 0)
return SQLITE_CANTOPEN;
if (outFlags)
*outFlags = flags;
ptr->base.pMethods = &vitaio;
return SQLITE_OK;
}
int xDelete(sqlite3_vfs *vfs, const char *name, int syncDir) {
int ret = sceIoRemove(name);
if (ret < 0)
return SQLITE_IOERR_DELETE;
return SQLITE_OK;
}
int xAccess(sqlite3_vfs *vfs, const char *name, int flags, int *pResOut) {
*pResOut = 1;
return SQLITE_OK;
}
int xFullPathname(sqlite3_vfs *vfs, const char *zName, int nOut, char *zOut) {
sceClibSnprintf(zOut, nOut, "%s", zName);
return 0;
}
void* xDlOpen(sqlite3_vfs *vfs, const char *zFilename) {
return nullptr;
}
void xDlError(sqlite3_vfs *vfs, int nByte, char *zErrMsg) {
}
void (*xDlSym(sqlite3_vfs *vfs,void*p, const char *zSymbol))(void) {
return nullptr;
}
void xDlClose(sqlite3_vfs *vfs, void*p) {
int Exit(void) {
int ret = SQLITE_OK;
std::free(rw_methods);
rw_methods = nullptr;
if (rw_vfs != nullptr) {
ret = sqlite3_vfs_unregister(rw_vfs);
if (ret != SQLITE_OK)
LOG("sqlite_rw_exit: error unregistering vfs: %d\n", ret);
std::free(rw_vfs);
rw_vfs = nullptr;
}
return ret;
}
int xRandomness(sqlite3_vfs *vfs, int nByte, char *zOut) {
return SQLITE_OK;
}
int xSleep(sqlite3_vfs *vfs, int microseconds) {
sceKernelDelayThread(microseconds);
return SQLITE_OK;
}
int xCurrentTime(sqlite3_vfs *vfs, double *pTime) {
time_t t = 0;
SceDateTime time = {0};
sceRtcGetCurrentClock(&time, 0);
sceRtcGetTime_t(&time, &t);
*pTime = t/86400.0 + 2440587.5;
return SQLITE_OK;
}
int xGetLastError(sqlite3_vfs *vfs, int e, char *err) {
return 0;
}
}
sqlite3_vfs vita_vfs = {
.iVersion = 1,
.szOsFile = sizeof(VITAFile),
.mxPathname = 0x100,
.pNext = nullptr,
.zName = "psp2",
.pAppData = nullptr,
.xOpen = VITAVFS::xOpen,
.xDelete = VITAVFS::xDelete,
.xAccess = VITAVFS::xAccess,
.xFullPathname = VITAVFS::xFullPathname,
.xDlOpen = VITAVFS::xDlOpen,
.xDlError = VITAVFS::xDlError,
.xDlSym = VITAVFS::xDlSym,
.xDlClose = VITAVFS::xDlClose,
.xRandomness = VITAVFS::xRandomness,
.xSleep = VITAVFS::xSleep,
.xCurrentTime = VITAVFS::xCurrentTime,
.xGetLastError = VITAVFS::xGetLastError,
};
int sqlite3_os_init(void) {
sqlite3_vfs_register(&vita_vfs, 1);
return 0;
}
int sqlite3_os_end(void) {
return 0;
}