diff --git a/public/sourcepawn/sp_file_headers.h b/public/sourcepawn/sp_file_headers.h index 5cf8e05f..05d157f2 100644 --- a/public/sourcepawn/sp_file_headers.h +++ b/public/sourcepawn/sp_file_headers.h @@ -159,12 +159,6 @@ typedef struct sp_file_tag_s uint32_t name; /**< Index into nametable */ } sp_file_tag_t; -#if defined __linux__ - #pragma pack() /* reset default packing */ -#else - #pragma pack(pop) /* reset previous packing */ -#endif - /** * @brief File-encoded debug information table. */ @@ -199,6 +193,7 @@ typedef struct sp_fdbg_line_s #define SP_SYM_ARRAY 3 /**< Symbol is an array */ #define SP_SYM_REFARRAY 4 /**< An array passed by reference (i.e. a pointer) */ #define SP_SYM_FUNCTION 9 /**< Symbol is a function */ +#define SP_SYM_VARARGS 11 /**< Variadic argument start. */ /** * @brief File-encoded debug symbol information. @@ -227,4 +222,48 @@ typedef struct sp_fdbg_arraydim_s /** Typedef for .names table */ typedef char * sp_file_nametab_t; +/** + * @brief File encoding for the dbg.natives table. + * + * This header is followed by variable length entries of sp_fdbg_native. + */ +typedef struct sp_fdbg_ntvtab_s +{ + uint32_t num_entries; /**< Number of entries. */ +} sp_fdbg_ntvtab_t; + +#define SP_NTVDBG_VARARGS (1<<0) /**< Formal args are followed by '...' */ + +/** + * @brief File encoding of native debug info. + * + * Each entry is followed by an sp_fdbg_ntvarg_t for each narg. + */ +typedef struct sp_fdbg_native_s +{ + uint32_t index; /**< Native index in the plugin. */ + uint32_t name; /**< Offset into debug nametable. */ + int16_t tagid; /**< Return tag. */ + uint16_t nargs; /**< Number of formal arguments. */ +} sp_fdbg_native_t; + +/** + * @brief File encoding of native arguments. + * + * Each entry is followed by an sp_fdbg_arraydim_t for each dimcount. + */ +typedef struct fp_fdbg_ntvarg_s +{ + uint8_t ident; /**< Variable type */ + int16_t tagid; /**< Tag id */ + uint16_t dimcount; /**< Dimension count (for arrays) */ + uint32_t name; /**< Offset into debug nametable */ +} sp_fdbg_ntvarg_t; + +#if defined __linux__ +#pragma pack() /* reset default packing */ +#else +#pragma pack(pop) /* reset previous packing */ +#endif + #endif //_INCLUDE_SPFILE_HEADERS_H diff --git a/sourcepawn/compiler/pawncc.c b/sourcepawn/compiler/pawncc.c index f29fc3c4..5701ca49 100644 --- a/sourcepawn/compiler/pawncc.c +++ b/sourcepawn/compiler/pawncc.c @@ -21,6 +21,7 @@ enum FileSections FS_DbgSymbol, FS_DbgLine, FS_DbgTags, + FS_DbgNatives, FS_DbgAutomaton, FS_DbgState, FS_DbgStrings, @@ -37,6 +38,28 @@ void sfwrite(const void *buf, size_t size, size_t count, sp_file_t *spf); memfile_t *bin_file = NULL; jmp_buf brkout; +#define sARGS_MAX 32 /* number of arguments a function can have, max */ +#define sDIMEN_MAX 4 /* maximum number of array dimensions */ + +typedef struct t_arg_s +{ + uint8_t ident; + int16_t tag; + char *name; + uint16_t dimcount; + sp_fdbg_arraydim_t dims[sDIMEN_MAX]; +} t_arg; + +typedef struct t_native_s +{ + char *name; + int16_t ret_tag; + uint16_t num_args; + t_arg args[sARGS_MAX]; +} t_native; + +t_native *native_list = NULL; + int main(int argc, char *argv[]) { #if defined _DEBUG @@ -51,7 +74,7 @@ int main(int argc, char *argv[]) sp_file_t *spf; memfile_t *dbgtab = NULL; //dbgcrab unsigned char *dbgptr = NULL; - uint32_t sections[FS_Number] = {1,1,0,0,0,1,0,0,0,0,0,0,0}; + uint32_t sections[FS_Number] = {1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0}; FILE *fp; if (bin_file == NULL) @@ -108,6 +131,10 @@ int main(int argc, char *argv[]) } else { dbgtab = memfile_creat("", 512); dbgptr = (unsigned char *)dbg + sizeof(AMX_DBG_HDR); + if ((sections[FS_DbgNatives] = sections[FS_Natives]) > 0) + { + spfw_add_section(spf, ".dbg.natives"); + } if (dbg->files) { spfw_add_section(spf, ".dbg.files"); @@ -298,6 +325,49 @@ int main(int argc, char *argv[]) memset(&info, 0, sizeof(sp_fdbg_info_t)); + if (sections[FS_Natives]) + { + uint16_t j; + uint32_t idx; + uint32_t name; + uint32_t natives = (hdr->libraries - hdr->natives) / hdr->defsize; + + sfwrite(&natives, sizeof(uint32_t), 1, spf); + for (idx=0; idxname = strdup(sym->name); + + for (i = 0; i < sMAXARGS; i++) + { + if (sym->dim.arglist[i].ident == 0) + { + break; + } + native->num_args++; + native->args[i].tag = sym->dim.arglist[i].tags == NULL ? 0 : sym->dim.arglist[i].tags[0]; + native->args[i].name = strdup(sym->dim.arglist[i].name); + native->args[i].ident = sym->dim.arglist[i].ident; + native->args[i].dimcount = sym->dim.arglist[i].numdim; + for (j = 0; j < native->args[i].dimcount; j++) + { + native->args[i].dims[j].size = sym->dim.arglist[i].dim[j]; + native->args[i].dims[j].tagid = sym->dim.arglist[i].idxtag[j]; + } + } + + native->ret_tag = sym->tag; +} diff --git a/sourcepawn/compiler/sc.h b/sourcepawn/compiler/sc.h index b6a59971..c762b8c3 100644 --- a/sourcepawn/compiler/sc.h +++ b/sourcepawn/compiler/sc.h @@ -519,6 +519,9 @@ long pc_lengthbin(void *handle); /* return the length of the file */ #define SC_VDEFINE #endif +void sp_fdbg_ntv_start(int num_natives); +void sp_fdbg_ntv_hook(int index, symbol *sym); + /* function prototypes in SC1.C */ SC_FUNC void set_extension(char *filename,char *extension,int force); SC_FUNC symbol *fetchfunc(char *name,int tag); diff --git a/sourcepawn/compiler/sc6.c b/sourcepawn/compiler/sc6.c index 6a431eac..c795c176 100644 --- a/sourcepawn/compiler/sc6.c +++ b/sourcepawn/compiler/sc6.c @@ -844,9 +844,11 @@ SC_FUNC int assemble(FILE *fout,FILE *fin) } /* if */ } /* for */ count=0; + sp_fdbg_ntv_start(numnatives); for (i=0; iname; if (lookup_alias(testalias,sym->name)) {