Exemple #1
0
        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);
                    }
                }
            }
        }
Exemple #2
0
        /// <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));
            }
        }
Exemple #3
0
        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);
                }
            }
        }
Exemple #4
0
 // 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));
     }
 }
Exemple #5
0
 // 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));
     }
 }
Exemple #6
0
        // 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);
            }
        }
Exemple #7
0
        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);
        }
Exemple #8
0
        // 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);
            }
        }
Exemple #9
0
        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
        }