Beispiel #1
0
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;
}
Beispiel #2
0
/* 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;
}
Beispiel #3
0
//As of Small 3.0, there's extra debug info in the file we need to get out.
//Sadly this is placed somewhere really inconvenient and I'm mad.
void ReadFileIntoPl(abl *pl, FILE *fp)
{
	AMX_HEADER hdr;
	AMX_DBG_HDR dbg;
	fread(&hdr, sizeof(hdr), 1, fp);
	amx_Align32((uint32_t *)&hdr.stp);
	amx_Align32((uint32_t *)&hdr.size);
	pl->stp = hdr.stp;
	int size = hdr.size;
	if (hdr.flags & AMX_FLAG_DEBUG)
	{
		fseek(fp, hdr.size, SEEK_SET);
		fread(&dbg, sizeof(dbg), 1, fp);
		size += dbg.size;
	}
	pl->size = size;
	pl->data = new char[size];
	rewind(fp);
	fread(pl->data, 1, size, fp);
}
Beispiel #4
0
size_t aux_ProgramSize(char *filename)
{
  FILE *fp;
  AMX_HEADER hdr;

  if ((fp=fopen(filename,"rb")) == NULL)
    return 0;
  fread(&hdr, sizeof hdr, 1, fp);
  fclose(fp);
  amx_Align32((uint32_t*)&hdr.stp);
  return hdr.stp;
}
Beispiel #5
0
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;
}
size_t aux_ProgramSize(char *filename)
{
  FILE *fp;
  AMX_HEADER hdr;

  if ((fp=fopen(filename,"rb")) == NULL)
    return 0;
  fread(&hdr, sizeof hdr, 1, fp);
  fclose(fp);

  amx_Align16(&hdr.magic);
  amx_Align32((unsigned long*)&hdr.stp);
  return (hdr.magic==AMX_MAGIC) ? (size_t)hdr.stp : 0;
}
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);
}
Beispiel #8
0
/* 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;
}
Beispiel #9
0
int AMXAPI dbg_LoadInfo(AMX_DBG *amxdbg, FILE *fp)
{
  AMX_HEADER amxhdr;
  AMX_DBG_HDR dbghdr;
  size_t size;
  unsigned char *ptr;
  int index, dim;
  AMX_DBG_LINE *line;
  AMX_DBG_SYMDIM *symdim;

  assert(fp != NULL);
  assert(amxdbg != NULL);

  memset(&amxhdr, 0, sizeof amxhdr);
  fseek(fp, 0L, SEEK_SET);
  if (fread(&amxhdr, sizeof amxhdr, 1, fp) == 0)
    return AMX_ERR_FORMAT;
  #if BYTE_ORDER==BIG_ENDIAN
    amx_Align32((uint32_t*)&amxhdr.size);
    amx_Align16(&amxhdr.magic);
    amx_Align16(&dbghdr.flags);
  #endif
  if (amxhdr.magic != AMX_MAGIC)
    return AMX_ERR_FORMAT;
  if ((amxhdr.flags & AMX_FLAG_DEBUG) == 0)
    return AMX_ERR_DEBUG;

  fseek(fp, amxhdr.size, SEEK_SET);
  memset(&dbghdr, 0, sizeof(AMX_DBG_HDR));
  if (fread(&dbghdr, sizeof(AMX_DBG_HDR), 1, fp) == 0)
    return AMX_ERR_FORMAT;

  #if BYTE_ORDER==BIG_ENDIAN
    amx_Align32((uint32_t*)&dbghdr.size);
    amx_Align16(&dbghdr.magic);
    amx_Align16(&dbghdr.flags);
    amx_Align16(&dbghdr.files);
    amx_Align16(&dbghdr.lines);
    amx_Align16(&dbghdr.symbols);
    amx_Align16(&dbghdr.tags);
    amx_Align16(&dbghdr.automatons);
    amx_Align16(&dbghdr.states);
  #endif
  if (dbghdr.magic != AMX_DBG_MAGIC)
    return AMX_ERR_FORMAT;

  /* allocate all memory */
  memset(amxdbg, 0, sizeof(AMX_DBG));
  amxdbg->hdr = malloc((size_t)dbghdr.size);
  if (dbghdr.files > 0)
    amxdbg->filetbl = malloc(dbghdr.files * sizeof(AMX_DBG_FILE *));
  if (dbghdr.symbols > 0)
    amxdbg->symboltbl = malloc(dbghdr.symbols * sizeof(AMX_DBG_SYMBOL *));
  if (dbghdr.tags > 0)
    amxdbg->tagtbl = malloc(dbghdr.tags * sizeof(AMX_DBG_TAG *));
  if (dbghdr.automatons > 0)
    amxdbg->automatontbl = malloc(dbghdr.automatons * sizeof(AMX_DBG_MACHINE *));
  if (dbghdr.states > 0)
    amxdbg->statetbl = malloc(dbghdr.states * sizeof(AMX_DBG_STATE *));
  if (amxdbg->hdr == NULL
      || (dbghdr.files > 0 && amxdbg->filetbl == NULL)
      || (dbghdr.symbols > 0 && amxdbg->symboltbl == NULL)
      || (dbghdr.tags > 0 && amxdbg->tagtbl == NULL)
      || (dbghdr.states > 0 && amxdbg->statetbl == NULL)
      || (dbghdr.automatons > 0 && amxdbg->automatontbl == NULL))
  {
    dbg_FreeInfo(amxdbg);
    return AMX_ERR_MEMORY;
  } /* if */

  /* load the entire symbolic information block into memory */
  memcpy(amxdbg->hdr, &dbghdr, sizeof dbghdr);
  size=(size_t)(dbghdr.size - sizeof dbghdr);
  if (fread(amxdbg->hdr + 1, 1, size, fp) < size) {
    dbg_FreeInfo(amxdbg);
    return AMX_ERR_FORMAT;
  } /* if */

  /* run through the file, fix alignment issues and set up table pointers */
  ptr = (unsigned char *)(amxdbg->hdr + 1);

  /* file table */
  for (index = 0; index < dbghdr.files; index++) {
    assert(amxdbg->filetbl != NULL);
    amxdbg->filetbl[index] = (AMX_DBG_FILE *)ptr;
    #if BYTE_ORDER==BIG_ENDIAN
      amx_AlignCell(&amxdbg->filetbl[index]->address);
    #endif
    for (ptr = ptr + sizeof(AMX_DBG_FILE); *ptr != '\0'; ptr++)
      /* nothing */;
    ptr++;              /* skip '\0' too */
  } /* for */

  /* line table */
  amxdbg->linetbl = (AMX_DBG_LINE*)ptr;
  #if BYTE_ORDER==BIG_ENDIAN
    for (index = 0; index < dbghdr.lines; index++) {
      amx_AlignCell(&amxdbg->linetbl[index].address);
      amx_Align32((uint32_t*)&amxdbg->linetbl[index].line);
    } /* for */
  #endif
  ptr += (uint16_t)dbghdr.lines * sizeof(AMX_DBG_LINE);

  /* detect dbghdr.lines overflow */
  while ((line = (AMX_DBG_LINE *)ptr)
         && (cell)line->address > (cell)(line - 1)->address) {
    #if BYTE_ORDER==BIG_ENDIAN
      for (index = 0; index <= (uint32_t)(1u << 16) - 1; index++) {
        amx_AlignCell(&linetbl[index].address);
        amx_Align32((uint32_t*)&linetbl[index].line);
        line++;
      } /* for */
    #endif
    ptr += (uint32_t)(1u << 16) * sizeof(AMX_DBG_LINE);
  } /* while */

  /* symbol table (plus index tags) */
  for (index = 0; index < dbghdr.symbols; index++) {
    assert(amxdbg->symboltbl != NULL);
    amxdbg->symboltbl[index] = (AMX_DBG_SYMBOL *)ptr;
    #if BYTE_ORDER==BIG_ENDIAN
      amx_AlignCell(&amxdbg->symboltbl[index]->address);
      amx_Align16((uint16_t*)&amxdbg->symboltbl[index]->tag);
      amx_AlignCell(&amxdbg->symboltbl[index]->codestart);
      amx_AlignCell(&amxdbg->symboltbl[index]->codeend);
      amx_Align16((uint16_t*)&amxdbg->symboltbl[index]->dim);
    #endif
    for (ptr = ptr + sizeof(AMX_DBG_SYMBOL); *ptr != '\0'; ptr++)
      /* nothing */;
    ptr++;              /* skip '\0' too */
    for (dim = 0; dim < amxdbg->symboltbl[index]->dim; dim++) {
      symdim = (AMX_DBG_SYMDIM *)ptr;
      amx_Align16((uint16_t*)&symdim->tag);
      amx_AlignCell(&symdim->size);
      ptr += sizeof(AMX_DBG_SYMDIM);
    } /* for */
  } /* for */

  /* tag name table */
  for (index = 0; index < dbghdr.tags; index++) {
    assert(amxdbg->tagtbl != NULL);
    amxdbg->tagtbl[index] = (AMX_DBG_TAG *)ptr;
    #if BYTE_ORDER==BIG_ENDIAN
      amx_Align16(&amxdbg->tagtbl[index]->tag);
    #endif
    for (ptr = ptr + sizeof(AMX_DBG_TAG) - 1; *ptr != '\0'; ptr++)
      /* nothing */;
    ptr++;              /* skip '\0' too */
  } /* for */

  /* automaton name table */
  for (index = 0; index < dbghdr.automatons; index++) {
    assert(amxdbg->automatontbl != NULL);
    amxdbg->automatontbl[index] = (AMX_DBG_MACHINE *)ptr;
    #if BYTE_ORDER==BIG_ENDIAN
      amx_Align16(&amxdbg->automatontbl[index]->automaton);
      amx_AlignCell(&amxdbg->automatontbl[index]->address);
    #endif
    for (ptr = ptr + sizeof(AMX_DBG_MACHINE) - 1; *ptr != '\0'; ptr++)
      /* nothing */;
    ptr++;              /* skip '\0' too */
  } /* for */

  /* state name table */
  for (index = 0; index < dbghdr.states; index++) {
    assert(amxdbg->statetbl != NULL);
    amxdbg->statetbl[index] = (AMX_DBG_STATE *)ptr;
    #if BYTE_ORDER==BIG_ENDIAN
      amx_Align16(&amxdbg->statetbl[index]->state);
      amx_Align16(&amxdbg->automatontbl[index]->automaton);
    #endif
    for (ptr = ptr + sizeof(AMX_DBG_STATE) - 1; *ptr != '\0'; ptr++)
      /* nothing */;
    ptr++;              /* skip '\0' too */
  } /* for */

  return AMX_ERR_NONE;
}
Beispiel #10
0
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;*/
}
Beispiel #11
0
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;
}
Beispiel #12
0
void CPluginMngr::CacheAndLoadModules(const char *plugin)
{
	size_t progsize;
	char *prog = ReadIntoOrFromCache(plugin, progsize);

	if (!prog)
		return;

	AMX_HEADER hdr;
	memcpy(&hdr, prog, sizeof(AMX_HEADER));

	uint16_t magic = hdr.magic;
	amx_Align16(&magic);

	if (magic != AMX_MAGIC)
	{
		return;
	}

	if (hdr.file_version < MIN_FILE_VERSION ||
		hdr.file_version > CUR_FILE_VERSION)
	{
		return;
	}
	if ((hdr.defsize != sizeof(AMX_FUNCSTUB)) &&
		(hdr.defsize != sizeof(AMX_FUNCSTUBNT)))
	{
		return;
	}

	amx_Align32((uint32_t*)&hdr.nametable);
	uint16_t *namelength=(uint16_t*)((unsigned char*)prog + (unsigned)hdr.nametable);
	amx_Align16(namelength);
	if (*namelength>sNAMEMAX)
	{
		return;
	}

	if (hdr.stp <= 0)
	{
		return;
	}

	AMX amx;
	memset(&amx, 0, sizeof(AMX));
	amx.base = (unsigned char *)prog;

	int num;
	char name[sNAMEMAX+1];

	num = amx_GetLibraries(&amx);
	for (int i=0; i<num; i++)
	{
		amx_GetLibrary(&amx, i, name, sNAMEMAX);
		if (stricmp(name, "Float")==0)
			continue;
		//awful backwards compat hack
		if (stricmp(name, "socket")==0)
			strcpy(name, "sockets");
		//we don't want to report failed modules here...
		LoadModule(name, PT_ANYTIME, true, true);
	}

	cell tag_id;
	amx_NumTags(&amx, &num);

	ke::Vector<LibDecoder *> expects;
	ke::Vector<LibDecoder *> defaults;
	CStack<LibDecoder *> delstack;
	for (int i=0; i<num; i++)
	{
		amx_GetTag(&amx, i, name, &tag_id);
		if (name[0] == '?')
		{
			LibDecoder *dc = new LibDecoder;
			delstack.push(dc);
			if (DecodeLibCmdString(name, dc))
			{
				if (dc->cmd == LibCmd_ForceLib)
				{
					RunLibCommand(dc);
				} else if ( (dc->cmd == LibCmd_ExpectClass) ||
							(dc->cmd == LibCmd_ExpectLib) )
				{
					expects.append(dc);
				} else if (dc->cmd == LibCmd_DefaultLib) {
					defaults.append(dc);
				}
			}
		}
	}

	for (size_t i=0; i<expects.length(); i++)
	{
		RunLibCommand(expects[i]);
	}
	for (size_t i=0; i<defaults.length(); i++)
	{
		RunLibCommand(defaults[i]);
	}

	expects.clear();
	defaults.clear();

	while (!delstack.empty())
	{
		delete delstack.front();
		delstack.pop();
	}

	return;
}