void LinearAnalysis::AnalyseFunctions() { for(size_t i = 0; i < _functions.size(); i++) { FunctionInfo & function = _functions[i]; if(function.end) //skip already-analysed functions continue; duint maxaddr = _base + _size; if(i < _functions.size() - 1) maxaddr = _functions[i + 1].start; duint end = FindFunctionEnd(function.start, maxaddr); if(end) { if(_cp.Disassemble(end, TranslateAddress(end), MAX_DISASM_BUFFER)) function.end = end + _cp.Size() - 1; else function.end = end; } } }
static int l_persist_dofile(lua_State *L) { const char *sFilename = luaL_checkstring(L, 1); lua_settop(L, 1); // Read entire file into memory FILE *fFile = fopen(sFilename, "r"); if(fFile == NULL) { const char *sError = strerror(errno); return luaL_error(L, "cannot open %s: %s", sFilename, sError); } size_t iBufferSize = lua_objlen(L, lua_upvalueindex(1)); size_t iBufferUsed = 0; while(!feof(fFile)) { iBufferUsed += fread(reinterpret_cast<char*>(lua_touserdata(L, lua_upvalueindex(1))) + iBufferUsed, 1, iBufferSize - iBufferUsed, fFile); if(iBufferUsed == iBufferSize) { iBufferSize *= 2; memcpy(lua_newuserdata(L, iBufferSize), lua_touserdata(L, lua_upvalueindex(1)), iBufferUsed); lua_replace(L, lua_upvalueindex(1)); } else break; } int iStatus = ferror(fFile); fclose(fFile); if(iStatus) { const char *sError = strerror(errno); return luaL_error(L, "cannot read %s: %s", sFilename, sError); } // Check file char *sFile = reinterpret_cast<char*>(lua_touserdata(L, lua_upvalueindex(1))); sFile[iBufferUsed] = 0; if(sFile[0] == '#') { do { ++sFile; --iBufferUsed; } while(sFile[0] != 0 && sFile[0] != '\r' && sFile[0] != '\n'); } if(sFile[0] == LUA_SIGNATURE[0]) { return luaL_error(L, "cannot load %s: compiled files not permitted", sFilename); } // Load and do file lua_pushliteral(L, "@"); lua_pushvalue(L, 1); lua_concat(L, 2); if(luaL_loadbuffer(L, sFile, iBufferUsed, lua_tostring(L, -1)) != 0) return lua_error(L); lua_remove(L, -2); int iBufferCopyIndex = lua_gettop(L); memcpy(lua_newuserdata(L, iBufferUsed + 1), sFile, iBufferUsed + 1); lua_insert(L, -2); lua_call(L, 0, LUA_MULTRET); sFile = reinterpret_cast<char*>(lua_touserdata(L, lua_upvalueindex(1))); memcpy(sFile, lua_touserdata(L, iBufferCopyIndex), iBufferUsed + 1); lua_remove(L, iBufferCopyIndex); // Extract persistable functions const char *sPosition = sFile; while(true) { sPosition = strstr(sPosition, "--[[persistable:"); if(!sPosition) break; sPosition += 16; const char *sNameEnd = strstr(sPosition, "]]"); if(sNameEnd) { int iLineNumber = CalculateLineNumber(sFile, sNameEnd); const char *sFunctionArgs = strchr(sNameEnd + 2, '('); const char *sFunctionEnd = FindFunctionEnd(L, sFunctionArgs); if((sNameEnd - sPosition) == 1 && *sPosition == ':') { // --[[persistable::]] means take the existing name of the function sPosition = strstr(sNameEnd, "function") + 8; sPosition += strspn(sPosition, " \t"); sNameEnd = sFunctionArgs; while(sNameEnd[-1] == ' ') --sNameEnd; } if(iLineNumber != -1 && sFunctionArgs && sFunctionEnd) { // Save <filename>:<line> => <name> lua_pushfstring(L, "%s:%d", sFilename, iLineNumber); lua_pushvalue(L, -1); lua_gettable(L, lua_upvalueindex(2)); if(lua_isnil(L, -1)) { lua_pop(L, 1); lua_pushlstring(L, sPosition, sNameEnd - sPosition); lua_settable(L, lua_upvalueindex(2)); } else { return luaL_error(L, "Multiple persistable functions defin" "ed on the same line (%s:%d)", sFilename, iLineNumber); } // Save <name> => <filename> lua_pushlstring(L, sPosition, sNameEnd - sPosition); lua_pushvalue(L, -1); lua_gettable(L, lua_upvalueindex(3)); if(lua_isnil(L, -1)) { lua_pop(L, 1); lua_pushvalue(L, 1); lua_settable(L, lua_upvalueindex(3)); } else { return luaL_error(L, "Persistable function name \'%s\' is" " not unique (defined in both %s and %s)", lua_tostring(L, -2), lua_tostring(L, -1), sFilename); } // Save <name> => <code> lua_pushlstring(L, sPosition, sNameEnd - sPosition); lua_pushliteral(L, "\n"); lua_getfield(L, -1, "rep"); lua_insert(L, -2); lua_pushinteger(L, iLineNumber - 1); lua_call(L, 2, 1); lua_pushliteral(L, "function"); lua_pushlstring(L, sFunctionArgs, sFunctionEnd - sFunctionArgs); lua_concat(L, 3); lua_settable(L, lua_upvalueindex(4)); } } } // Finish return lua_gettop(L) - 1; }