Exemple #1
0
        private void DisassembleMethod(ClrMethod method)
        {
            var module = method.Type.Module;
            string fileName = module.FileName;

            AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(fileName);
            TypeDefinition type = assembly.MainModule.GetType(method.Type.Name);

            MethodDefinition methodDef = type.Methods.Single(
                m => m.MetadataToken.ToUInt32() == method.MetadataToken);

            _context.WriteLine("{0}", method.GetFullSignature());

            if (method.ILOffsetMap == null)
                return;

            var mapByOffset = (from map in method.ILOffsetMap
                               where map.ILOffset != -2
                               where map.StartAddress <= map.EndAddress
                               orderby map.ILOffset
                               select map).ToArray();
            if (mapByOffset.Length == 0)
            {
                // The method doesn't have an offset map. Just print the whole thing.
                PrintInstructions(methodDef.Body.Instructions);
            }

            // This is the prologue, looks like it's always there, but it could
            // also be the only thing that's in the method
            DisassembleNative(method.ILOffsetMap.Single(e => e.ILOffset == -2));

            for (int i = 0; i < mapByOffset.Length; ++i)
            {
                var map = mapByOffset[i];
                IEnumerable<Instruction> instructions;
                if (i == mapByOffset.Length - 1)
                {
                    instructions = methodDef.Body.Instructions.Where(
                        instr => instr.Offset >= map.ILOffset);
                }
                else
                {
                    instructions = methodDef.Body.Instructions.Where(
                        instr => instr.Offset >= map.ILOffset &&
                            instr.Offset < mapByOffset[i + 1].ILOffset);
                }

                var sourceLocation = method.GetSourceLocation(map.ILOffset);
                if (sourceLocation != null)
                {
                    _context.WriteLine("{0} {1}-{2}:{3}-{4}", sourceLocation.FilePath,
                        sourceLocation.LineNumber, sourceLocation.LineNumberEnd,
                        sourceLocation.ColStart, sourceLocation.ColEnd);
                    for (int line = sourceLocation.LineNumber; line <= sourceLocation.LineNumberEnd; ++line)
                    {
                        _context.WriteLine(ReadSourceLine(sourceLocation.FilePath, line));
                        _context.WriteLine(new string(' ', sourceLocation.ColStart - 1) + new string('^', sourceLocation.ColEnd - sourceLocation.ColStart));
                    }
                }
                PrintInstructions(instructions);
                DisassembleNative(map);
            }

            // TODO We are still not printing the epilogue while sosex does
        }