int pawnLoad( Pawn * p, const char * fileName ) { FILE *fp; AMX_HEADER hdr; int result, i; int32_t size; unsigned char * datablock; #define OVLPOOLSIZE 1024 // open the file, read and check the header if ((fp = fopen(fileName, "rb")) == NULL) return AMX_ERR_NOTFOUND; p->fp = fp; fread(&hdr, sizeof hdr, 1, fp); amx_Align16(&hdr.magic); amx_Align16((uint16_t *)&hdr.flags); amx_Align32((uint32_t *)&hdr.size); amx_Align32((uint32_t *)&hdr.cod); amx_Align32((uint32_t *)&hdr.dat); amx_Align32((uint32_t *)&hdr.hea); amx_Align32((uint32_t *)&hdr.stp); if (hdr.magic != AMX_MAGIC) { fclose(fp); return AMX_ERR_FORMAT; } // if if ((hdr.flags & AMX_FLAG_OVERLAY) != 0) // allocate the block for the data + stack/heap, plus the complete file // header, plus the overlay pool size = (hdr.stp - hdr.dat) + hdr.cod + POOL_SZ; else size = hdr.stp; if( size > (STACK_SZ + POOL_SZ) ) { fclose(fp); return AMX_ERR_MEMORY; } datablock = p->datablock; p->header = datablock; p->stack = datablock + hdr.cod; p->pool = datablock + hdr.cod + (hdr.stp - hdr.dat); // save the filename, for optionally reading the debug information (we could // also have read it here immediately); for reading overlays, we also need // the filename (and in this case, note that amx_Init() already browses // through all overlays) // read in the file, in two parts; first the header and then the data section rewind(fp); if ((hdr.flags & AMX_FLAG_OVERLAY) != 0) { // read the entire header fread(datablock, 1, hdr.cod, fp); // read the data section, put it behind the header in the block fseek(fp, hdr.dat, SEEK_SET); fread(datablock + hdr.cod, 1, hdr.hea - hdr.dat, fp); // initialize the overlay pool amx_poolinit(datablock + (hdr.stp - hdr.dat) + hdr.cod, OVLPOOLSIZE); } else { fread(datablock, 1, (size_t)hdr.size, fp); } // if //fclose(fp); // initialize the abstract machine for ( i=0; i<sizeof(p->amx); i++ ) ((unsigned char *)&p->amx)[i] = 0; if ((hdr.flags & AMX_FLAG_OVERLAY) != 0) { p->amx.data = datablock + hdr.cod; p->amx.overlay = prun_Overlay; } else { fread(datablock, 1, (size_t)hdr.size, fp); } result = amx_Init( &p->amx, datablock); // free the memory block on error, if it was allocated here if (result != AMX_ERR_NONE) { p->amx.base = NULL; // avoid a double free } // if return result; /*AMX_HEADER hdr; int i; if ( !(p->fp = fopen( fileName, "rb" ) ) ) return PAWN_ERR_FILE_OPEN; g_fp = p->fp; fread( &hdr, sizeof(hdr), 1, p->fp ); amx_Align16( &hdr.magic ); amx_Align16((uint16_t *)&hdr.flags); amx_Align32((uint32_t *)&hdr.size); amx_Align32((uint32_t *)&hdr.cod); amx_Align32((uint32_t *)&hdr.dat); amx_Align32((uint32_t *)&hdr.hea); amx_Align32((uint32_t *)&hdr.stp); if ( hdr.magic != AMX_MAGIC ) { fclose( p->fp ); return PAWN_ERR_FORMAT; } rewind( p->fp ); fread( p->header, 1, hdr.cod, p->fp ); fseek( p->fp, hdr.dat, SEEK_SET ); fread( p->stack, 1, hdr.hea - hdr.dat, p->fp ); amx_poolinit( p->pool, POOL_SZ ); for ( i=0; i<sizeof(p->amx); i++ ) ((unsigned char *)&p->amx)[i] = 0; p->amx.data = p->stack; p->amx.overlay = prun_Overlay; i = amx_Init( &p->amx, p->header ); return ( i == AMX_ERR_NONE ) ? PAWN_OK : PAWN_ERR_INIT;*/ }
/* aux_LoadProgram() * Load a compiled Pawn script into memory and initialize the abstract machine. * This function is extracted out of AMXAUX.C. */ int AMXAPI aux_LoadProgram(AMX *amx, char *filename) { FILE *fp; AMX_HEADER hdr; int result; int32_t size; unsigned char *datablock; #define OVLPOOLSIZE 4096 /* open the file, read and check the header */ if ((fp = fopen(filename, "rb")) == NULL) return AMX_ERR_NOTFOUND; fread(&hdr, sizeof hdr, 1, fp); amx_Align16(&hdr.magic); amx_Align16((uint16_t *)&hdr.flags); amx_Align32((uint32_t *)&hdr.size); amx_Align32((uint32_t *)&hdr.cod); amx_Align32((uint32_t *)&hdr.dat); amx_Align32((uint32_t *)&hdr.hea); amx_Align32((uint32_t *)&hdr.stp); if (hdr.magic != AMX_MAGIC) { fclose(fp); return AMX_ERR_FORMAT; } /* if */ if ((hdr.flags & AMX_FLAG_OVERLAY) != 0) { /* allocate the block for the data + stack/heap, plus the complete file * header, plus the overlay pool */ #if defined AMXOVL size = (hdr.stp - hdr.dat) + hdr.cod + OVLPOOLSIZE; #else return AMX_ERR_OVERLAY; #endif } else { size = hdr.stp; } /* if */ if ((datablock = malloc(size)) == NULL) { fclose(fp); return AMX_ERR_MEMORY; } /* if */ /* save the filename, for optionally reading the debug information (we could * also have read it here immediately); for reading overlays, we also need * the filename (and in this case, note that amx_Init() already browses * through all overlays) */ strcpy(g_filename, filename); /* read in the file, in two parts; first the header and then the data section */ rewind(fp); if ((hdr.flags & AMX_FLAG_OVERLAY) != 0) { #if defined AMXOVL /* read the entire header */ fread(datablock, 1, hdr.cod, fp); /* read the data section, put it behind the header in the block */ fseek(fp, hdr.dat, SEEK_SET); fread(datablock + hdr.cod, 1, hdr.hea - hdr.dat, fp); /* initialize the overlay pool */ amx_poolinit(datablock + (hdr.stp - hdr.dat) + hdr.cod, OVLPOOLSIZE); #endif } else { fread(datablock, 1, (size_t)hdr.size, fp); } /* if */ fclose(fp); /* initialize the abstract machine */ memset(amx, 0, sizeof *amx); #if defined AMXOVL if ((hdr.flags & AMX_FLAG_OVERLAY) != 0) { amx->data = datablock + hdr.cod; amx->overlay = prun_Overlay; } /* if */ #endif result = amx_Init(amx, datablock); /* free the memory block on error, if it was allocated here */ if (result != AMX_ERR_NONE) { free(datablock); amx->base = NULL; /* avoid a double free */ } /* if */ return result; }
int loadprogram(const char *filename, char *error, size_t error_size) { FIL *file = &amx_file; FRESULT status = f_open(file, filename, FA_READ); if (status != FR_OK) { snprintf(error, error_size, "Could not open file %s: %d", filename, status); return AMX_ERR_NOTFOUND; } /* Read file header */ memset(&amx, 0, sizeof(amx)); AMX_HEADER hdr; UINT read_count; f_read(file, &hdr, sizeof hdr, &read_count); if (read_count != sizeof hdr || hdr.magic != AMX_MAGIC) return AMX_ERR_FORMAT; if (hdr.flags & AMX_FLAG_OVERLAY) { // Read the header f_lseek(file, 0); f_read(file, vm_data, hdr.cod, &read_count); // Read the data block f_lseek(file, hdr.dat); unsigned dat_size = hdr.hea - hdr.dat; f_read(file, vm_data + hdr.cod, dat_size, &read_count); if (read_count != dat_size) return AMX_ERR_FORMAT; unsigned static_size = (hdr.stp - hdr.dat) + hdr.cod; amx_poolinit(vm_data + static_size, sizeof(vm_data) - static_size); amx.base = vm_data; amx.data = vm_data + hdr.cod; overlay_init(&amx, amx_filename, &amx_file); } else { if (hdr.stp > sizeof(vm_data)) return AMX_ERR_MEMORY; /* Read the actual file, including the header (again) */ f_lseek(file, 0); f_read(file, vm_data, hdr.size, &read_count); if (read_count != hdr.size) return AMX_ERR_FORMAT; } AMXERRORS(amx_Init(&amx, vm_data)); amxinit_display(&amx); amx_CoreInit(&amx); amxinit_string(&amx); amxinit_fixed(&amx); amxinit_wavein(&amx); amxinit_waveout(&amx); amxinit_menu(&amx); amxinit_file(&amx); amxinit_buttons(&amx); amxinit_fourier(&amx); amxinit_time(&amx); amxinit_device(&amx); amxinit_fpga(&amx); // Check that everything has been registered int regstat = amx_Register(&amx, NULL, -1); if (regstat != 0) { // Find out what is missing for (int i = 0; i < NUMENTRIES((AMX_HEADER*)amx.base,natives,libraries); i++) { AMX_FUNCSTUB *func = GETENTRY((AMX_HEADER*)amx.base,natives,i); if (func->address == 0) { snprintf(error, error_size, "Native function not found: %s", GETENTRYNAME((AMX_HEADER*)amx.base,func)); return AMX_ERR_NOTFOUND; } } snprintf(error, error_size, "Error registering native functions"); return regstat; } return 0; }