Explorar o código

started memory inspector

Nicolas Cannasse %!s(int64=8) %!d(string=hai) anos
pai
achega
c1e0460d12
Modificáronse 2 ficheiros con 217 adicións e 0 borrados
  1. 164 0
      other/memory/Memory.hx
  2. 53 0
      other/memory/memory.hxproj

+ 164 - 0
other/memory/Memory.hx

@@ -0,0 +1,164 @@
+import format.hl.Data;
+
+abstract Pointer(Int) {
+	public inline function isNull() {
+		return this == 0;
+	}
+}
+
+class Page {
+	public var addr : Pointer;
+	public var kind : Int;
+	public var size : Int;
+	public var blockSize : Int;
+	public var firstBlock : Int;
+	public var maxBlocks : Int;
+	public var nextBlock : Int;
+	public var dataPosition : Int;
+	public var bmp : haxe.io.Bytes;
+	public var sizes : haxe.io.Bytes;
+
+	public function new() {
+	}
+
+	public function isLiveBlock( bid : Int ) {
+		if( bmp == null ) return true;
+		return bmp.get(bid >> 3)
+	}
+}
+
+class Stack {
+	public var base : Pointer;
+	public var contents : Array<Pointer>;
+	public function new() {
+	}
+}
+
+class Memory {
+
+	var memoryDump : sys.io.FileInput;
+	var code : format.hl.Data;
+	var is64 : Bool;
+	var pages : Array<Page>;
+	var roots : Array<Pointer>;
+	var stacks : Array<Stack>;
+	var types : Array<Pointer>;
+	var pointerType : Map<Pointer, HLType>;
+
+	function new() {
+	}
+
+	function loadBytecode( arg : String ) {
+		if( code != null ) throw "Duplicate code";
+		code = new format.hl.Reader(false).read(new haxe.io.BytesInput(sys.io.File.getBytes(arg)));
+		log(arg + " code loaded");
+	}
+
+	inline function readInt() {
+		return memoryDump.readInt32();
+	}
+
+	inline function readPointer() : Pointer {
+		return cast memoryDump.readInt32();
+	}
+
+	function loadMemory( arg : String ) {
+		memoryDump = sys.io.File.read(arg);
+		if( memoryDump.read(3).toString() != "HMD" )
+			throw "Invalid memory dump file";
+		var version = memoryDump.readByte() - "0".code;
+		var flags = readInt();
+		is64 = (flags & 1) != 0;
+		if( is64 ) throw "64 bit not supported";
+
+		// load pages
+		var count = readInt();
+		var totalSize = 0;
+		pages = [];
+		for( i in 0...count ) {
+			while( true ) {
+				var addr = readPointer();
+				if( addr.isNull() ) break;
+				var p = new Page();
+				p.addr = addr;
+				p.kind = readInt();
+				p.size = readInt();
+				p.blockSize = readInt();
+				p.firstBlock = readInt();
+				p.maxBlocks = readInt();
+				p.nextBlock = readInt();
+
+				var flags = readInt();
+				p.dataPosition = memoryDump.tell();
+				memoryDump.seek(p.size, SeekCur);
+				if( flags & 1 != 0 )
+					p.bmp = memoryDump.read((p.maxBlocks + 7) >> 3); // 1 bit per block
+				if( flags & 2 != 0 )
+					p.sizes = memoryDump.read(p.maxBlocks); // 1 byte per block
+				pages.push(p);
+				totalSize += p.size;
+			}
+		}
+		log(pages.length + " pages, " + (totalSize >> 10) + "KB memory");
+
+		// load roots
+		roots = [for( i in 0...readInt() ) readPointer()];
+		log(roots.length + " roots");
+
+		// load stacks
+		stacks = [];
+		for( i in 0...readInt() ) {
+			var s = new Stack();
+			s.base = readPointer();
+			s.contents = [for( i in 0...readInt() ) readPointer()];
+			stacks.push(s);
+		}
+		log(stacks.length + " stacks");
+
+		// load types
+		types = [for( i in 0...readInt() ) readPointer()];
+		log(types.length + " types");
+	}
+
+	function check() {
+		if( code == null ) throw "Missing .hl file";
+		if( memoryDump == null ) throw "Missing .dump file";
+		if( code.types.length != this.types.length ) throw "Types count mismatch";
+
+		pointerType = new Map();
+		for( i in 0...types.length )
+			pointerType.set(types[i], code.types[i]);
+
+		for( p in pages ) {
+			var bid = p.firstBlock;
+			while( bid < p.maxBlocks ) {
+				if( !p.isBlockLive(bid) ) {
+					bid++;
+					continue;
+				}
+				count++;
+			}
+		}
+		log(count + " live blocks");
+	}
+
+	function log(msg:String) {
+		Sys.println(msg);
+	}
+
+	static function main() {
+		var m = new Memory();
+
+		var args = Sys.args();
+		while( args.length > 0 ) {
+			var arg = args.shift();
+			if( StringTools.endsWith(arg, ".hl") ) {
+				m.loadBytecode(arg);
+				continue;
+			}
+			m.loadMemory(arg);
+		}
+		m.check();
+	}
+
+}

+ 53 - 0
other/memory/memory.hxproj

@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<project version="2">
+  <!-- Output SWF options -->
+  <output>
+    <movie outputType="CustomBuild" />
+    <movie input="" />
+    <movie path="" />
+    <movie fps="0" />
+    <movie width="0" />
+    <movie height="0" />
+    <movie version="0" />
+    <movie minorVersion="0" />
+    <movie platform="JavaScript" />
+    <movie background="#FFFFFF" />
+  </output>
+  <!-- Other classes to be compiled into your SWF -->
+  <classpaths>
+    <!-- example: <class path="..." /> -->
+  </classpaths>
+  <!-- Build options -->
+  <build>
+    <option directives="" />
+    <option flashStrict="False" />
+    <option noInlineOnDebug="False" />
+    <option mainClass="" />
+    <option enabledebug="False" />
+    <option additional="-lib format" />
+  </build>
+  <!-- haxelib libraries -->
+  <haxelib>
+    <!-- example: <library name="..." /> -->
+  </haxelib>
+  <!-- Class files to compile (other referenced classes will automatically be included) -->
+  <compileTargets>
+    <!-- example: <compile path="..." /> -->
+  </compileTargets>
+  <!-- Paths to exclude from the Project Explorer tree -->
+  <hiddenPaths>
+    <hidden path="obj" />
+  </hiddenPaths>
+  <!-- Executed before build -->
+  <preBuildCommand>haxe -hl memory.hl -main Memory -lib format</preBuildCommand>
+  <!-- Executed after build -->
+  <postBuildCommand alwaysRun="False" />
+  <!-- Other project options -->
+  <options>
+    <option showHiddenPaths="False" />
+    <option testMovie="Custom" />
+    <option testMovieCommand="run.bat" />
+  </options>
+  <!-- Plugin storage -->
+  <storage />
+</project>