1.1 --- a/tools/gdc-psyfork/gdc.cpp Tue Jul 03 07:51:12 2012 -0400
1.2 +++ b/tools/gdc-psyfork/gdc.cpp Tue Jul 03 10:27:27 2012 -0400
1.3 @@ -3,6 +3,7 @@
1.4 #include <dlfcn.h>
1.5 #include <fcntl.h>
1.6 #include <math.h>
1.7 +#include <iostream>
1.8 #include "gdc.h"
1.9 #include "GameConfigs.h"
1.10 #include "MemoryUtils.h"
1.11 @@ -16,6 +17,11 @@
1.12 char *wgame_binary = NULL;
1.13 char *wengine_binary = NULL;
1.14
1.15 +inline bool IsDigit( char c )
1.16 +{
1.17 + return c < 58 && c > 47;
1.18 +}
1.19 +
1.20 int main(int argc, char **argv)
1.21 {
1.22 char *gamedata = NULL;
1.23 @@ -125,26 +131,6 @@
1.24 return 0;
1.25 }
1.26
1.27 - const char *vtsym = symbols.GetKeyValue("vtsym");
1.28 - if (!vtsym)
1.29 - {
1.30 - printf("Couldn't find vtsym\n");
1.31 - return 0;
1.32 - }
1.33 -
1.34 - void **vt = (void**) mu.ResolveSymbol(ghandle, vtsym);
1.35 - if (!vt)
1.36 - {
1.37 - printf("Couldn't find vtable %s\n", vtsym);
1.38 - dlclose(ghandle);
1.39 - dlclose(ehandle);
1.40 - close(wgfile);
1.41 - close(wefile);
1.42 -
1.43 - return 0;
1.44 - }
1.45 -
1.46 -
1.47 for (list<Offset>::iterator it = gc.m_Offsets.begin(); it != gc.m_Offsets.end(); it++)
1.48 {
1.49 if (debug)
1.50 @@ -155,34 +141,60 @@
1.51 const char *symbol = symbols.GetKeyValue(it->name);
1.52 if (symbol)
1.53 {
1.54 + char symvt[128] = "_ZTV";
1.55 + bool bGotFirstNumbers = false;
1.56 + bool bLastNumberDigit = false;
1.57 + unsigned int symlen = strlen(symbol);
1.58 + unsigned int pos = strlen(symvt);
1.59 +
1.60 + for ( unsigned int i = 0; i < symlen && pos < (sizeof(symvt)-1); ++i )
1.61 + {
1.62 + bool isDigit = IsDigit( symbol[i] );
1.63 + if( !isDigit && bLastNumberDigit )
1.64 + {
1.65 + bGotFirstNumbers = true;
1.66 + }
1.67 +
1.68 + // we're before the class len
1.69 + if( !bGotFirstNumbers && !isDigit )
1.70 + continue;
1.71 +
1.72 + // we're at the function name len
1.73 + if( bGotFirstNumbers && isDigit )
1.74 + {
1.75 + symvt[pos] = 0;
1.76 + break;
1.77 + }
1.78 +
1.79 + // we're at the class len or class name. we want these
1.80 + symvt[pos++] = symbol[i];
1.81 + if( isDigit )
1.82 + {
1.83 + bLastNumberDigit = isDigit;
1.84 + }
1.85 + }
1.86 + symvt[pos] = 0;
1.87 +
1.88 int newOffset;
1.89 - char symvt[128];
1.90 - strcpy(symvt, it->name);
1.91 - strcat(symvt, "_vt");
1.92 - const char *newvtsym = symbols.GetKeyValue(symvt);
1.93 - if (newvtsym && newvtsym[0])
1.94 + if (symvt[0])
1.95 {
1.96 - void **newvt = (void**) mu.ResolveSymbol(ghandle, newvtsym);
1.97 + void **newvt = (void**) mu.ResolveSymbol(ghandle, symvt);
1.98 if (!newvt)
1.99 {
1.100 - printf("O: %-22s - can't find, skipping\n", symvt);
1.101 + printf("? O: %-22s - can't find, skipping\n", symvt);
1.102 continue;
1.103 }
1.104
1.105 newOffset = findVFunc(ghandle, newvt, symbol);
1.106 }
1.107 - else
1.108 - {
1.109 - newOffset = findVFunc(ghandle, vt, symbol);
1.110 - }
1.111
1.112 if (newOffset == it->lin)
1.113 {
1.114 - printf("O: %-22s - GOOD. current [ w: %3d, l: %3d ].\n", it->name, it->win, it->lin);
1.115 + printf(" O: %-22s - GOOD. current [ w: %3d, l: %3d ].\n", it->name, it->win, it->lin);
1.116 }
1.117 else
1.118 {
1.119 - printf("O: %-22s - CHANGED. old [ w: %3d, l: %3d ]. new [ w: %3d, l: %3d ].\n",
1.120 + printf("! O: %-22s - CHANGED. old [ w: %3d, l: %3d ]. new [ w: %3d, l: %3d ].\n",
1.121 it->name,
1.122 it->win, it->lin,
1.123 newOffset - (it->lin - it->win), newOffset
1.124 @@ -191,7 +203,7 @@
1.125 }
1.126 else // !symbol
1.127 {
1.128 - printf("O: %-22s - no Linux symbol, skipping\n", it->name);
1.129 + printf(" O: %-22s - no Linux symbol, skipping\n", it->name);
1.130 }
1.131 }
1.132
1.133 @@ -210,7 +222,7 @@
1.134 bool hasWindows = (winSymbol && winSymbol[0]);
1.135 if (!hasLinux && !hasWindows)
1.136 {
1.137 - printf("S: %-22s - hasn't linux nor windows data, skipping\n", it->name);
1.138 + printf(" S: %-22s - hasn't linux nor windows data, skipping\n", it->name);
1.139 continue;
1.140 }
1.141
1.142 @@ -228,16 +240,17 @@
1.143 }
1.144 else
1.145 {
1.146 - printf("S: %-22s - isn't from server nor engine, skipping\n", it->name);
1.147 + printf(" S: %-22s - isn't from server nor engine, skipping\n", it->name);
1.148 continue;
1.149 }
1.150
1.151 - bool foundLinux = (!hasLinux || checkSigStringL(linHandle, linSymbol));
1.152 - bool foundWindows = (!hasWindows || checkSigStringW(winFile, winSymbol));
1.153 + int linuxMatches = 0, windowsMatches = 0;
1.154 + if( hasLinux )
1.155 + linuxMatches = checkSigStringL(linHandle, linSymbol);
1.156 + if( hasWindows )
1.157 + windowsMatches = checkSigStringW(winFile, winSymbol);
1.158
1.159 - // Prepare for ternery ABUSE
1.160 -
1.161 - if (foundLinux && foundWindows)
1.162 + if (linuxMatches == 1 && windowsMatches == 1)
1.163 {
1.164 // too much clutter to print current data if it matches anyway, unlike with offsets
1.165 /*
1.166 @@ -248,42 +261,86 @@
1.167 linSymbol ? linSymbol : ""
1.168 );
1.169 */
1.170 - printf("S: %-22s (%s) - GOOD.\n",
1.171 + printf(" S: %-22s (%s) - w: GOOD - l: GOOD \n",
1.172 it->name,
1.173 (it->lib == Server) ? "server" : "engine"
1.174 );
1.175 }
1.176 else
1.177 {
1.178 - // extra \n at end is intentional to add buffer after possibly long sigs
1.179 - printf("S: %-22s (%s) - w: %s - l: %s\n%s%s%s%s%s%s%s%s\n",
1.180 - it->name,
1.181 - (it->lib == Server) ? "server" : "engine",
1.182 - hasWindows ? (foundWindows ? "GOOD" : "CHANGED") : "UNKNOWN",
1.183 - hasLinux ? (foundLinux ? "GOOD" : "CHANGED") : "UNKNOWN",
1.184 -
1.185 - hasWindows ? "\tcurrent - w: " : "",
1.186 - (hasWindows && foundWindows) ? " (found) \"" : (hasWindows ? "(NOT found) \"" : ""),
1.187 - (hasWindows && winSymbol) ? winSymbol : "",
1.188 - hasWindows ? "\"\n" : "",
1.189 -
1.190 - hasLinux ? "\tcurrent - l: " : "",
1.191 - (hasLinux && foundLinux) ? " (found) \"" : (hasLinux ? "(NOT found) \"" : ""),
1.192 - (hasLinux && linSymbol) ? linSymbol : "",
1.193 - hasLinux ? "\"\n" : ""
1.194 + char winStatus[16];
1.195 + // right now the only option is to ignore
1.196 + const char *options = symbols.GetOptionValue(it->name);
1.197 + bool allowMulti = ( options && strstr(options, "allowmultiple") != NULL );
1.198 + bool allowMidfunc = ( options && strstr(options, "allowmidfunc") != NULL );
1.199 +
1.200 + bool bWinGood = false;
1.201 + if( !hasWindows ) {
1.202 + snprintf( winStatus, sizeof(winStatus), "UNKNOWN" );
1.203 + }
1.204 + else if( windowsMatches == -1 && !allowMidfunc) {
1.205 + snprintf( winStatus, sizeof(winStatus), "MIDFUNC" );
1.206 + }
1.207 + else if( windowsMatches == 0 ) {
1.208 + snprintf( winStatus, sizeof(winStatus), "NOTFOUND" );
1.209 + }
1.210 + else if( windowsMatches > 1 && !allowMulti) {
1.211 + snprintf( winStatus, sizeof(winStatus), "MULTIPLE" );
1.212 + }
1.213 + else {
1.214 + bWinGood = true;
1.215 + snprintf( winStatus, sizeof(winStatus), "GOOD" );
1.216 + }
1.217 +
1.218 + char linStatus[16];
1.219 + bool bLinGood = false;
1.220 + if( !hasLinux ) {
1.221 + snprintf( linStatus, sizeof(linStatus), "UNKNOWN" );
1.222 + }
1.223 + else if( linuxMatches == 0 ) {
1.224 + snprintf( linStatus, sizeof(linStatus), "NOTFOUND" );
1.225 + }
1.226 + else if( linuxMatches == 1 ) {
1.227 + bLinGood = true;
1.228 + snprintf( linStatus, sizeof(linStatus), "GOOD" );
1.229 + }
1.230 + else {
1.231 + snprintf( linStatus, sizeof(linStatus), "CHECK" );
1.232 + }
1.233 +
1.234 + bool showWinExtra = (hasWindows && !bWinGood);
1.235 + bool showLinExtra = ( ( hasLinux && !bLinGood ) || showWinExtra );
1.236 +
1.237 + printf("%s S: %-22s (%s)", (showWinExtra || showLinExtra) ? "!" : " ", it->name, (it->lib == Server) ? "server" : "engine" );
1.238 + printf(" - w: %-8s - l: %-8s\n", winStatus, linStatus );
1.239 +
1.240 + if( showWinExtra || showLinExtra )
1.241 + printf( "! current:\n" );
1.242 +
1.243 + if( showWinExtra )
1.244 + {
1.245 + printf("! w: \"%s\"\n",
1.246 + winSymbol ? winSymbol : ""
1.247 );
1.248 + }
1.249
1.250 + if( showLinExtra )
1.251 + {
1.252 + // extra \n at end is intentional to add buffer after possibly long sigs
1.253 + printf("! l: \"%s\"\n\n",
1.254 + linSymbol ? linSymbol : ""
1.255 + );
1.256 + }
1.257 }
1.258 -
1.259 - // j/k, no way that anyone could have been prepared for that
1.260 }
1.261
1.262 return 0;
1.263 }
1.264
1.265 -bool checkSigStringW(int file, const char* symbol)
1.266 +int checkSigStringW(int file, const char* symbol)
1.267 {
1.268 - void *addr = NULL;
1.269 + int matches = 0;
1.270 + bool atFuncStart = true;
1.271 bool isAt = (symbol[0] == '@');
1.272 // we can't support this on windows from here
1.273 if (isAt)
1.274 @@ -294,23 +351,25 @@
1.275
1.276 if (real_bytes >= 1)
1.277 {
1.278 - addr = mu.FindPatternInFile(file, (char*)real_sig, real_bytes);
1.279 + mu.FindPatternInFile(file, (char*)real_sig, real_bytes, matches, atFuncStart);
1.280 }
1.281
1.282 - if (addr)
1.283 - return true;
1.284 + if( !atFuncStart )
1.285 + return -1;
1.286
1.287 - return false;
1.288 + return matches;
1.289 }
1.290
1.291 -bool checkSigStringL(void *handle, const char* symbol)
1.292 +int checkSigStringL(void *handle, const char* symbol)
1.293 {
1.294 - void *addr = NULL;
1.295 bool isAt = (symbol[0] == '@');
1.296 + int matches = 0;
1.297 + bool dummy;
1.298
1.299 if (isAt)
1.300 {
1.301 - addr = mu.ResolveSymbol(handle, symbol + 1);
1.302 + if( mu.ResolveSymbol(handle, symbol + 1) )
1.303 + matches = 1;
1.304 }
1.305 else
1.306 {
1.307 @@ -319,14 +378,11 @@
1.308
1.309 if (real_bytes >= 1)
1.310 {
1.311 - addr = mu.FindPattern(handle, (char*)real_sig, real_bytes);
1.312 + mu.FindPattern(handle, (char*)real_sig, real_bytes, matches, dummy);
1.313 }
1.314 }
1.315
1.316 - if (addr)
1.317 - return true;
1.318 -
1.319 - return false;
1.320 + return matches;
1.321 }
1.322
1.323 /*