Beispiel #1
0
        /// <summary>
        /// Build IL header for new method.
        /// </summary>
        /// <param name="methodDef">Definition of new method.</param>
        /// <returns>Metadata token to local variables signature.</returns>
        private uint buildILHeader(MethodDefinition methodDef)
        {
            uint local_var      = methodDef.Body.LocalVarToken.ToUInt32();
            uint code_size      = (uint)methodDef.Body.CodeSize;
            uint max_stack_size = (uint)methodDef.Body.MaxStackSize;
            bool tiny           = methodDef.Body.IsTiny;



            if (!tiny)
            {
                uint header_flags = 0x3013;

                byte[]    sig   = metadata.NewImporter.GetSigantureSA(local_var);
                Signature signa = new Signature(sig);
                signa.Migrate(metadata);
                byte[] sig2 = signa.Compress();
                metadata.OldEmitter.CorMetaDataEmit.GetTokenFromSig(sig2, (uint)sig2.Length, out local_var);

                buffer.AddRange(BitConverter.GetBytes((ushort)header_flags));
                buffer.AddRange(BitConverter.GetBytes((ushort)max_stack_size)); //Util.uintToByteArray(max_stack_size,2));
                buffer.AddRange(BitConverter.GetBytes(code_size));              //.uintToByteArray(code_size));
                buffer.AddRange(BitConverter.GetBytes(local_var));              //.uintToByteArray(local_var));

                return(local_var);
            }
            else
            {
                buffer.Add((byte)((code_size << 2) | 0x2));

                return(0);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Emits scope debugging symbols based on <c>ISymUnmanagedScope</c> insatnce, representing
        /// scope from new assembly.
        /// </summary>
        /// <param name="smScope">Scope from new version of changed assembly.</param>
        /// <param name="placeholder">Placeholder translation for local variables.</param>
        public void EmitScope(ISymUnmanagedScope smScope, Dictionary <int, int> placeholder)
        {
            if (State != WriterState.Building)
            {
                throw new TranslatingException("ISym* interfaces were not initialized.");
            }
            uint scStartOffset = smScope.__GetStartOffset();
            uint scEndOffset   = smScope.__GetEndOffset();

            mWriter.OpenScope(scStartOffset);

            uint localsCount = smScope.__GetLocalCount();

            if (localsCount > 0)
            {
                uint read;
                ISymUnmanagedVariable[] variables = new ISymUnmanagedVariable[localsCount];
                smScope.__GetLocals(localsCount, out read, variables);
                for (int i = 0; i < localsCount; i++)
                {
                    byte[]    signature = variables[i].GetSignature();
                    Signature sig       = new Signature(signature);
                    sig.Migrate(translator);
                    signature = sig.Compress();

                    string name     = variables[i].GetName();
                    uint   addr1    = 0;                             //variables[i].GetAddressField1();
                    uint   addr2    = 0;                             //variables[i].GetAddressField2();
                    uint   addr3    = 0;                             //variables[i].GetAddressField3();
                    uint   addrKind = variables[i].GetAddressKind(); //variables[i].GetAddressKind();
                    if ((variables[i].GetAttributes() & 1) != 1)
                    {
                        addr1    = variables[i].GetAddressField1();
                        addrKind = variables[i].GetAddressKind();
                        if (placeholder != null && placeholder.ContainsKey((int)addr1))
                        {
                            addr1 = (uint)placeholder[(int)addr1];
                        }
                    }
                    uint varStartOffset = scStartOffset;
                    uint varEndOffset   = scEndOffset;
                    uint attributes     = variables[i].GetAttributes();

                    IntPtr pName = Marshal.StringToCoTaskMemUni(name);
                    IntPtr pSig  = Marshal.AllocCoTaskMem(signature.Length);
                    Marshal.Copy(signature, 0, pSig, signature.Length);

                    try{
                        mWriter.DefineLocalVariable(pName, attributes, (uint)signature.Length, pSig, addrKind,
                                                    addr1, addr2, addr3, varStartOffset, varEndOffset);
                    } finally {
                        Marshal.FreeCoTaskMem(pSig);
                        Marshal.FreeCoTaskMem(pName);
                    }
                }
            }
            ISymUnmanagedScope[] subScopes = smScope.GetChildren();
            foreach (ISymUnmanagedScope subScope in subScopes)
            {
                EmitScope(subScope, placeholder);
            }
            mWriter.CloseScope(scEndOffset);
        }
Beispiel #3
0
        //        +-----------------+ 0
        //        |	  delta header  |    ----->> size of the rest of IL in bytes
        //        +-----------------+ 4
        //        |    IL header    |
        //		  +-----------------+
        //        |				    |
        //		  |	    IL code     |
        //		  |				    |
        //		  +-----------------+

        /// <summary>
        /// Builds header of changing method.
        /// </summary>
        /// <param name="newMethod">MethodDefinition of new version of changing method.</param>
        /// <param name="originMethod">MethoDefinition of original version of changing method.</param>
        /// <param name="tkMethod">Metadata token pointing to place of method in running version of metadata.</param>
        /// <param name="remapper">IL offset remapper, used to build local variable changes.</param>
        /// <param name="placeholder">Product of method, represents translation from old variable set to the new one.</param>
        /// <returns>Metadata token pointing to lolcalVars signature, if not present, 0 is given.</returns>
        private uint buildILHeader(MethodDefinition newMethod, MethodDefinition originMethod,
                                   SequencePointRemapper remapper, out Dictionary <int, int> placeholder)
        {
            uint local_var_old, token;
            uint local_var      = newMethod.Body.LocalVarToken.ToUInt32();
            uint code_size      = (uint)newMethod.Body.CodeSize;
            uint max_stack_size = (uint)newMethod.Body.MaxStackSize;
            bool old_tiny       = originMethod.Body.IsTiny;
            bool tiny           = newMethod.Body.IsTiny;

            placeholder = null;

            if (old_tiny && !tiny)
            {
                // when new method is fat and the old tiny
                byte[]    sig   = metadata.NewImporter.GetSigantureSA(local_var);
                Signature signa = new Signature(sig);
                signa.Migrate(metadata);
                byte[] sig2 = signa.Compress();
                metadata.OldEmitter.CorMetaDataEmit.GetTokenFromSig(sig2, (uint)sig2.Length, out token);
                tiny = false;
            }
            else if (!old_tiny && tiny)
            {
                // when new method is tiny and old fat
                local_var_old  = originMethod.Body.LocalVarToken.ToUInt32();
                local_var      = local_var_old;
                max_stack_size = 8;
                tiny           = false;
            }
            else if (!old_tiny && !tiny)
            {
                // both methods are fat
                Signature sigNew = new Signature(metadata.NewImporter.GetSigantureSA(local_var));
                Signature sigOld = new Signature(metadata.OldImporter.GetSigantureSA(originMethod.Body.LocalVarToken.ToUInt32()));
                sigNew.Migrate(metadata);

                // Instead of unused old local variables use placeholders
                LocalVarDiff varDiff = new LocalVarDiff(Builder.Manager.ResourceManager.CurrentModule.SymReader,
                                                        Builder.SymbolWriter.CorSymNewReader, remapper);

                byte[] sig = varDiff.makeSignature(sigOld, sigNew, out placeholder, originMethod.MetadataToken.ToUInt32(),
                                                   newMethod.MetadataToken.ToUInt32(), metadata).Compress();

                metadata.OldEmitter.CorMetaDataEmit.GetTokenFromSig(sig, (uint)sig.Length, out local_var);
            }

            //there is no need to change IL and MetaData when both methods are tiny

            if (!tiny)
            {
                uint header_flags = 0x3013;

                buffer.AddRange(BitConverter.GetBytes((ushort)header_flags));   //BitConverter.GetBytes((ushort)header_flags));//.uintToByteArray(header_flags,2));
                buffer.AddRange(BitConverter.GetBytes((ushort)max_stack_size)); //Util.uintToByteArray(max_stack_size,2));
                buffer.AddRange(BitConverter.GetBytes(code_size));              //.uintToByteArray(code_size));
                buffer.AddRange(BitConverter.GetBytes(local_var));              //.uintToByteArray(local_var));

                originMethod.Body.LocalVarToken = new MetadataToken(local_var);
                return(local_var);
            }
            else
            {
                buffer.Add((byte)((code_size << 2) | 0x2));

                return(0);
            }
        }