diff --git a/compiler/amxxpc/amxdbg.h b/compiler/amxxpc/amxdbg.h new file mode 100755 index 00000000..9f9258c4 --- /dev/null +++ b/compiler/amxxpc/amxdbg.h @@ -0,0 +1,172 @@ +/* Abstract Machine for the Pawn compiler, debugger support + * + * This file contains extra definitions that are convenient for debugger + * support. + * + * Copyright (c) ITB CompuPhase, 2005 + * + * 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$ + */ + +#ifndef AMXDBG_H_INCLUDED +#define AMXDBG_H_INCLUDED + +#ifndef AMX_H_INCLUDED + #include "amx.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Some compilers do not support the #pragma align, which should be fine. Some + * compilers give a warning on unknown #pragmas, which is not so fine... + */ +#if defined SN_TARGET_PS2 || defined __GNUC__ + #define AMX_NO_ALIGN +#endif + +#if defined __GNUC__ + #define PACKED __attribute__((packed)) +#else + #define PACKED +#endif + +#if !defined AMX_NO_ALIGN + #if defined LINUX || defined __FreeBSD__ + #pragma pack(1) /* structures must be packed (byte-aligned) */ + #elif defined MACOS && defined __MWERKS__ + #pragma options align=mac68k + #else + #pragma pack(push) + #pragma pack(1) /* structures must be packed (byte-aligned) */ + #if defined __TURBOC__ + #pragma option -a- /* "pack" pragma for older Borland compilers */ + #endif + #endif +#endif + +typedef struct tagAMX_DBG_HDR { + int32_t size PACKED; /* size of the debug information chunk */ + uint16_t magic PACKED; /* signature, must be 0xf1ef */ + char file_version PACKED; /* file format version */ + char amx_version PACKED; /* required version of the AMX */ + int16_t flags PACKED; /* currently unused */ + int16_t files PACKED; /* number of entries in the "file" table */ + int16_t lines PACKED; /* number of entries in the "line" table */ + int16_t symbols PACKED; /* number of entries in the "symbol" table */ + int16_t tags PACKED; /* number of entries in the "tag" table */ + int16_t automatons PACKED; /* number of entries in the "automaton" table */ + int16_t states PACKED; /* number of entries in the "state" table */ +} AMX_DBG_HDR PACKED; +#define AMX_DBG_MAGIC 0xf1ef + +typedef struct tagAMX_DBG_FILE { + ucell address PACKED; /* address in the code segment where generated code (for this file) starts */ + const char name[1] PACKED; /* ASCII string, zero-terminated */ +} AMX_DBG_FILE PACKED; + +typedef struct tagAMX_DBG_LINE { + ucell address PACKED; /* address in the code segment where generated code (for this line) starts */ + int32_t line PACKED; /* line number */ +} AMX_DBG_LINE PACKED; + +typedef struct tagAMX_DBG_SYMBOL { + ucell address PACKED; /* address in the data segment or relative to the frame */ + int16_t tag PACKED; /* tag for the symbol */ + ucell codestart PACKED; /* address in the code segment from which this symbol is valid (in scope) */ + ucell codeend PACKED; /* address in the code segment until which this symbol is valid (in scope) */ + char ident PACKED; /* kind of symbol (function/variable) */ + char vclass PACKED; /* class of symbol (global/local) */ + int16_t dim PACKED; /* number of dimensions */ + const char name[1] PACKED; /* ASCII string, zero-terminated */ +} AMX_DBG_SYMBOL PACKED; + +typedef struct tagAMX_DBG_SYMDIM { + int16_t tag PACKED; /* tag for the array dimension */ + ucell size PACKED; /* size of the array dimension */ +} AMX_DBG_SYMDIM PACKED; + +typedef struct tagAMX_DBG_TAG { + int16_t tag PACKED; /* tag id */ + const char name[1] PACKED; /* ASCII string, zero-terminated */ +} AMX_DBG_TAG PACKED; + +typedef struct tagAMX_DBG_MACHINE { + int16_t automaton PACKED; /* automaton id */ + ucell address PACKED; /* address of state variable */ + const char name[1] PACKED; /* ASCII string, zero-terminated */ +} AMX_DBG_MACHINE PACKED; + +typedef struct tagAMX_DBG_STATE { + int16_t state PACKED; /* state id */ + int16_t automaton PACKED; /* automaton id */ + const char name[1] PACKED; /* ASCII string, zero-terminated */ +} AMX_DBG_STATE PACKED; + +typedef struct tagAMX_DBG { + AMX_DBG_HDR _FAR *hdr PACKED; /* points to the AMX_DBG header */ + AMX_DBG_FILE _FAR **filetbl PACKED; + AMX_DBG_LINE _FAR *linetbl PACKED; + AMX_DBG_SYMBOL _FAR **symboltbl PACKED; + AMX_DBG_TAG _FAR **tagtbl PACKED; + AMX_DBG_MACHINE _FAR **automatontbl PACKED; + AMX_DBG_STATE _FAR **statetbl PACKED; +} AMX_DBG PACKED; + +#if !defined iVARIABLE + #define iVARIABLE 1 /* cell that has an address and that can be fetched directly (lvalue) */ + #define iREFERENCE 2 /* iVARIABLE, but must be dereferenced */ + #define iARRAY 3 + #define iREFARRAY 4 /* an array passed by reference (i.e. a pointer) */ + #define iFUNCTN 9 +#endif + + +int AMXAPI dbg_FreeInfo(AMX_DBG *amxdbg); +int AMXAPI dbg_LoadInfo(AMX_DBG *amxdbg, FILE *fp); + +int AMXAPI dbg_LookupFile(AMX_DBG *amxdbg, ucell address, const char **filename); +int AMXAPI dbg_LookupFunction(AMX_DBG *amxdbg, ucell address, const char **funcname); +int AMXAPI dbg_LookupLine(AMX_DBG *amxdbg, ucell address, long *line); + +int AMXAPI dbg_GetFunctionAddress(AMX_DBG *amxdbg, const char *funcname, const char *filename, ucell *address); +int AMXAPI dbg_GetLineAddress(AMX_DBG *amxdbg, long line, const char *filename, ucell *address); +int AMXAPI dbg_GetAutomatonName(AMX_DBG *amxdbg, int automaton, const char **name); +int AMXAPI dbg_GetStateName(AMX_DBG *amxdbg, int state, const char **name); +int AMXAPI dbg_GetTagName(AMX_DBG *amxdbg, int tag, const char **name); +int AMXAPI dbg_GetVariable(AMX_DBG *amxdbg, const char *symname, ucell scopeaddr, const AMX_DBG_SYMBOL **sym); +int AMXAPI dbg_GetArrayDim(AMX_DBG *amxdbg, const AMX_DBG_SYMBOL *sym, const AMX_DBG_SYMDIM **symdim); + + +#if !defined AMX_NO_ALIGN + #if defined LINUX || defined __FreeBSD__ + #pragma pack() /* reset default packing */ + #elif defined MACOS && defined __MWERKS__ + #pragma options align=reset + #else + #pragma pack(pop) /* reset previous packing */ + #endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* AMXDBG_H_INCLUDED */ diff --git a/compiler/amxxpc/amxxpc.cpp b/compiler/amxxpc/amxxpc.cpp index a212e1d8..3a1c60f8 100755 --- a/compiler/amxxpc/amxxpc.cpp +++ b/compiler/amxxpc/amxxpc.cpp @@ -8,8 +8,11 @@ #include #include "zlib.h" #include "amx.h" +#include "amxdbg.h" #include "amxxpc.h" +void ReadFileIntoPl(abl *pl, FILE *fp); + int main(int argc, char **argv) { struct abl pl32; @@ -36,26 +39,25 @@ int main(int argc, char **argv) } COMPILER sc32 = (COMPILER)dlsym(lib, "Compile32"); + PRINTF pc_printf = (PRINTF)dlsym(lib, "pc_printf"); - if (!sc32) + if (!sc32 || !pc_printf) { #ifdef __linux__ - printf("32bit compiler failed to link: %p.\n",sc32); + printf("32bit compiler failed to link: %p|%p.\n",sc32, sc_printf); #else printf("32bit compiler failed to link: %d.\n", GetLastError()); #endif exit(0); } - AMX_HEADER hdr; - - printf("Welcome to the AMX Mod X %s Compiler.\n", VERSION_STRING); - printf("Copyright (c) 1997-2005 ITB CompuPhase, AMX Mod X Team\n\n"); + pc_printf("Welcome to the AMX Mod X %s Compiler.\n", VERSION_STRING); + pc_printf("Copyright (c) 1997-2005 ITB CompuPhase, AMX Mod X Team\n\n"); if (argc < 2) { - printf("Usage: [options]\n"); - printf("Use -? or --help to see full options\n\n"); + pc_printf("Usage: [options]\n"); + pc_printf("Use -? or --help to see full options\n\n"); getchar(); exit(0); } @@ -63,7 +65,7 @@ int main(int argc, char **argv) if (!strcmp(argv[1], "-?") || !strcmp(argv[1], "--help")) { show_help(); - printf("Press any key to continue.\n"); + pc_printf("Press any key to continue.\n"); getchar(); exit(0); } @@ -74,28 +76,20 @@ int main(int argc, char **argv) if (file == NULL) { - printf("Could not locate the output file.\n"); + pc_printf("Could not locate the output file.\n"); exit(0); } else if (strstr(file, ".asm")) { - printf("Assembler output succeeded.\n"); + pc_printf("Assembler output succeeded.\n"); exit(0); } else { FILE *fp = fopen(file, "rb"); if (fp == NULL) { - printf("Could not locate output file %s (compile failed).\n", file); + pc_printf("Could not locate output file %s (compile failed).\n", file); exit(0); } - fread(&hdr, sizeof(hdr), 1, fp); - amx_Align32((uint32_t *)&hdr.stp); - amx_Align32((uint32_t *)&hdr.size); - pl32.stp = hdr.stp; + ReadFileIntoPl(&pl32, fp); pl32.cellsize = 4; - int size = sizeof(hdr) + hdr.size; - pl32.size = size; - pl32.data = new char[size]; - rewind(fp); - fread(pl32.data, 1, size, fp); fclose(fp); } @@ -109,7 +103,7 @@ int main(int argc, char **argv) #endif if (!lib64) { - printf("64bit compiler failed to instantiate.\n"); + pc_printf("64bit compiler failed to instantiate.\n"); exit(0); } @@ -118,9 +112,9 @@ int main(int argc, char **argv) if (!sc64) { #ifdef __linux__ - printf("64bit compiler failed to link: %s.\n", dlerror()); + pc_printf("64bit compiler failed to link: %s.\n", dlerror()); #else - printf("64bit compiler failed to link: %d.\n", GetLastError()); + pc_printf("64bit compiler failed to link: %d.\n", GetLastError()); #endif exit(0); } @@ -131,25 +125,17 @@ int main(int argc, char **argv) if (file == NULL) { - printf("Could not locate the output file on second pass.\n"); + pc_printf("Could not locate the output file on second pass.\n"); exit(0); } else { FILE *fp = fopen(file, "rb"); if (fp == NULL) { - printf("Could not locate output file on second pass (compile failed).\n"); + pc_printf("Could not locate output file on second pass (compile failed).\n"); exit(0); } - fread(&hdr, sizeof(hdr), 1, fp); - amx_Align32((uint32_t *)&hdr.stp); - amx_Align32((uint32_t *)&hdr.size); - pl64.stp = hdr.stp; + ReadFileIntoPl(&pl64, fp); pl64.cellsize = 8; - int size = sizeof(hdr) + hdr.size; - pl64.size = sizeof(hdr) + hdr.size; - pl64.data = new char[size]; - rewind(fp); - fread(pl64.data, 1, size, fp); fclose(fp); } @@ -165,7 +151,7 @@ int main(int argc, char **argv) if (err != Z_OK) { - printf("internal error - compression failed on first pass: %d\n", err); + pc_printf("internal error - compression failed on first pass: %d\n", err); exit(0); } @@ -175,7 +161,7 @@ int main(int argc, char **argv) if (err != Z_OK) { - printf("internal error - compression failed on second pass: %d\n", err); + pc_printf("internal error - compression failed on second pass: %d\n", err); exit(0); } @@ -187,7 +173,7 @@ int main(int argc, char **argv) FILE *fp = fopen(newfile, "wb"); if (!fp) { - printf("Error trying to write file %s.\n", newfile); + pc_printf("Error trying to write file %s.\n", newfile); exit(0); } @@ -215,13 +201,36 @@ int main(int argc, char **argv) unlink(file); - printf("Done.\n"); + pc_printf("Done.\n"); dlclose(lib); exit(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); +} + //we get the full name of the file here //our job is to a] switch the .sma extension to .amx // and to b] strip everything but the trailing name diff --git a/compiler/amxxpc/amxxpc.vcproj b/compiler/amxxpc/amxxpc.vcproj index a16966d0..e9a590bb 100755 --- a/compiler/amxxpc/amxxpc.vcproj +++ b/compiler/amxxpc/amxxpc.vcproj @@ -128,6 +128,9 @@ + +