sourcepawn/jit/engine2.cpp
author David Anderson <dvander@alliedmods.net>
Mon Oct 27 02:02:14 2008 -0500 (2008-10-27)
changeset 2378 d812052c5821
parent 2376 91efbb63ad5b
child 2545 9cb1a1fefc2c
permissions -rw-r--r--
Fixed horrendous crash in the JIT from packing change in the debug table (bug 3334, r=me).
I accidentally changed the debug table packing in a commit a while ago. This explains the nonsense debug output and crashes people have been getting on the 1.1 branch. Fortunately this is (mostly) detectable via the "debug.natives" table and the JIT will unpack symbols based on that information.
     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <string.h>
     4 #include "engine2.h"
     5 #include "x86/jit_x86.h"
     6 #include "jit_version.h"
     7 #include "zlib/zlib.h"
     8 #include "BaseRuntime.h"
     9 #include "sp_vm_engine.h"
    10 
    11 using namespace SourcePawn;
    12 
    13 SourcePawnEngine2::SourcePawnEngine2()
    14 {
    15 	m_Profiler = NULL;
    16 }
    17 
    18 IPluginRuntime *SourcePawnEngine2::LoadPlugin(ICompilation *co, const char *file, int *err)
    19 {
    20 	sp_file_hdr_t hdr;
    21 	uint8_t *base;
    22 	int z_result;
    23 	int error;
    24 	BaseRuntime *pRuntime;
    25 
    26 	FILE *fp = fopen(file, "rb");
    27 
    28 	if (!fp)
    29 	{
    30 		error = SP_ERROR_NOT_FOUND;
    31 		goto return_error;
    32 	}
    33 
    34 	/* Rewind for safety */
    35 	fread(&hdr, sizeof(sp_file_hdr_t), 1, fp);
    36 
    37 	if (hdr.magic != SPFILE_MAGIC)
    38 	{
    39 		error = SP_ERROR_FILE_FORMAT;
    40 		goto return_error;
    41 	}
    42 
    43 	switch (hdr.compression)
    44 	{
    45 	case SPFILE_COMPRESSION_GZ:
    46 		{
    47 			uint32_t uncompsize = hdr.imagesize - hdr.dataoffs;
    48 			uint32_t compsize = hdr.disksize - hdr.dataoffs;
    49 			uint32_t sectsize = hdr.dataoffs - sizeof(sp_file_hdr_t);
    50 			uLongf destlen = uncompsize;
    51 
    52 			char *tempbuf = (char *)malloc(compsize);
    53 			void *uncompdata = malloc(uncompsize);
    54 			void *sectheader = malloc(sectsize);
    55 
    56 			fread(sectheader, sectsize, 1, fp);
    57 			fread(tempbuf, compsize, 1, fp);
    58 
    59 			z_result = uncompress((Bytef *)uncompdata, &destlen, (Bytef *)tempbuf, compsize);
    60 			free(tempbuf);
    61 			if (z_result != Z_OK)
    62 			{
    63 				free(sectheader);
    64 				free(uncompdata);
    65 				error = SP_ERROR_DECOMPRESSOR;
    66 				goto return_error;
    67 			}
    68 
    69 			base = (uint8_t *)malloc(hdr.imagesize);
    70 			memcpy(base, &hdr, sizeof(sp_file_hdr_t));
    71 			memcpy(base + sizeof(sp_file_hdr_t), sectheader, sectsize);
    72 			free(sectheader);
    73 			memcpy(base + hdr.dataoffs, uncompdata, uncompsize);
    74 			free(uncompdata);
    75 			break;
    76 		}
    77 	case SPFILE_COMPRESSION_NONE:
    78 		{
    79 			base = (uint8_t *)malloc(hdr.imagesize);
    80 			rewind(fp);
    81 			fread(base, hdr.imagesize, 1, fp);
    82 			break;
    83 		}
    84 	default:
    85 		{
    86 			error = SP_ERROR_DECOMPRESSOR;
    87 			goto return_error;
    88 		}
    89 	}
    90 
    91 	pRuntime = new BaseRuntime();
    92 	if ((error = pRuntime->CreateFromMemory(&hdr, base)) != SP_ERROR_NONE)
    93 	{
    94 		delete pRuntime;
    95 		goto return_error;
    96 	}
    97 
    98 	size_t len;
    99 	
   100 	len = strlen(file);
   101 	for (size_t i = len - 1; i >= 0 && i < len; i--)
   102 	{
   103 		if (file[i] == '/' 
   104 		#if defined WIN32
   105 			|| file[i] == '\\'
   106 		#endif
   107 		)
   108 		{
   109 			pRuntime->m_pPlugin->name = strdup(&file[i+1]);
   110 			break;
   111 		}
   112 	}
   113 
   114 	if (pRuntime->m_pPlugin->name == NULL)
   115 	{
   116 		pRuntime->m_pPlugin->name = strdup(file);
   117 	}
   118 
   119 	pRuntime->ApplyCompilationOptions(co);
   120 
   121     fclose(fp);
   122 
   123 	return pRuntime;
   124 
   125 return_error:
   126 	*err = error;
   127 	if (fp != NULL)
   128 	{
   129     	fclose(fp);
   130 	}
   131 
   132 	return NULL;
   133 }
   134 
   135 SPVM_NATIVE_FUNC SourcePawnEngine2::CreateFakeNative(SPVM_FAKENATIVE_FUNC callback, void *pData)
   136 {
   137 	return g_Jit.CreateFakeNative(callback, pData);
   138 }
   139 
   140 void SourcePawnEngine2::DestroyFakeNative(SPVM_NATIVE_FUNC func)
   141 {
   142 	g_Jit.DestroyFakeNative(func);
   143 }
   144 
   145 const char *SourcePawnEngine2::GetEngineName()
   146 {
   147 	return "SourcePawn 1.1, jit-x86";
   148 }
   149 
   150 const char *SourcePawnEngine2::GetVersionString()
   151 {
   152 	return SVN_FULL_VERSION;
   153 }
   154 
   155 IProfiler *SourcePawnEngine2::GetProfiler()
   156 {
   157 	return m_Profiler;
   158 }
   159 
   160 void SourcePawnEngine2::SetProfiler(IProfiler *profiler)
   161 {
   162 	m_Profiler = profiler;
   163 }
   164 
   165 IDebugListener *SourcePawnEngine2::SetDebugListener(IDebugListener *listener)
   166 {
   167 	return g_engine1.SetDebugListener(listener);
   168 }
   169 
   170 unsigned int SourcePawnEngine2::GetAPIVersion()
   171 {
   172 	return SOURCEPAWN_ENGINE2_API_VERSION;
   173 }
   174 
   175 ICompilation *SourcePawnEngine2::StartCompilation()
   176 {
   177 	return g_Jit.StartCompilation();
   178 }
   179 
   180 const char *SourcePawnEngine2::GetErrorString(int err)
   181 {
   182 	return g_engine1.GetErrorString(err);
   183 }
   184 
   185 bool SourcePawnEngine2::Initialize()
   186 {
   187 	return g_Jit.InitializeJIT();
   188 }
   189 
   190 void SourcePawnEngine2::Shutdown()
   191 {
   192 	g_Jit.ShutdownJIT();
   193 }