finished 2/6 sections for file output

fixed some more minor sm things

--HG--
branch : dvander
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/dvander%4018
This commit is contained in:
David Anderson 2006-07-15 01:36:50 +00:00
parent 9cd64d946c
commit d2cee081ac
9 changed files with 678 additions and 38 deletions

View File

@ -34,9 +34,10 @@
#include <sclinux.h>
#endif
#if defined HAVE_STDINT_H
#if defined __GNUC__
#include <stdint.h>
#else
#define HAVE_STDINT_H
#elif !defined HAVE_STDINT_H
#if defined __LCC__ || defined __DMC__ || defined LINUX || (defined __WATCOMC__ && __WATCOMC__ >= 1200)
#if defined HAVE_INTTYPES_H
#include <inttypes.h>
@ -459,4 +460,170 @@ int AMXAPI amx_UTF8Put(char *string, char **endptr, int maxchars, cell value);
}
#endif
typedef enum {
OP_NONE, /* invalid opcode */
OP_LOAD_PRI,
OP_LOAD_ALT,
OP_LOAD_S_PRI,
OP_LOAD_S_ALT,
OP_LREF_PRI,
OP_LREF_ALT,
OP_LREF_S_PRI,
OP_LREF_S_ALT,
OP_LOAD_I,
OP_LODB_I,
OP_CONST_PRI,
OP_CONST_ALT,
OP_ADDR_PRI,
OP_ADDR_ALT,
OP_STOR_PRI,
OP_STOR_ALT,
OP_STOR_S_PRI,
OP_STOR_S_ALT,
OP_SREF_PRI,
OP_SREF_ALT,
OP_SREF_S_PRI,
OP_SREF_S_ALT,
OP_STOR_I,
OP_STRB_I,
OP_LIDX,
OP_LIDX_B,
OP_IDXADDR,
OP_IDXADDR_B,
OP_ALIGN_PRI,
OP_ALIGN_ALT,
OP_LCTRL,
OP_SCTRL,
OP_MOVE_PRI,
OP_MOVE_ALT,
OP_XCHG,
OP_PUSH_PRI,
OP_PUSH_ALT,
OP_PUSH_R,
OP_PUSH_C,
OP_PUSH,
OP_PUSH_S,
OP_POP_PRI,
OP_POP_ALT,
OP_STACK,
OP_HEAP,
OP_PROC,
OP_RET,
OP_RETN,
OP_CALL,
OP_CALL_PRI,
OP_JUMP,
OP_JREL,
OP_JZER,
OP_JNZ,
OP_JEQ,
OP_JNEQ,
OP_JLESS,
OP_JLEQ,
OP_JGRTR,
OP_JGEQ,
OP_JSLESS,
OP_JSLEQ,
OP_JSGRTR,
OP_JSGEQ,
OP_SHL,
OP_SHR,
OP_SSHR,
OP_SHL_C_PRI,
OP_SHL_C_ALT,
OP_SHR_C_PRI,
OP_SHR_C_ALT,
OP_SMUL,
OP_SDIV,
OP_SDIV_ALT,
OP_UMUL,
OP_UDIV,
OP_UDIV_ALT,
OP_ADD,
OP_SUB,
OP_SUB_ALT,
OP_AND,
OP_OR,
OP_XOR,
OP_NOT,
OP_NEG,
OP_INVERT,
OP_ADD_C,
OP_SMUL_C,
OP_ZERO_PRI,
OP_ZERO_ALT,
OP_ZERO,
OP_ZERO_S,
OP_SIGN_PRI,
OP_SIGN_ALT,
OP_EQ,
OP_NEQ,
OP_LESS,
OP_LEQ,
OP_GRTR,
OP_GEQ,
OP_SLESS,
OP_SLEQ,
OP_SGRTR,
OP_SGEQ,
OP_EQ_C_PRI,
OP_EQ_C_ALT,
OP_INC_PRI,
OP_INC_ALT,
OP_INC,
OP_INC_S,
OP_INC_I,
OP_DEC_PRI,
OP_DEC_ALT,
OP_DEC,
OP_DEC_S,
OP_DEC_I,
OP_MOVS,
OP_CMPS,
OP_FILL,
OP_HALT,
OP_BOUNDS,
OP_SYSREQ_PRI,
OP_SYSREQ_C,
OP_FILE, /* obsolete */
OP_LINE, /* obsolete */
OP_SYMBOL, /* obsolete */
OP_SRANGE, /* obsolete */
OP_JUMP_PRI,
OP_SWITCH,
OP_CASETBL,
OP_SWAP_PRI,
OP_SWAP_ALT,
OP_PUSH_ADR,
OP_NOP,
OP_SYSREQ_N,
OP_SYMTAG, /* obsolete */
OP_BREAK,
OP_PUSH2_C,
OP_PUSH2,
OP_PUSH2_S,
OP_PUSH2_ADR,
OP_PUSH3_C,
OP_PUSH3,
OP_PUSH3_S,
OP_PUSH3_ADR,
OP_PUSH4_C,
OP_PUSH4,
OP_PUSH4_S,
OP_PUSH4_ADR,
OP_PUSH5_C,
OP_PUSH5,
OP_PUSH5_S,
OP_PUSH5_ADR,
OP_LOAD_BOTH,
OP_LOAD_S_BOTH,
OP_CONST,
OP_CONST_S,
/* ----- */
OP_SYSREQ_D,
OP_SYSREQ_ND,
/* ----- */
OP_NUM_OPCODES
} OPCODE;
#endif /* AMX_H_INCLUDED */

View File

@ -221,6 +221,8 @@ char *pc_readasm(void *handle, char *string, int maxchars)
#endif
}
extern memfile_t *bin_file;
/* Should return a pointer, which is used as a "magic cookie" to all I/O
* functions; return NULL for failure.
*/
@ -234,6 +236,9 @@ void pc_closebin(void *handle,int deletefile)
if (deletefile)
{
memfile_destroy((memfile_t *)handle);
bin_file = NULL;
} else {
bin_file = (memfile_t *)handle;
}
}

View File

@ -42,6 +42,7 @@
# define access _access
# define chdir _chdir
# define strdup _strdup
# define unlink _unlink
# endif
#endif

View File

@ -1,30 +1,389 @@
/* Pawn compiler driver
*
* Function and variable definition and declaration, statement parser.
*
* Copyright (c) ITB CompuPhase, 2006
*
* This software is provided "as-is", without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from
* the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software in
* a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* Version: $Id: Sc1.c 3114 2005-03-17 14:48:29Z thiadmer $
*/
#include "sc.h"
#include <stdio.h>
#include <setjmp.h>
#include <assert.h>
#include <string.h>
#include "memfile.h"
#include "sp_file.h"
#include "amx.h"
#include "osdefs.h"
#define NUM_SECTIONS 6
int pc_printf(const char *message,...);
int pc_compile(int argc, char **argv);
void sfwrite(const void *buf, size_t size, size_t count, FILE *fp);
memfile_t *bin_file = NULL;
jmp_buf brkout;
int main(int argc, char *argv[])
{
return pc_compile(argc,argv);
if (pc_compile(argc,argv) == 0)
{
FILE *fp;
AMX_HEADER *hdr;
sp_file_hdr_t shdr;
uint32_t curoffs = 0;
uint32_t lastsection = 0;
int err;
uint8_t i8;
uint32_t i;
const char *tables[NUM_SECTIONS] = {".code", ".data", ".publics", ".pubvars", ".natives", ".names"};
uint32_t offsets[NUM_SECTIONS] = {0,0,0,0,0,0};
sp_file_section_t sh;
if (bin_file == NULL)
{
return 0;
}
hdr = (AMX_HEADER *)bin_file->base;
shdr.version = SPFILE_VERSION;
shdr.magic = SPFILE_MAGIC;
if ((fp=fopen(bin_file->name, "wb")) == NULL)
{
pc_printf("Error writing to file: %s", bin_file->name);
return 1;
}
if ((err=setjmp(brkout))!=0)
{
goto write_error;
}
shdr.sections = NUM_SECTIONS;
shdr.stringtab = sizeof(shdr) + (sizeof(sp_file_section_t) * shdr.sections);
/**
* write the header
* unwritten values:
* imagesize
*/
sfwrite(&shdr, sizeof(shdr), 1, fp);
curoffs = shdr.stringtab;
/**
* write the sections
* unwritten values:
* dataoffs
* size
*/
for (i8=0; i8<shdr.sections; i8++)
{
/* set name offset to next in string table */
sh.nameoffs = curoffs - shdr.stringtab;
/* save offset to this section */
offsets[i8] = (uint32_t)ftell(fp) + sizeof(sh.nameoffs);
/* update `end of file` offset */
curoffs += strlen(tables[i8]) + 1;
sfwrite(&sh, sizeof(sh), 1, fp);
}
/** write the string table */
for (i8=0; i8<shdr.sections; i8++)
{
sfwrite(tables[i8], 1, strlen(tables[i8])+1, fp);
}
lastsection = curoffs;
/** write the code table */
if (strcmp(tables[0], ".code") == 0)
{
sp_file_code_t cod;
cell cip;
unsigned char *cbase;
uint8_t *tbase, *tptr;
cell real_codesize;
uint8_t op;
cod.cellsize = sizeof(cell);
cod.codesize = 0;
cod.codeversion = hdr->amx_version;
cod.flags = 0;
if (hdr->flags & AMX_FLAG_DEBUG)
{
cod.flags |= SP_FILE_DEBUG;
}
cod.code = sizeof(cod);
/* write the code in our newer format */
cbase = (unsigned char *)hdr + hdr->cod;
real_codesize = hdr->dat - hdr->cod;
tbase = (uint8_t *)malloc(real_codesize);
tptr = tbase;
for (cip = 0; cip < real_codesize;)
{
#define DBGPARAM(v) ( (v)=*(cell *)(cbase+(int)cip), cip+=sizeof(cell) )
op=(uint8_t) *(ucell *)(cbase+(int)cip);
cip += sizeof(cell);
*tptr++ = op;
switch (op)
{
case OP_PUSH5_C: /* instructions with 5 parameters */
case OP_PUSH5:
case OP_PUSH5_S:
case OP_PUSH5_ADR:
{
memcpy(tptr, cbase+(int)cip, sizeof(cell)*5);
cip += sizeof(cell)*5;
tptr += sizeof(cell)*5;
break;
}
case OP_PUSH4_C: /* instructions with 4 parameters */
case OP_PUSH4:
case OP_PUSH4_S:
case OP_PUSH4_ADR:
{
memcpy(tptr, cbase+(int)cip, sizeof(cell)*4);
cip += sizeof(cell)*4;
tptr += sizeof(cell)*4;
break;
}
case OP_PUSH3_C: /* instructions with 3 parameters */
case OP_PUSH3:
case OP_PUSH3_S:
case OP_PUSH3_ADR:
{
memcpy(tptr, cbase+(int)cip, sizeof(cell)*3);
cip += sizeof(cell)*3;
tptr += sizeof(cell)*3;
break;
}
case OP_PUSH2_C: /* instructions with 2 parameters */
case OP_PUSH2:
case OP_PUSH2_S:
case OP_PUSH2_ADR:
case OP_LOAD_BOTH:
case OP_LOAD_S_BOTH:
case OP_CONST:
case OP_CONST_S:
case OP_SYSREQ_N:
{
memcpy(tptr, cbase+(int)cip, sizeof(cell)*2);
cip += sizeof(cell)*2;
tptr += sizeof(cell)*2;
break;
}
case OP_LOAD_PRI: /* instructions with 1 parameter */
case OP_LOAD_ALT:
case OP_LOAD_S_PRI:
case OP_LOAD_S_ALT:
case OP_LREF_PRI:
case OP_LREF_ALT:
case OP_LREF_S_PRI:
case OP_LREF_S_ALT:
case OP_LODB_I:
case OP_CONST_PRI:
case OP_CONST_ALT:
case OP_ADDR_PRI:
case OP_ADDR_ALT:
case OP_STOR_PRI:
case OP_STOR_ALT:
case OP_STOR_S_PRI:
case OP_STOR_S_ALT:
case OP_SREF_PRI:
case OP_SREF_ALT:
case OP_SREF_S_PRI:
case OP_SREF_S_ALT:
case OP_STRB_I:
case OP_LIDX_B:
case OP_IDXADDR_B:
case OP_ALIGN_PRI:
case OP_ALIGN_ALT:
case OP_LCTRL:
case OP_SCTRL:
case OP_PUSH_R:
case OP_PUSH_C:
case OP_PUSH:
case OP_PUSH_S:
case OP_STACK:
case OP_HEAP:
case OP_JREL:
case OP_SHL_C_PRI:
case OP_SHL_C_ALT:
case OP_SHR_C_PRI:
case OP_SHR_C_ALT:
case OP_ADD_C:
case OP_SMUL_C:
case OP_ZERO:
case OP_ZERO_S:
case OP_EQ_C_PRI:
case OP_EQ_C_ALT:
case OP_INC:
case OP_INC_S:
case OP_DEC:
case OP_DEC_S:
case OP_MOVS:
case OP_CMPS:
case OP_FILL:
case OP_HALT:
case OP_BOUNDS:
case OP_PUSH_ADR:
case OP_CALL: /* opcodes that need relocation */
case OP_JUMP:
case OP_JZER:
case OP_JNZ:
case OP_JEQ:
case OP_JNEQ:
case OP_JLESS:
case OP_JLEQ:
case OP_JGRTR:
case OP_JGEQ:
case OP_JSLESS:
case OP_JSLEQ:
case OP_JSGRTR:
case OP_JSGEQ:
case OP_SWITCH:
case OP_SYSREQ_C:
{
*(cell *)tptr = *(cell *)(cbase + (int)cip);
cip += sizeof(cell);
tptr += sizeof(cell);
break;
}
case OP_LOAD_I: /* instructions without parameters */
case OP_STOR_I:
case OP_LIDX:
case OP_IDXADDR:
case OP_MOVE_PRI:
case OP_MOVE_ALT:
case OP_XCHG:
case OP_PUSH_PRI:
case OP_PUSH_ALT:
case OP_POP_PRI:
case OP_POP_ALT:
case OP_PROC:
case OP_RET:
case OP_RETN:
case OP_CALL_PRI:
case OP_SHL:
case OP_SHR:
case OP_SSHR:
case OP_SMUL:
case OP_SDIV:
case OP_SDIV_ALT:
case OP_UMUL:
case OP_UDIV:
case OP_UDIV_ALT:
case OP_ADD:
case OP_SUB:
case OP_SUB_ALT:
case OP_AND:
case OP_OR:
case OP_XOR:
case OP_NOT:
case OP_NEG:
case OP_INVERT:
case OP_ZERO_PRI:
case OP_ZERO_ALT:
case OP_SIGN_PRI:
case OP_SIGN_ALT:
case OP_EQ:
case OP_NEQ:
case OP_LESS:
case OP_LEQ:
case OP_GRTR:
case OP_GEQ:
case OP_SLESS:
case OP_SLEQ:
case OP_SGRTR:
case OP_SGEQ:
case OP_INC_PRI:
case OP_INC_ALT:
case OP_INC_I:
case OP_DEC_PRI:
case OP_DEC_ALT:
case OP_DEC_I:
case OP_SYSREQ_PRI:
case OP_JUMP_PRI:
case OP_SWAP_PRI:
case OP_SWAP_ALT:
case OP_NOP:
case OP_BREAK:
break;
case OP_CASETBL:
{
cell num;
int i;
DBGPARAM(*(cell *)tptr);
num = *(cell *)tptr;
tptr += sizeof(cell);
memcpy(tptr, cbase+(int)cip, (2*num+1)*sizeof(cell));
tptr += (2*num+1) * sizeof(cell);
cip += (2*num+1) * sizeof(cell);
break;
}
default:
{
assert(0);
}
#undef DBGPARAM
}
}
cod.codesize = (uint32_t)(tptr - tbase);
sfwrite(&cod, sizeof(cod), 1, fp);
sfwrite(tbase, cod.codesize, 1, fp);
free(tbase);
/* backtrack and write this section's header info */
curoffs = (uint32_t)ftell(fp);
fseek(fp, offsets[0], SEEK_SET);
sfwrite(&lastsection, sizeof(lastsection), 1, fp);
cod.codesize += sizeof(cod);
sfwrite(&cod.codesize, sizeof(cod.codesize), 1, fp);
fseek(fp, curoffs, SEEK_SET);
lastsection = curoffs;
}
if (strcmp(tables[1], ".data") == 0)
{
sp_file_data_t dat;
unsigned char *dbase;
dat.datasize = hdr->hea - hdr->dat;
dat.memsize = hdr->stp;
dat.data = sizeof(dat);
dbase = (unsigned char *)hdr + hdr->dat;
sfwrite(&dat, sizeof(dat), 1, fp);
if (dat.datasize)
{
sfwrite(dbase, dat.datasize, 1, fp);
}
/* backtrack and write this section's header info */
curoffs = ftell(fp);
fseek(fp, offsets[1], SEEK_SET);
sfwrite(&lastsection, sizeof(lastsection), 1, fp);
dat.datasize += sizeof(dat);
sfwrite(&dat.datasize, sizeof(dat.datasize),1, fp);
fseek(fp, curoffs, SEEK_SET);
lastsection = curoffs;
}
fclose(fp);
return 0;
write_error:
pc_printf("Error writing to file: %s", bin_file->name);
unlink(bin_file->name);
fclose(fp);
return 1;
}
return 1;
}
void sfwrite(const void *buf, size_t size, size_t count, FILE *fp)
{
if (fwrite(buf, size, count, fp) != count)
{
longjmp(brkout, 1);
}
}

View File

@ -629,14 +629,10 @@ static void initglobals(void)
warnnum=0; /* number of warnings */
optproccall=FALSE; /* sourcemod: do not support "procedure call" */
verbosity=1; /* verbosity level, no copyright banner */
sc_debug=sSYMBOLIC; /* sourcemod: full debug stuff */
pc_optimize=sOPTIMIZE_DEFAULT; /* sourcemod: full optimization */
sc_debug=sCHKBOUNDS|sSYMBOLIC; /* sourcemod: full debug stuff */
pc_optimize=sOPTIMIZE_DEFAULT; /* sourcemod: full optimization */
sc_packstr=FALSE; /* strings are unpacked by default */
#if AMX_COMPACTMARGIN > 2
sc_compress=TRUE; /* compress output bytecodes */
#else
sc_compress=FALSE;
#endif
sc_compress=FALSE; /* always disable compact encoding! */
sc_needsemicolon=FALSE;/* semicolon required to terminate expressions? */
sc_dataalign=sizeof(cell);
pc_stksize=sDEF_AMXSTACK;/* default stack size */
@ -1132,7 +1128,7 @@ static void about(void)
pc_printf("Options:\n");
pc_printf(" -A<num> alignment in bytes of the data segment and the stack\n");
pc_printf(" -a output assembler code\n");
#if AMX_COMPACTMARGIN > 2
#if 0 /* not toggleable in SourceMod */
pc_printf(" -C[+/-] compact encoding for output file (default=%c)\n", sc_compress ? '+' : '-');
#endif
pc_printf(" -c<name> codepage name or number; e.g. 1252 for Windows Latin-1\n");

View File

@ -1076,10 +1076,12 @@ static int command(void)
if (find_constval(&libname_tab,name,0)==NULL)
curlibrary=append_constval(&libname_tab,name,0,0);
} /* if */
#if 0 /* more unused */
} else if (strcmp(str,"pack")==0) {
cell val;
preproc_expr(&val,NULL); /* default = packed/unpacked */
sc_packstr=(int)val;
#endif
} else if (strcmp(str,"rational")==0) {
char name[sNAMEMAX+1];
cell digits=0;

View File

@ -47,7 +47,7 @@ typedef struct {
char *name;
int segment; /* sIN_CSEG=parse in cseg, sIN_DSEG=parse in dseg */
OPCODE_PROC func;
} OPCODE;
} OPCODEC;
static cell codeindex; /* similar to "code_idx" */
static cell *lbltab; /* label table */
@ -454,7 +454,7 @@ static cell do_case(FILE *fbin,char *params,cell opcode)
return opcodes(0)+opargs(2);
}
static OPCODE opcodelist[] = {
static OPCODEC opcodelist[] = {
/* node for "invalid instruction" */
{ 0, NULL, 0, noop },
/* opcodes in sorted order */

102
compiler-init/sp_file.h Normal file
View File

@ -0,0 +1,102 @@
#ifndef _INCLUDE_SPFILE_H
#define _INCLUDE_SPFILE_H
#include <stddef.h>
#if defined __GNUC__ || defined HAVE_STDINT_
#include <stdint.h>
#else
#if !defined HAVE_STDINT_H
typedef unsigned __int64 uint64_t;
typedef __int64 int64_t;
typedef unsigned __int32 uint32_t;
typedef __int32 int32_t;
typedef unsigned __int16 uint16_t;
typedef __int16 int16_t;
typedef unsigned __int8 uint8_t;
typedef __int8 int8_t;
#define HAVE_STDINT_H
#endif
#endif
#define SPFILE_MAGIC 0xDEADC0D3
#define SPFILE_VERSION 0x0100
//:TODO: better compiler/nix support
#if defined __linux__
#pragma pack(1) /* structures must be packed (byte-aligned) */
#else
#pragma pack(push)
#pragma pack(1) /* structures must be packed (byte-aligned) */
#endif
typedef struct sp_file_section_s
{
uint32_t nameoffs; /* rel offset into global string table */
uint32_t dataoffs;
uint32_t size;
} sp_file_section_t;
typedef struct sp_file_hdr_s
{
uint32_t magic;
uint16_t version;
uint32_t imagesize;
uint8_t sections;
uint32_t stringtab;
} sp_file_hdr_t;
typedef enum
{
SP_FILE_NONE = 0,
SP_FILE_DEBUG = 1,
} sp_file_flags_t;
/* section is ".code" */
typedef struct sp_file_code_s
{
uint32_t codesize; /* codesize in bytes */
uint8_t cellsize; /* cellsize in bytes */
uint8_t codeversion; /* version of opcodes supported */
uint16_t flags; /* flags */
uint32_t code; /* rel offset to code */
} sp_file_code_t;
/* section is .data */
typedef struct sp_file_data_s
{
uint32_t datasize; /* size of data section */
uint32_t memsize; /* total mem required (includes data) */
uint32_t data; /* file offset to data (helper) */
} sp_file_data_t;
/* section is .publics */
typedef struct sp_file_publics_s
{
uint32_t address; /* address rel to code section */
uint32_t name; /* index into nametable */
} sp_file_publics_t;
/* section is .natives */
typedef struct sp_file_natives_s
{
uint32_t name; /* name of native at index */
} sp_file_natives_t;
/* section is .pubvars */
typedef struct sp_file_pubvars_s
{
uint32_t address; /* address rel to dat section */
uint32_t name; /* index into nametable */
} sp_file_pubvars_t;
#if defined __linux__
#pragma pack() /* reset default packing */
#else
#pragma pack(pop) /* reset previous packing */
#endif
/* section is .names */
typedef char * sp_file_nametab_t;
#endif //_INCLUDE_SPFILE_H

View File

@ -250,6 +250,10 @@
RelativePath=".\scvars.c"
>
</File>
<File
RelativePath=".\sp_file.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
@ -276,6 +280,10 @@
RelativePath=".\sc.h"
>
</File>
<File
RelativePath=".\sp_file.h"
>
</File>
<File
RelativePath=".\svnrev.h"
>