private void renderCodeSection(TreeNode root, SmxCodeV1Section code) { root.Tag = new NodeData(delegate() { renderSectionHeaderDetail(code.SectionHeader); addDetailLine("codesize = {0} bytes", code.Header.CodeSize); addDetailLine("cellsize = {0} bytes", code.Header.CellSize); addDetailLine("codeversion = 0x{0:x}", code.Header.CodeVersion); addDetailLine("flags = 0x{0:x} ; {0}", code.Header.Flags, code.Header.Flags.ToString()); addDetailLine("main = 0x{0:x}", code.Header.main); addDetailLine("codeoffs = 0x{0:x}", code.Header.codeoffs); addDetailLine("features = 0x{0:x}", code.Header.features); endDetailUpdate(); }, code); root.Nodes.Add("cell view").Tag = new NodeData(delegate() { renderHexView(code.Reader(), (int)code.Header.CodeSize); }, null); var functionMap = new Dictionary <string, uint>(); if (file_.Publics != null) { foreach (var pubfun in file_.Publics.Entries) { functionMap[pubfun.Name] = pubfun.Address; } } if (file_.DebugSymbols != null) { foreach (var sym in file_.DebugSymbols.Entries) { if (sym.Ident != SymKind.Function) { continue; } functionMap[sym.Name] = sym.CodeStart; } } if (file_.CalledFunctions != null) { foreach (var fun in file_.CalledFunctions.Entries) { functionMap[fun.Name] = fun.Address; } } foreach (var pair in functionMap) { var name = pair.Key; var address = functionMap[pair.Key]; root.Nodes.Add(pair.Key).Tag = new NodeData(delegate() { renderCodeView(code, name, (int)address); }, null); } }
private void renderCodeView(SmxCodeV1Section code, string name, int address) { startDetailUpdate(); V1Instruction[] insns; try { insns = V1Disassembler.Disassemble(file_, code, address); } catch (Exception e) { addDetailLine("Could not disassemble method {0}: {1}", name, e.Message); endDetailUpdate(); return; } addDetailLine("; {0}", name); addDetailLine("; {0} instruction(s)", insns.Length); addDetailLine("; starts at code address 0x{0:x}", address); addDetailLine("---"); if (insns.Length == 0) { endDetailUpdate(); return; } // Find the largest address so we can get consistent column length. int last_address = insns[insns.Length - 1].Address; var ndigits = string.Format("{0:x}", last_address).Length; var addrfmt = "0x{0:x" + ndigits + "}: "; var buffer = new StringBuilder(); var comment = new StringBuilder(); foreach (var insn in insns) { buffer.Clear(); comment.Clear(); buffer.Append(insn.Info.Name); for (var i = 0; i < insn.Params.Length; i++) { if (i >= insn.Info.Params.Length) { break; } var kind = insn.Info.Params[i]; var value = insn.Params[i]; switch (kind) { case V1Param.Constant: case V1Param.CaseTable: buffer.Append(string.Format(" 0x{0:x}", value)); comment.Append(string.Format(" {0}", value)); break; case V1Param.Native: buffer.Append(string.Format(" {0}", value)); if (file_.Natives != null && value < file_.Natives.Length) { comment.Append(string.Format(" {0}", file_.Natives[value].Name)); } break; case V1Param.Jump: int delta = value - insn.Address; buffer.Append(string.Format(" 0x{0:x}", value)); if (delta >= 0) { comment.Append(string.Format(" +0x{0:x}", delta)); } else { comment.Append(string.Format(" -0x{0:x}", -delta)); } break; case V1Param.Address: { DebugSymbolEntry sym = null; if (file_.DebugSymbols != null) { sym = file_.DebugSymbols.FindDataRef(value); } buffer.Append(string.Format(" 0x{0:x}", value)); if (sym != null) { comment.Append(string.Format(" {0}", sym.Name)); } else { comment.Append(string.Format(" {0}", value)); } break; } case V1Param.Stack: { DebugSymbolEntry sym = null; if (file_.DebugSymbols != null) { sym = file_.DebugSymbols.FindStackRef(insn.Address, value); } buffer.Append(string.Format(" 0x{0:x}", value)); if (sym != null) { comment.Append(string.Format(" {0}", sym.Name)); } else { comment.Append(string.Format(" {0}", value)); } break; } case V1Param.Function: string fun = file_.FindFunctionName(value); buffer.Append(string.Format(" 0x{0:x}", value)); comment.Append(string.Format(" {0}", fun)); break; } } detail_buffer_.Append(string.Format(addrfmt, insn.Address)); detail_buffer_.Append(string.Format("{0,-32}", buffer)); if (comment.Length > 0) { detail_buffer_.Append(string.Format(" ;{1}", buffer, comment)); } detail_buffer_.Append("\r\n"); } endDetailUpdate(); }