library,
link,
defines;
+ bool no_lto;
};
enum obj_type
"-fstack-protector-strong " );
}
- /* always want this */
- vg_strcat( &cmd, " -flto \\\n" );
+ vg_strcat( &cmd, conf->no_lto? " -fno-lto \\\n": " -flto \\\n" );
/* want a lot of warnings but not useless ones */
vg_strcat( &cmd, " -Wall -ferror-limit=10\\\n"
vg_strcat( &cmd, architecture_names[env->arch] );
vg_strcat( &cmd, "-" );
vg_strcat( &cmd, platform_names[env->platform] );
- vg_strcat( &cmd, " -fno-sanitize=undefined " );
if( env->platform == k_platform_linux )
{
vg_strcat( &cmd, " /SUBSYSTEM:windows" );
}
}
+
+ vg_strcat( &cmd, " -fno-sanitize=undefined " );
+ vg_strcat( &cmd, " -fkeep-static-consts -fkeep-persistent-storage-variables " );
}
vg_syscall( cmd.buffer );
//denv.optimization = 3;
/* external dependencies */
- struct compile_result depencies =
- vg_compiler_run( &vg_proj, &denv, conf, "vg/vg_depencies.c",
- "vg_deps", k_obj_type_obj );
+ struct compile_result depencies = vg_compiler_run( &vg_proj, &denv, conf, "vg/vg_depencies.c",
+ "vg_deps", k_obj_type_obj );
vg_strcatf( &components, "%s ", depencies.path );
/* glad */
- struct compile_result glad =
- vg_compiler_run( &vg_proj, &denv, conf, "vg/dep/glad/glad.c",
- "vg_glad", k_obj_type_obj );
+ struct compile_result glad = vg_compiler_run( &vg_proj, &denv, conf, "vg/dep/glad/glad.c",
+ "vg_glad", k_obj_type_obj );
vg_strcatf( &components, "%s ", glad.path );
/* core engine */
- struct compile_result vg =
- vg_compiler_run( &vg_proj, &denv, conf, "vg/vg_engine.c",
- "vg_engine_core", k_obj_type_obj );
+ struct compile_result vg = vg_compiler_run( &vg_proj, &denv, conf, "vg/vg_engine.c",
+ "vg_engine_core", k_obj_type_obj );
vg_strcatf( &components, "%s ", vg.path );
/* steamworks */
#include <stddef.h>
#include <stdarg.h>
+static void vg_db_touch( vg_db *db, u16 cache_id );
+
/* util
* ------------------------------------------------------------------------------------------------------------------ */
if( fseek( fwal, 0, SEEK_SET ) )
{
+ free( temp_page );
vg_warn( "WAL file was empty (assuming db is atomic)\n" );
return;
}
vg_db_wal log;
if( !fread( &log, sizeof(log), 1, fwal ) )
{
+ free( temp_page );
vg_warn( "No checkpoints in WAL file (assuming db is atomic)\n" );
return;
}
db->fp = fopen( path, "wb+" );
if( !db->fp )
vg_db_abort( db, "fopen(wb+) failed for '%s'\n", path );
- vg_db_allocate_physical_page( db ); // Allocate header as 0
- vg_db_write( db, offsetof(vg_db_header,ident), &k_ident, 4 );
+
+ vg_db_header init = {0};
+ init.ident = k_ident;
+ init._end = k_ident;
+ init.physical_size = VG_PAGE_SIZE;
+ if( !fwrite( &init, sizeof(init), 1, db->fp ) )
+ vg_db_abort( db, "fwrite header failed'\n" );
+
+ /* Sit it into the cache */
+ u16 cache_id = ++db->cache_count;
+ vg_db_page *page = &db->page_cache[ cache_id-1 ];
+ memset( page, 0, sizeof(vg_db_page) );
+ u64 page_base = 0;
+ u32 hash = vg_dbhash( (void *)(&page_base), sizeof(page_base) ) & (VG_PAGE_CACHE_HASH_WIDTH-1u);
+ db->hash_table[ hash ] = cache_id;
+ vg_db_touch( db, cache_id );
+ page->virtual_id = page_base;
+ page->physical_offset = page_base;
+ page->unwritten = 0;
+ memcpy( db->page_data, &init, sizeof(init) );
+
db->userdata_address = vg_db_virtual_allocate( db, VG_1GB );
+
+ db->unprotect0 ++;
vg_db_write( db, offsetof(vg_db_header,userdata_address), &db->userdata_address, 8 );
vg_db_tree_init( db, offsetof(vg_db_header,address_tree) );
+ db->unprotect0 --;
+
vg_db_checkpoint( db );
}
}
static u64 vg_db_allocate_physical_page( vg_db *db )
{
- if( fseek( db->fp, 0, SEEK_END ) )
- vg_db_abort( db, "SEEK_END(0) failed\n" );
- u64 zero = 0;
- for( u64 i=0; i<VG_PAGE_SIZE/8; i ++ )
- if( !fwrite( &zero, 8, 1, db->fp ) )
- vg_db_abort( db, "fwrite failed\n" );
- return ftell( db->fp ) - VG_PAGE_SIZE;
+ u64 physical_size, address;
+ vg_db_read( db, 0x0lu + offsetof(vg_db_header,physical_size), &physical_size, sizeof(physical_size) );
+ address = physical_size;
+ physical_size += VG_PAGE_SIZE;
+ db->unprotect0 ++;
+ vg_db_write( db, 0x0lu + offsetof(vg_db_header,physical_size), &physical_size, sizeof(physical_size) );
+ db->unprotect0 --;
+ return address;
}
static void vg_db_sync_page( vg_db *db, u16 cache_id )
if( translated_page_base == 0 )
{
u64 new_page = vg_db_allocate_physical_page( db );
+ db->unprotect0 ++;
vg_db_tree_map( db, tree_address, page_base, new_page );
+ db->unprotect0 --;
translated_page_base = new_page;
}
}
page->unwritten = write;
/* read entire page into memory */
- void *page_data = db->page_data + (u64)(cache_id-1)*VG_PAGE_SIZE;
+ u8 *page_data = (u8 *)(db->page_data + (u64)(cache_id-1)*VG_PAGE_SIZE);
if( fseek( db->fp, translated_page_base, SEEK_SET ) )
vg_db_abort( db, "SEEK_SET (%lx) failed\n", translated_page_base );
- if( !fread( page_data, VG_PAGE_SIZE, 1, db->fp ) )
- vg_db_abort( db, "fread page failed\n" );
+
+ bool eof = 0;
+ for( u32 i=0; i<VG_PAGE_SIZE; i ++ )
+ {
+ if( !eof )
+ {
+ if( !fread( page_data+i, 1, 1, db->fp ) )
+ {
+ if( ferror( db->fp ) )
+ vg_db_abort( db, "fread page failed\n" );
+ else if( feof( db->fp ) )
+ eof = 1;
+ else
+ vg_db_abort( db, "Invalid read condition\n" );
+ }
+ }
+
+ if( eof )
+ page_data[i] = 0;
+ }
+
*out_physical_address = translated_page_base + inner_offset;
return page_data + inner_offset;
}
*user_buffer = buf + (address-base_address);
if( write )
{
+ if( (physical_address < VG_PAGE_SIZE) && !db->unprotect0 )
+ {
+ vg_db_abort( db, "Tried to write to the 0 page while unprotected!\n"
+ " base_address: %llu, length: %u\n", base_address, length );
+ }
+
if( db->fp_wal == NULL )
{
db->fp_wal = fopen( db->wal_path, "wb+" );
+ if( !db->fp_wal )
+ vg_db_abort( db, "Failed to open wal file '%s'\n", db->wal_path );
+
vg_db_wal log = {
.type = k_wal_log_checkpoint,
.previous_log_offset = 0,
u64 pages = (bytes + (VG_PAGE_SIZE-1lu)) >> VG_PAGE_BITS,
addr = page_count * VG_PAGE_SIZE;
page_count += pages;
+ db->unprotect0 ++;
vg_db_write( db,0x0lu + offsetof(vg_db_header,virtual_pages), &page_count, sizeof(page_count) );
+ db->unprotect0 --;
return VG_VIRTUAL_ADDRESS_BIT | addr;
}