private void CreateLocalScopeAndLocalVariables(LocalScopeTable localScope, LocalVariableTable localVariable, ImportScopeTable importScope) { var methods = this.methods.ToArray(); Array.Sort(methods, (m1, m2) => tokenMap[m1.Token].CompareTo(tokenMap[m2.Token])); for (var i = 0; i < methods.Length; i++) { var scopes = methods[i].Scopes; Array.Sort(scopes, (s1, s2) => s1.StartOffset != s2.StartOffset ? s1.StartOffset.CompareTo(s2.StartOffset) : s2.Length.CompareTo(s1.Length)); for (var j = 0; j < scopes.Length; j++) { LocalScopeTable.Record scope; scope.Method = tokenMap[methods[i].Token] & 0xFFFFFF; // TODO we don't set the parent ImportScope, because Visual Studio doesn't seem to need it scope.ImportScope = importScope.FindOrAddRecord(0, CreateNamespaceImportBlob(scopes[j].Namespaces)); scope.VariableList = localVariable.RowCount + 1; scope.ConstantList = 1; scope.StartOffset = scopes[j].StartOffset; scope.Length = scopes[j].Length; localScope.AddRecord(scope); for (var k = 0; k < scopes[j].VariableList.Count; k++) { LocalVariableTable.Record variable; variable.Attributes = 0; variable.Index = (short)scopes[j].VariableList[k].Index; variable.Name = Strings.Add(scopes[j].VariableList[k].Name); localVariable.AddRecord(variable); } } } }
/// <summary> /// Constructor. lvt will be null when creating a new entry. /// </summary> public EditLocalVariableTable(Window owner, DisasmProject project, Formatter formatter, LocalVariableTable lvt, int offset) { InitializeComponent(); Owner = owner; DataContext = this; mProject = project; mFormatter = formatter; mSymbolTable = project.SymbolTable; mOffset = NewOffset = offset; if (lvt != null) { mWorkTable = new LocalVariableTable(lvt); mIsNotNewTable = true; } else { mWorkTable = new LocalVariableTable(); } for (int i = 0; i < mWorkTable.Count; i++) { DefSymbol defSym = mWorkTable[i]; Variables.Add(CreateFormattedSymbol(defSym)); } }
public void Close() { var localScope = new LocalScopeTable(); var localVariable = new LocalVariableTable(); var importScope = new ImportScopeTable(); CreateLocalScopeAndLocalVariables(localScope, localVariable, importScope); Strings.Freeze(); UserStrings.Freeze(); Guids.Freeze(); Blobs.Freeze(); using (var fs = System.IO.File.Create(fileName)) { var tablesForRowCountOnly = moduleBuilder.GetTables(); var tables = new Table[64]; tables[DocumentTable.Index] = Document; tables[MethodDebugInformationTable.Index] = CreateMethodDebugInformation(); tables[LocalScopeTable.Index] = localScope; tables[LocalVariableTable.Index] = localVariable; tables[ImportScopeTable.Index] = importScope; for (var i = 0; i < tables.Length; i++) { if (tables[i] != null) { tablesForRowCountOnly[i] = tables[i]; } } var mw = new PortablePdbMetadataWriter(fs, tables, tablesForRowCountOnly, Strings.IsBig, Guids.IsBig, Blobs.IsBig); Tables.Freeze(mw); var pdb = new PdbHeap(guid, timestamp, moduleBuilder.GetTables(), GetEntryPointToken()); mw.WriteMetadata("PDB v1.0", pdb, Tables, Strings, UserStrings, Guids, Blobs); if (IsDeterministic) { byte[] hash; using (var sha1 = System.Security.Cryptography.SHA1.Create()) { fs.Seek(0, System.IO.SeekOrigin.Begin); hash = sha1.ComputeHash(fs); } timestamp = (uint)BitConverter.ToInt32(hash, 16) | 0x80000000; Array.Resize(ref hash, 16); // set GUID type to "version 4" (random) hash[7] &= 0x0F; hash[7] |= 0x40; hash[8] &= 0x3F; hash[8] |= 0x80; guid = new Guid(hash); fs.Position = pdb.PositionPdbId; PdbHeap.WritePdbId(mw, guid, timestamp); } } }
// IGenerator public void OutputLocalVariableTable(int offset, List <DefSymbol> newDefs, LocalVariableTable allDefs) { foreach (DefSymbol defSym in newDefs) { string valueStr = PseudoOp.FormatNumericOperand(SourceFormatter, Project.SymbolTable, null, defSym.DataDescriptor, defSym.Value, 1, PseudoOp.FormatNumericOpFlags.OmitLabelPrefixSuffix); OutputLine(SourceFormatter.FormatVariableLabel(defSym.Label), SourceFormatter.FormatPseudoOp(sDataOpNames.VarDirective), valueStr, SourceFormatter.FormatEolComment(defSym.Comment)); } }
// IGenerator public void OutputLocalVariableTable(int offset, List <DefSymbol> newDefs, LocalVariableTable allDefs) { foreach (DefSymbol defSym in newDefs) { // Use an operand length of 1 so values are shown as concisely as possible. string valueStr = PseudoOp.FormatNumericOperand(SourceFormatter, Project.SymbolTable, null, defSym.DataDescriptor, defSym.Value, 1, PseudoOp.FormatNumericOpFlags.None); OutputLine(SourceFormatter.FormatVariableLabel(defSym.Label), SourceFormatter.FormatPseudoOp(sDataOpNames.VarDirective), valueStr, SourceFormatter.FormatEolComment(defSym.Comment)); } }
// IGenerator public void OutputLocalVariableTable(int offset, List <DefSymbol> newDefs, LocalVariableTable allDefs) { OutputLine(string.Empty, "!zone", "Z" + offset.ToString("x6"), string.Empty); for (int i = 0; i < allDefs.Count; i++) { DefSymbol defSym = allDefs[i]; string valueStr = PseudoOp.FormatNumericOperand(SourceFormatter, Project.SymbolTable, null, defSym.DataDescriptor, defSym.Value, 1, PseudoOp.FormatNumericOpFlags.None); OutputEquDirective(SourceFormatter.FormatVariableLabel(defSym.Label), valueStr, defSym.Comment); } }
public static AttributeInfo Read(ClassReader classReader, ConstantPool constantPool) { ushort attributeNameIndex = classReader.ReadU2(); string attributeName = Encoding.UTF8.GetString(((ConstantUtf8)constantPool.ConstantPoolInfo[attributeNameIndex]).Bytes); AttributeInfo attributeInfo = null; switch (attributeName) { case "ConstantValue": attributeInfo = new ConstantValue(); break; case "Code": attributeInfo = new Code(); break; case "Deprecated": attributeInfo = new Deprecated(); break; case "LineNumberTable": attributeInfo = new LineNumberTable(); break; case "LocalVariableTable": attributeInfo = new LocalVariableTable(); break; case "SourceFile": attributeInfo = new SourceFile(); break; case "Synthetic": attributeInfo = new Synthetic(); break; case "Exceptions": attributeInfo = new Exceptions(); break; case "Signature": attributeInfo = new Signature(); break; //case "StackMapTable": // attributeInfo = null; default: throw new Exception("no such attribute error"); } attributeInfo.AttributeName = attributeName; attributeInfo.ReadAttributeInfo(classReader, constantPool); return(attributeInfo); }
// IGenerator public void OutputLocalVariableTable(int offset, List <DefSymbol> newDefs, LocalVariableTable allDefs) { // We can do better here, but it requires knowing whether anything in "newDefs" // overwrote a previous entry. If everything is new, we don't need to start // a new zone, and can just output newDefs. (We don't need to start a new zone // on a "clear previous".) OutputLine(string.Empty, "!zone", "Z" + offset.ToString("x6"), string.Empty); for (int i = 0; i < allDefs.Count; i++) { DefSymbol defSym = allDefs[i]; string valueStr = PseudoOp.FormatNumericOperand(SourceFormatter, Project.SymbolTable, null, defSym.DataDescriptor, defSym.Value, 1, PseudoOp.FormatNumericOpFlags.OmitLabelPrefixSuffix); OutputEquDirective(SourceFormatter.FormatVariableLabel(defSym.Label), valueStr, defSym.Comment); } }
private void GenerateDebugInfo(int prologSize) { Messages.Verbose(" Generating debug info..."); sourceFileNameCounter = new Counter <string>(); Messages.Verbose(" Generating LocalVariableTable..."); #region LocalVariableTable LocalVariableTable varTable = new LocalVariableTable(); for (int i = 0; i < nextVarIndex; i++) { LocalVariableTable.LocalVariable varDesc = new LocalVariableTable.LocalVariable(); varDesc.Index = (ushort)i; ILVariable ilVar = var2Index.Where(K => K.Value == i).FirstOrDefault().Key; if ((ilVar != null) && (ilVar.Name != ClassNames.VarArgParamName)) { varDesc.Name = null; if (ilVar.IsGenerated) { varDesc.Name = "gen_" + i.ToString(); } else if (ilVar.IsParameter) { varDesc.Name = ilVar.OriginalParameter.Name; } else if (ilVar.OriginalVariable != null) { varDesc.Name = ilVar.OriginalVariable.Name; } if ((varDesc.Name == null) || (varDesc.Name.Length == 0)) { varDesc.Name = ilVar.Name ?? "unknown_" + i.ToString(); } if (ilVar.Name == "this") { if (thisMethod.DeclaringType.IsPrimitive) { varDesc.Descriptor = "L" + namesController.TypeNameToJava(thisMethod.DeclaringType.CILBoxType) + ";"; } else { varDesc.Descriptor = namesController.GetFieldDescriptor(thisMethod.DeclaringType); } } else { varDesc.Descriptor = namesController.GetFieldDescriptor(resolver.Resolve(ilVar.Type, thisMethod.FullGenericArguments)); } varDesc.StartPC = 0; varDesc.Length = (ushort)resultCode.CodeBytes.Length; varTable.Table.Add(varDesc); } else if ((ilVar != null) && (ilVar.Name == ClassNames.VarArgParamName)) { varDesc.Name = ClassNames.VarArgParamName; varDesc.Descriptor = "Ljava/lang/Object;"; varDesc.StartPC = 0; varDesc.Length = (ushort)resultCode.CodeBytes.Length; varTable.Table.Add(varDesc); } else { var tmpVarsList = tempVars.Where(TV => TV.index == i); int additionalIndex = 0; foreach (var tmpVar in tmpVarsList) { varDesc.Name = "temp_" + i.ToString() + "_" + (additionalIndex++).ToString(); switch (tmpVar.type) { case JavaPrimitiveType.Bool: varDesc.Descriptor = "Z"; break; case JavaPrimitiveType.Byte: varDesc.Descriptor = "B"; break; case JavaPrimitiveType.Char: varDesc.Descriptor = "C"; break; case JavaPrimitiveType.Double: varDesc.Descriptor = "D"; break; case JavaPrimitiveType.Float: varDesc.Descriptor = "F"; break; case JavaPrimitiveType.Int: varDesc.Descriptor = "I"; break; case JavaPrimitiveType.Long: varDesc.Descriptor = "J"; break; case JavaPrimitiveType.Short: varDesc.Descriptor = "S"; break; default: varDesc.Descriptor = "Ljava/lang/Object;"; break; } int start = oldCodeGenerator.GetInstructionOffset(tmpVar.startInstr) + prologSize; int end = resultCode.CodeBytes.Length; if (tmpVar.endInstr >= 0) { end = oldCodeGenerator.GetInstructionOffset(tmpVar.endInstr) + prologSize; } varDesc.StartPC = (ushort)(start); varDesc.Length = (ushort)(end - start); varTable.Table.Add(varDesc); } } } resultCode.Attributes.Add(varTable); #endregion Messages.Verbose(" Generating LineNumberTable..."); #region LineNumberTable LineNumberTable linesTable = new LineNumberTable(); int lastLine = -1; var methodInstructions = thisMethod.Body.Instructions; foreach (var i in oldCodeGenerator.EnumerateInstructions()) { ILExpression tag = i.Item2.Tag as ILExpression; if (tag == null) { continue; } if ((tag.ILRanges == null) || (tag.ILRanges.Count == 0)) { continue; } int minRange = tag.ILRanges.Min(R => R.From); int maxRange = tag.ILRanges.Max(R => R.To); var ilInstruction = methodInstructions.Where(I => I.Offset >= minRange && I.Offset < maxRange).LastOrDefault(); if (ilInstruction == null) { continue; } if (ilInstruction.SequencePoint == null) { continue; } int line = ilInstruction.SequencePoint.StartLine; sourceFileNameCounter.Add(ilInstruction.SequencePoint.Document.Url); if (line == lastLine) { continue; } linesTable.Table.Add(new LineNumberTable.LineNumber((ushort)(i.Item1 + prologSize), (ushort)line)); lastLine = line; } resultCode.Attributes.Add(linesTable); #endregion }