Esempio n. 1
0
        PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody body, SymbolScope symScope)
        {
            if (symScope == null)
            {
                return(null);
            }

            // Don't use recursive calls
            var stack = new Stack <CreateScopeState>();
            var state = new CreateScopeState()
            {
                SymScope = symScope
            };

recursive_call:
            int instrIndex = 0;
            int endIsInclusiveValue = Compiler == Compiler.VisualBasic ? 1 : 0;

            state.PdbScope = new PdbScope()
            {
                Start = GetInstruction(body.Instructions, state.SymScope.StartOffset, ref instrIndex),
                End   = GetInstruction(body.Instructions, state.SymScope.EndOffset + endIsInclusiveValue, ref instrIndex),
            };
            foreach (var cdi in state.SymScope.CustomDebugInfos)
            {
                state.PdbScope.CustomDebugInfos.Add(cdi);
            }

            foreach (var symLocal in state.SymScope.Locals)
            {
                int localIndex = symLocal.Index;
                if ((uint)localIndex >= (uint)body.Variables.Count)
                {
                    // VB sometimes creates a PDB local without a metadata local
                    continue;
                }
                var local = body.Variables[localIndex];
                var name  = symLocal.Name;
                local.SetName(name);
                var attributes = symLocal.Attributes;
                local.SetAttributes(attributes);
                var pdbLocal = new PdbLocal(local, name, attributes);
                foreach (var cdi in symLocal.CustomDebugInfos)
                {
                    pdbLocal.CustomDebugInfos.Add(cdi);
                }
                state.PdbScope.Variables.Add(pdbLocal);
            }

            foreach (var ns in state.SymScope.Namespaces)
            {
                state.PdbScope.Namespaces.Add(ns.Name);
            }
            state.PdbScope.ImportScope = state.SymScope.ImportScope;

            var constants = state.SymScope.GetConstants(module, gpContext);

            for (int i = 0; i < constants.Count; i++)
            {
                var constant = constants[i];
                var type     = constant.Type.RemovePinnedAndModifiers();
                if (type != null)
                {
                    // Fix a few values since they're stored as some other type in the PDB
                    switch (type.ElementType)
                    {
                    case ElementType.Boolean:
                        if (constant.Value is short)
                        {
                            constant.Value = (short)constant.Value != 0;
                        }
                        break;

                    case ElementType.Char:
                        if (constant.Value is ushort)
                        {
                            constant.Value = (char)(ushort)constant.Value;
                        }
                        break;

                    case ElementType.I1:
                        if (constant.Value is short)
                        {
                            constant.Value = (sbyte)(short)constant.Value;
                        }
                        break;

                    case ElementType.U1:
                        if (constant.Value is short)
                        {
                            constant.Value = (byte)(short)constant.Value;
                        }
                        break;

                    case ElementType.I2:
                    case ElementType.U2:
                    case ElementType.I4:
                    case ElementType.U4:
                    case ElementType.I8:
                    case ElementType.U8:
                    case ElementType.R4:
                    case ElementType.R8:
                    case ElementType.Void:
                    case ElementType.Ptr:
                    case ElementType.ByRef:
                    case ElementType.TypedByRef:
                    case ElementType.I:
                    case ElementType.U:
                    case ElementType.FnPtr:
                    case ElementType.ValueType:
                        break;

                    case ElementType.String:
                        // "" is stored as null, and null is stored as (int)0
                        if (constant.Value is int && (int)constant.Value == 0)
                        {
                            constant.Value = null;
                        }
                        else if (constant.Value == null)
                        {
                            constant.Value = string.Empty;
                        }
                        break;

                    case ElementType.Object:
                    case ElementType.Class:
                    case ElementType.SZArray:
                    case ElementType.Array:
                    default:
                        if (constant.Value is int && (int)constant.Value == 0)
                        {
                            constant.Value = null;
                        }
                        break;

                    case ElementType.GenericInst:
                        var gis = (GenericInstSig)type;
                        if (gis.GenericType is ValueTypeSig)
                        {
                            break;
                        }
                        goto case ElementType.Class;

                    case ElementType.Var:
                    case ElementType.MVar:
                        var gp = ((GenericSig)type).GenericParam;
                        if (gp != null)
                        {
                            if (gp.HasNotNullableValueTypeConstraint)
                            {
                                break;
                            }
                            if (gp.HasReferenceTypeConstraint)
                            {
                                goto case ElementType.Class;
                            }
                        }
                        break;
                    }
                }
                state.PdbScope.Constants.Add(constant);
            }

            // Here's the now somewhat obfuscated for loop
            state.ChildrenIndex = 0;
            state.Children      = state.SymScope.Children;
do_return:
            if (state.ChildrenIndex < state.Children.Count)
            {
                var child = state.Children[state.ChildrenIndex];
                stack.Push(state);
                state = new CreateScopeState()
                {
                    SymScope = child
                };
                goto recursive_call;
            }

            if (stack.Count == 0)
            {
                return(state.PdbScope);
            }

            // Return from recursive call, and execute the last part of the for loop
            var newPdbScope = state.PdbScope;

            state = stack.Pop();
            state.PdbScope.Scopes.Add(newPdbScope);
            state.ChildrenIndex++;
            goto do_return;
        }
Esempio n. 2
0
        static PdbScope CreateScope(CilBody body, ISymbolScope symScope)
        {
            if (symScope == null)
            {
                return(null);
            }

            // Don't use recursive calls
            var stack = new Stack <CreateScopeState>();
            var state = new CreateScopeState()
            {
                SymScope = symScope
            };

recursive_call:
            int instrIndex = 0;

            state.PdbScope = new PdbScope()
            {
                Start = GetInstruction(body.Instructions, state.SymScope.StartOffset, ref instrIndex),
                End   = GetInstruction(body.Instructions, state.SymScope.EndOffset, ref instrIndex),
            };

            foreach (var symLocal in state.SymScope.GetLocals())
            {
                if (symLocal.AddressKind != SymAddressKind.ILOffset)
                {
                    continue;
                }

                int localIndex = symLocal.AddressField1;
                if ((uint)localIndex >= (uint)body.Variables.Count)
                {
                    continue;
                }
                var local = body.Variables[localIndex];
                local.Name = symLocal.Name;
                var attributes = symLocal.Attributes;
                if (attributes is int)
                {
                    local.PdbAttributes = (int)attributes;
                }
                state.PdbScope.Variables.Add(local);
            }

            foreach (var ns in state.SymScope.GetNamespaces())
            {
                state.PdbScope.Namespaces.Add(ns.Name);
            }

            // Here's the now somewhat obfuscated for loop
            state.ChildrenIndex = 0;
            state.Children      = state.SymScope.GetChildren();
do_return:
            if (state.ChildrenIndex < state.Children.Length)
            {
                var child = state.Children[state.ChildrenIndex];
                stack.Push(state);
                state = new CreateScopeState()
                {
                    SymScope = child
                };
                goto recursive_call;
            }

            if (stack.Count == 0)
            {
                return(state.PdbScope);
            }

            // Return from recursive call, and execute the last part of the for loop
            var newPdbScope = state.PdbScope;

            state = stack.Pop();
            state.PdbScope.Scopes.Add(newPdbScope);
            state.ChildrenIndex++;
            goto do_return;
        }
Esempio n. 3
0
		static PdbScope CreateScope(CilBody body, ISymbolScope symScope) {
			if (symScope == null)
				return null;

			// Don't use recursive calls
			var stack = new Stack<CreateScopeState>();
			var state = new CreateScopeState() { SymScope = symScope };
recursive_call:
			int instrIndex = 0;
			state.PdbScope = new PdbScope() {
				Start = GetInstruction(body.Instructions, state.SymScope.StartOffset, ref instrIndex),
				End   = GetInstruction(body.Instructions, state.SymScope.EndOffset, ref instrIndex),
			};

			foreach (var symLocal in state.SymScope.GetLocals()) {
				if (symLocal.AddressKind != SymAddressKind.ILOffset)
					continue;

				int localIndex = symLocal.AddressField1;
				if ((uint)localIndex >= (uint)body.Variables.Count)
					continue;
				var local = body.Variables[localIndex];
				local.Name = symLocal.Name;
				var attributes = symLocal.Attributes;
				if (attributes is int)
					local.PdbAttributes = (int)attributes;
				state.PdbScope.Variables.Add(local);
			}

			foreach (var ns in state.SymScope.GetNamespaces())
				state.PdbScope.Namespaces.Add(ns.Name);

			// Here's the now somewhat obfuscated for loop
			state.ChildrenIndex = 0;
			state.Children = state.SymScope.GetChildren();
do_return:
			if (state.ChildrenIndex < state.Children.Length) {
				var child = state.Children[state.ChildrenIndex];
				stack.Push(state);
				state = new CreateScopeState() { SymScope = child };
				goto recursive_call;
			}

			if (stack.Count == 0)
				return state.PdbScope;

			// Return from recursive call, and execute the last part of the for loop
			var newPdbScope = state.PdbScope;
			state = stack.Pop();
			state.PdbScope.Scopes.Add(newPdbScope);
			state.ChildrenIndex++;
			goto do_return;
		}