int AMXAPI aux_LoadProgramFromMemory(AMX* amx, char* filedata) { AMX_HEADER hdr; memcpy(&hdr, filedata, sizeof hdr); amx_Align16(&hdr.magic); amx_Align32((uint32_t *)&hdr.size); amx_Align32((uint32_t *)&hdr.stp); if (hdr.magic != AMX_MAGIC) { return AMX_ERR_FORMAT; } void* memblock; if ((memblock = malloc(hdr.stp)) == NULL) { return AMX_ERR_MEMORY; } memcpy(memblock, filedata, (size_t)hdr.size); //amx_SetDebugHook(amx, (AMX_DEBUG)amx_Debug); memset(amx, 0, sizeof(*amx)); int result = amx_Init(amx, memblock); if (result != AMX_ERR_NONE) { free(memblock); amx->base = NULL; } return result; }
static void pawnExec( Pawn * pawn ) { chSysLock(); pawn->isRunning = 0; chSysUnlock(); uint32_t i; unsigned char * tmp = (unsigned char *)&pawn->amx; for ( i=0; i<sizeof( pawn->amx ); i++ ) tmp[i] = 0; pawn->amx.data = (uint8_t *)pawn->memblock; uint8_t * rom = (uint8_t *)(PAWN_FLASH_START + PAWN_PAGE_SIZE * PAWN_START_PAGE); pawn->result = amx_Init( &pawn->amx, rom ); if ( pawn->result != AMX_ERR_NONE ) return; static cell ret = 0; chSysLock(); pawn->isRunning = 1; chSysUnlock(); pawn->error = amx_Exec( &pawn->amx, &ret, AMX_EXEC_MAIN ); pawn->result = ret; amx_Cleanup( &pawn->amx ); chSysLock(); pawn->isRunning = 0; chSysUnlock(); }
/* 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, void *memblock, int AMXAPI (*amx_Debug)(AMX*)) { FILE *fp; AMX_HEADER hdr; int result, didalloc; /* 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_Align32((uint32_t *)&hdr.size); amx_Align32((uint32_t *)&hdr.stp); if (hdr.magic != AMX_MAGIC) { fclose(fp); return AMX_ERR_FORMAT; } /* if */ /* allocate the memblock if it is NULL */ didalloc = 0; if (memblock == NULL) { if ((memblock = malloc(hdr.stp)) == NULL) { fclose(fp); return AMX_ERR_MEMORY; } /* if */ didalloc = 1; /* after amx_Init(), amx->base points to the memory block */ } /* if */ /* read in the file */ rewind(fp); fread(memblock, 1, (size_t)hdr.size, fp); fclose(fp); /* initialize the abstract machine */ memset(amx, 0, sizeof *amx); amx_SetDebugHook(amx, amx_Debug); /* set up the debug hook */ result = amx_Init(amx, memblock); /* free the memory block on error, if it was allocated here */ if (result != AMX_ERR_NONE && didalloc) { free(memblock); amx->base = NULL; /* avoid a double free */ } /* if */ return result; }
int aux_LoadProgram(AMX *amx, char *filename, void *memblock) { FILE *fp; AMX_HEADER hdr; if ((fp = fopen(filename, "rb")) == NULL ) return AMX_ERR_NOTFOUND; fread(&hdr, sizeof hdr, 1, fp); amx_Align32((unsigned long *)&hdr.size); rewind(fp); fread(memblock, 1, (size_t)hdr.size, fp); fclose(fp); memset(amx, 0, sizeof *amx); return amx_Init(amx, memblock); }
int AMXAPI aux_LoadProgram(AMX* amx, char* filename) { FILE* fp; if ((fp = fopen(filename, "rb")) == NULL) { return AMX_ERR_NOTFOUND; } AMX_HEADER hdr; fread(&hdr, sizeof hdr, 1, fp); amx_Align16(&hdr.magic); amx_Align32((uint32_t *)&hdr.size); amx_Align32((uint32_t *)&hdr.stp); if (hdr.magic != AMX_MAGIC) { fclose(fp); return AMX_ERR_FORMAT; } void* memblock; if ((memblock = malloc(hdr.stp)) == NULL) { fclose(fp); return AMX_ERR_MEMORY; } rewind(fp); fread(memblock, 1, (size_t)hdr.size, fp); fclose(fp); //amx_SetDebugHook(amx, (AMX_DEBUG)amx_Debug); memset(amx, 0, sizeof(*amx)); int result = amx_Init(amx, memblock); if (result != AMX_ERR_NONE) { free(memblock); amx->base = NULL; } return result; }
/* 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 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;*/ }
int AMXAPI aux_LoadProgram(AMX *amx, const char *filename) { int error; FILE *fp; AMX_HEADER hdr; void *pcode = NULL; void *ncode = NULL; // ncode = new machine code void *rt = NULL; // rt = relocation table (temporary) /* open the file */ error = AMX_ERR_NOTFOUND; /* assume "file not found" */ if ((fp = fopen(filename, "rb")) == NULL) goto fail; /* read the header */ error = AMX_ERR_FORMAT; /* assume "invalid file format" */ fread(&hdr, sizeof hdr, 1, fp); amx_Align16(&hdr.magic); if (hdr.magic != AMX_MAGIC) goto fail; /* allocate memory for the P-code */ error = AMX_ERR_MEMORY; /* assume "insufficient memory" */ amx_Align32((uint32_t *)&hdr.stp); amx_Align32((uint32_t *)&hdr.size); if ((pcode = malloc((size_t)hdr.stp)) == NULL) goto fail; /* read the P-code and initialize the abstract machine */ rewind(fp); fread(pcode, 1, (int)hdr.size, fp); fclose(fp); fp = NULL; memset(amx, 0, sizeof *amx); amx->flags = AMX_FLAG_JITC; if ((error = amx_Init(amx, pcode)) != AMX_ERR_NONE) goto fail; /* Now we have an initialized abstract machine, which is normally immediately * runnable by amx_Exec(). Instead of running the code, we throw it at the * JIT compiler... */ /* allocate memory for the compiled instructions and the temporary * relocation table */ error = AMX_ERR_MEMORY; /* assume "insufficient memory" */ ncode = malloc(amx->code_size);/* amx->code_size is an estimate */ if (ncode == NULL) goto fail; if (amx->reloc_size > 0) { rt = malloc(amx->reloc_size); if (rt == NULL) goto fail; } /* if */ /* JIT rulz! (TM) */ if ((error = amx_InitJIT(amx, rt, ncode)) != AMX_ERR_NONE) goto fail; /* The compiled code is relocatable, since only relative jumps are * used for destinations within the generated code and absoulute * addresses for jumps into the runtime, which is fixed in memory. */ error = AMX_ERR_MEMORY; /* assume "insufficient memory" */ if ((amx->base = vmalloc_exec(amx->code_size)) == NULL) goto fail; memcpy(amx->base, ncode, amx->code_size); free(pcode); free(rt); free(ncode); return AMX_ERR_NONE; fail: if (fp != NULL) fclose(fp); if (pcode != NULL) free(pcode); if (rt != NULL) free(rt); if (ncode != NULL) free(ncode); memset(amx, 0, sizeof *amx); return error; }
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; }