コード例 #1
0
        private DisassemblyData FetchBadInstruction(enum_DISASSEMBLY_STREAM_FIELDS dwFields)
        {
            DisassemblyData dis = new DisassemblyData();

            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS) != 0)
            {
                dis.dwFields   |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS;
                dis.bstrAddress = EngineUtils.AsAddr(_addr, _engine.DebuggedProcess.Is64BitArch);
            }

            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID) != 0)
            {
                dis.dwFields       |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID;
                dis.uCodeLocationId = _addr;
            }

            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL) != 0)
            {
                dis.dwFields  |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL;
                dis.bstrSymbol = string.Empty;
            }

            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE) != 0)
            {
                dis.dwFields  |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE;
                dis.bstrOpcode = "??";
            }
            return(dis);
        }
コード例 #2
0
ファイル: AD7Disassembly.cs プロジェクト: kelltrick/MIEngine
        public int Read(uint dwInstructions, enum_DISASSEMBLY_STREAM_FIELDS dwFields, out uint pdwInstructionsRead, DisassemblyData[] prgDisassembly)
        {
            uint iOp = 0;

            DebuggedProcess process = DebuggedProcess.g_Process;
            IEnumerable <DisasmInstruction> instructions = null;

            process.WorkerThread.RunOperation(async() =>
            {
                instructions = await process.Disassembly.FetchInstructions(_addr, (int)dwInstructions);
            });

            if (instructions != null)
            {
                foreach (DisasmInstruction instruction in instructions)
                {
                    if (iOp >= dwInstructions)
                    {
                        break;
                    }
                    _addr = instruction.Addr;

                    if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS) != 0)
                    {
                        prgDisassembly[iOp].dwFields   |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS;
                        prgDisassembly[iOp].bstrAddress = instruction.AddressString;
                    }

                    if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID) != 0)
                    {
                        prgDisassembly[iOp].dwFields       |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID;
                        prgDisassembly[iOp].uCodeLocationId = instruction.Addr;
                    }

                    if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL) != 0)
                    {
                        if (instruction.Offset == 0)
                        {
                            prgDisassembly[iOp].dwFields  |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL;
                            prgDisassembly[iOp].bstrSymbol = instruction.Symbol ?? string.Empty;
                        }
                    }

                    if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE) != 0)
                    {
                        prgDisassembly[iOp].dwFields  |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE;
                        prgDisassembly[iOp].bstrOpcode = instruction.Opcode;
                    }

                    iOp++;
                }
                ;
            }

            pdwInstructionsRead = iOp;

            return(pdwInstructionsRead != 0 ? Constants.S_OK : Constants.S_FALSE);
        }
コード例 #3
0
        public int Read(uint dwInstructions, enum_DISASSEMBLY_STREAM_FIELDS dwFields, out uint pdwInstructionsRead, DisassemblyData[] prgDisassembly)
        {
            uint iOp = 0;

            //IEnumerable<DisasmInstruction> instructions = null;
            //_engine.DebuggedProcess.WorkerThread.RunOperation(async () =>
            //{
            //    instructions = await _engine.DebuggedProcess.Disassembly.FetchInstructions(_addr, (int)dwInstructions);
            //});

            //if (instructions != null)
            //{
            //    foreach (DisasmInstruction instruction in instructions)
            //    {
            //        if (iOp >= dwInstructions)
            //        {
            //            break;
            //        }
            //        _addr = instruction.Addr;

            //        if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS) != 0)
            //        {
            //            prgDisassembly[iOp].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS;
            //            prgDisassembly[iOp].bstrAddress = instruction.AddressString;
            //        }

            //        if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID) != 0)
            //        {
            //            prgDisassembly[iOp].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID;
            //            prgDisassembly[iOp].uCodeLocationId = instruction.Addr;
            //        }

            //        if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL) != 0)
            //        {
            //            if (instruction.Offset == 0)
            //            {
            //                prgDisassembly[iOp].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL;
            //                prgDisassembly[iOp].bstrSymbol = instruction.Symbol ?? string.Empty;
            //            }
            //        }

            //        if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE) != 0)
            //        {
            //            prgDisassembly[iOp].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE;
            //            prgDisassembly[iOp].bstrOpcode = instruction.Opcode;
            //        }

            //        iOp++;
            //    };
            //}

            pdwInstructionsRead = iOp;

            return(pdwInstructionsRead != 0 ? VSConstants.S_OK : VSConstants.S_FALSE);
        }
コード例 #4
0
ファイル: AD7Disassembly.cs プロジェクト: lsgxeva/MIEngine
        public int Read(uint dwInstructions, enum_DISASSEMBLY_STREAM_FIELDS dwFields, out uint pdwInstructionsRead, DisassemblyData[] prgDisassembly)
        {
            uint iOp = 0;

            IEnumerable<DisasmInstruction> instructions = null;
            _engine.DebuggedProcess.WorkerThread.RunOperation(async () =>
            {
                instructions = await _engine.DebuggedProcess.Disassembly.FetchInstructions(_addr, (int)dwInstructions);
            });

            if (instructions != null)
            {
                foreach (DisasmInstruction instruction in instructions)
                {
                    if (iOp >= dwInstructions)
                    {
                        break;
                    }
                    _addr = instruction.Addr;

                    if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS) != 0)
                    {
                        prgDisassembly[iOp].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS;
                        prgDisassembly[iOp].bstrAddress = instruction.AddressString;
                    }

                    if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID) != 0)
                    {
                        prgDisassembly[iOp].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID;
                        prgDisassembly[iOp].uCodeLocationId = instruction.Addr;
                    }

                    if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL) != 0)
                    {
                        if (instruction.Offset == 0)
                        {
                            prgDisassembly[iOp].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL;
                            prgDisassembly[iOp].bstrSymbol = instruction.Symbol ?? string.Empty;
                        }
                    }

                    if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE) != 0)
                    {
                        prgDisassembly[iOp].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE;
                        prgDisassembly[iOp].bstrOpcode = instruction.Opcode;
                    }

                    iOp++;
                };
            }

            pdwInstructionsRead = iOp;

            return pdwInstructionsRead != 0 ? Constants.S_OK : Constants.S_FALSE;
        }
コード例 #5
0
        public int Read(uint dwInstructions, enum_DISASSEMBLY_STREAM_FIELDS dwFields, out uint pdwInstructionsRead, DisassemblyData[] prgDisassembly)
        {
            pdwInstructionsRead = 0;

            if (_method == null)
                return HResults.E_DISASM_NOTAVAILABLE;

            var method = _method.Method;
            var insCount = method.Body.Instructions.Count;

            bool wantsDocumentUrl = (dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_DOCUMENTURL) != 0;
            bool wantsPosition = (dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION) != 0;
            bool wantsByteOffset = (dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_BYTEOFFSET) != 0;
            bool wantsFlags = (dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_FLAGS) != 0;

            for (pdwInstructionsRead = 0; pdwInstructionsRead < dwInstructions; ++pdwInstructionsRead, ++_instructionPointer)
            {
                int ip = _instructionPointer;

                if (ip >= insCount)
                    break;

                var insd = new DisassemblyData();
                var ins = method.Body.Instructions[ip];

                if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS) != 0)
                {
                    insd.bstrAddress = _method.FormatAddress(ins);
                    insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS;
                }

                if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID) != 0)
                {
                    insd.uCodeLocationId = (ulong)ins.Offset;
                    insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID;
                }

                if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE) != 0)
                {
                    insd.bstrOpcode = _method.FormatOpCode(ins);
                    insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE;
                }

                if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS) != 0)
                {
                    insd.bstrOperands = _method.FormatOperands(ins);
                    insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS;
                }

                if (wantsDocumentUrl || wantsPosition || wantsByteOffset || wantsFlags)
                {
                    var source = _method.FindSourceCode(ins.Offset);
                    var hasSource = source != null && !source.IsSpecial;

                    bool isSameDocAsPrevious, isSameDocPos;

                    if (hasSource)
                    {
                        isSameDocAsPrevious = _prevSource != null
                                              && !_prevSource.IsSpecial
                                              && _prevSource.Document.Path == source.Document.Path;
                        isSameDocPos = _prevSource != null && !_prevSource.IsSpecial
                                              && isSameDocAsPrevious
                                              && source.Position.CompareTo(_prevSource.Position) == 0;

                    }
                    else
                    {
                        isSameDocAsPrevious = (source == null && _prevSource == null) || (source != null && _prevSource != null && _prevSource.IsSpecial);
                        isSameDocPos = isSameDocAsPrevious;
                    }

                    if (wantsDocumentUrl && (!isSameDocAsPrevious || _justSeeked))
                    {
                        if (hasSource)
                        {
                            insd.bstrDocumentUrl = "file://" + source.Document.Path;
                            insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_DOCUMENTURL;
                        }
                        // how do I clear the document?
                    }

                    int byteOffset = 0;

                    if ((wantsByteOffset || wantsPosition) && hasSource)
                    {
                        if (isSameDocPos)
                            byteOffset = ins.Offset - _prevSourceInstructionOffset;
                        else
                        {
                            byteOffset = 0;
                            _prevSourceInstructionOffset = ins.Offset;
                        }
                    }

                    if (wantsPosition && hasSource && !isSameDocPos)
                    {
                        var pos = source.Position;

                        insd.posBeg.dwLine      = (uint)(pos.Start.Line - 1);
                        insd.posBeg.dwColumn    = (uint)(pos.Start.Column - 1);
                        insd.posEnd.dwLine      = (uint)(pos.End.Line - 1);
                        insd.posEnd.dwColumn    = (uint)(pos.End.Column - 1);

                        if (insd.posEnd.dwLine - insd.posBeg.dwLine > 3) // never show more than 3 lines.
                            insd.posEnd.dwLine = insd.posBeg.dwLine + 3;

                        // Is this just me? I have no idea why my VS throws an exception when using this.
                        //insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION;
                    }

                    if (wantsByteOffset && hasSource)
                    {
                        insd.dwByteOffset = (uint)byteOffset;
                        insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_BYTEOFFSET;
                    }

                    if (wantsFlags)
                    {
                        if(!isSameDocAsPrevious)
                            insd.dwFlags |= enum_DISASSEMBLY_FLAGS.DF_DOCUMENTCHANGE;
                        if(hasSource)
                            insd.dwFlags |= enum_DISASSEMBLY_FLAGS.DF_HASSOURCE;

                        //if (_loc.Location.Index == (ulong)ins.Offset)
                        //    insd.dwFlags |= enum_DISASSEMBLY_FLAGS.DF_INSTRUCTION_ACTIVE;

                        insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_FLAGS;
                    }

                    if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS) != 0)
                    {
                        if (!hasSource && !isSameDocPos)
                        {
                            insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS;
                            insd.bstrSymbol = "(generated instructions)";
                        }
                        else if (hasSource && !isSameDocPos)
                        {
                            // workaround to show something at least
                            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS) != 0)
                            {
                                insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS;
                                insd.bstrSymbol = "File Position: "  + source.Position.Start + " - " + source.Position.End;
                            }

                        }
                    }

                    _justSeeked = false;
                    _prevSource = source;
                }

                prgDisassembly[pdwInstructionsRead] = insd;
            }

            return pdwInstructionsRead == 0 || _instructionPointer >= insCount ? VSConstants.S_FALSE : VSConstants.S_OK;
        }
コード例 #6
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int Read(uint dwInstructions, enum_DISASSEMBLY_STREAM_FIELDS dwFields, out uint pdwInstructionsRead, DisassemblyData [] prgDisassembly)
        {
            //
            // Reads instructions starting from the current position in the disassembly stream.
            //

            LoggingUtils.PrintFunction();

            try
            {
                ulong startAddress = m_codeContext.Address.MemoryAddress;

                ulong endAddress = startAddress + ((ulong)(dwInstructions) * 4); // TODO: 4 for a 32-bit instruction set?

                string disassemblyCommand = string.Format("-data-disassemble -s 0x{0:X8} -e 0x{1:X8} -- 1", startAddress, endAddress);

                MiResultRecord resultRecord = m_debugger.GdbClient.SendSyncCommand(disassemblyCommand);

                MiResultRecord.RequireOk(resultRecord, disassemblyCommand);

                if (!resultRecord.HasField("asm_insns"))
                {
                    throw new InvalidOperationException("-data-disassemble result missing 'asm_insns' field");
                }

                MiResultValueList assemblyRecords = (MiResultValueList)resultRecord ["asm_insns"] [0];

                long maxInstructions = Math.Min(assemblyRecords.Values.Count, dwInstructions);

                if (maxInstructions == 0)
                {
                    throw new InvalidOperationException();
                }

                int currentInstruction = 0;

                for (int i = 0; i < assemblyRecords.Values.Count; ++i)
                {
                    MiResultValue recordValue = assemblyRecords [i];

                    if (recordValue.Variable.Equals("src_and_asm_line"))
                    {
                        //
                        // Parse mixed-mode disassembly reports.
                        //

                        uint line = recordValue ["line"] [0].GetUnsignedInt();

                        string file = recordValue ["file"] [0].GetString();

                        MiResultValueList lineAsmInstructionValues = (MiResultValueList)recordValue ["line_asm_insn"] [0];

                        foreach (MiResultValue instructionValue in lineAsmInstructionValues.Values)
                        {
                            string address = instructionValue ["address"] [0].GetString();

                            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS) != 0)
                            {
                                prgDisassembly [currentInstruction].bstrAddress = address;

                                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS;
                            }

                            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESSOFFSET) != 0)
                            {
                                string offset = instructionValue ["offset"] [0].GetString();

                                prgDisassembly [currentInstruction].bstrAddressOffset = offset;

                                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESSOFFSET;
                            }

                            if (((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE) != 0) || ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS) != 0) || ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS) != 0))
                            {
                                string inst = instructionValue ["inst"] [0].GetString();

                                string [] operations = inst.Split(new string [] { "\\t" }, StringSplitOptions.None);

                                if (operations.Length > 0)
                                {
                                    prgDisassembly [currentInstruction].bstrOpcode = operations [0];

                                    prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE;
                                }

                                if (operations.Length > 1)
                                {
                                    prgDisassembly [currentInstruction].bstrOperands = operations [1];

                                    prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS;
                                }

                                if (operations.Length > 2)
                                {
                                    prgDisassembly [currentInstruction].bstrOperands += " " + operations [2];

                                    prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS;
                                }
                            }

                            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL) != 0)
                            {
                                string functionName = instructionValue ["func-name"] [0].GetString();

                                prgDisassembly [currentInstruction].bstrSymbol = functionName;

                                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL;
                            }

                            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID) != 0)
                            {
                                DebuggeeAddress instructionAddress = new DebuggeeAddress(address);

                                prgDisassembly [currentInstruction].uCodeLocationId = instructionAddress.MemoryAddress;

                                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID;
                            }

                            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION) != 0)
                            {
                                prgDisassembly [currentInstruction].posBeg.dwLine = line;

                                prgDisassembly [currentInstruction].posBeg.dwColumn = 0;

                                prgDisassembly [currentInstruction].posEnd.dwLine = line;

                                prgDisassembly [currentInstruction].posEnd.dwColumn = uint.MaxValue;

                                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION;
                            }

                            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_DOCUMENTURL) != 0)
                            {
                                prgDisassembly [currentInstruction].bstrDocumentUrl = "file://" + file;

                                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_DOCUMENTURL;
                            }

                            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_BYTEOFFSET) != 0)
                            {
                                uint offset = instructionValue ["offset"] [0].GetUnsignedInt();

                                prgDisassembly [currentInstruction].dwByteOffset = offset;

                                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_BYTEOFFSET;
                            }

                            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_FLAGS) != 0)
                            {
                                prgDisassembly [currentInstruction].dwFlags |= enum_DISASSEMBLY_FLAGS.DF_HASSOURCE;

                                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_FLAGS;
                            }

                            if (++currentInstruction >= maxInstructions)
                            {
                                break;
                            }
                        }
                    }
                }

                pdwInstructionsRead = (uint)currentInstruction;

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                pdwInstructionsRead = 0;

                return(Constants.E_FAIL);
            }
        }
コード例 #7
0
        /// <summary>
        /// Reads instructions starting from the current position in the disassembly stream.
        /// </summary>
        /// <param name="dwInstructions">[in] The number of instructions to disassemble. This value is also the maximum length of the prgDisassembly array.</param>
        /// <param name="dwFields">[in] A combination of flags from the DISASSEMBLY_STREAM_FIELDS enumeration that indicate which fields of prgDisassembly are to be filled out.</param>
        /// <param name="pdwInstructionsRead">[out] Returns the number of instructions actually disassembled.</param>
        /// <param name="prgDisassembly">[out] An array of DisassemblyData structures that is filled in with the disassembled code, one structure per disassembled instruction. The length of this array is dictated by the dwInstructions parameter.</param>
        /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
        /// <remarks>
        /// The maximum number of instructions that are available in the current scope can be obtained by calling the IDebugDisassemblyStream2.GetSize method.
        /// 
        /// The current position where the next instruction is read from can be changed by calling the IDebugDisassemblyStream2.Seek method.
        /// 
        /// The DSF_OPERANDS_SYMBOLS flag can be added to the DSF_OPERANDS flag in the dwFields parameter to indicate that symbol names should be used when disassembling instructions.
        /// </remarks>
        public int Read(uint dwInstructions, enum_DISASSEMBLY_STREAM_FIELDS dwFields, out uint pdwInstructionsRead, DisassemblyData[] prgDisassembly)
        {
            pdwInstructionsRead = 0;

            uint actualInstructions = Math.Min(dwInstructions, (uint)(_disassembledMethod.Instructions.Count - _currentInstructionIndex));

            if (prgDisassembly == null || prgDisassembly.Length < dwInstructions)
                return VSConstants.E_INVALIDARG;

            IMethod method = _executionContext.Location.GetMethod();
            ReadOnlyCollection<ILocalVariable> localVariables = method.GetHasVariableInfo() ? method.GetVariables() : new ReadOnlyCollection<ILocalVariable>(new ILocalVariable[0]);
            ReadOnlyCollection<ConstantPoolEntry> constantPool = _executionContext.Location.GetDeclaringType().GetConstantPool();

            int addressFieldWidth = 1;
            int addressFieldRange = 10 * addressFieldWidth;
            while (addressFieldRange <= _bytecode.Length)
            {
                addressFieldWidth++;
                addressFieldRange *= 10;
            }

            for (int i = 0; i < actualInstructions; i++)
            {
                JavaInstruction instruction = _disassembledMethod.Instructions[_currentInstructionIndex + i];
                int instructionStart = instruction.Offset;
                int instructionSize = instruction.Size;

#if false // bstrAddress is supposed to refer to an absolute offset
                if (dwFields.GetAddress())
                {
                    prgDisassembly[i].bstrAddress = string.Format("{0," + addressFieldWidth + "}", instructionStart);
                    prgDisassembly[i].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS;
                }
#endif

                if (dwFields.GetCodeBytes())
                {
                    prgDisassembly[i].bstrCodeBytes = string.Join(" ", _bytecode.Skip(instructionStart).Take(instructionSize).Select(x => x.ToString("X2")));
                    prgDisassembly[i].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODEBYTES;
                }

                if (dwFields.GetCodeLocationId())
                {
                    prgDisassembly[i].uCodeLocationId = (ulong)instructionStart;
                    prgDisassembly[i].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID;
                }

                if (dwFields.GetOpCode())
                {
                    string depth = _evaluationStackDepths != null ? string.Format("[{0}]", _evaluationStackDepths[_currentInstructionIndex + i]) : string.Empty;
                    prgDisassembly[i].bstrOpcode = string.Format("{0}{1}", depth, instruction.OpCode.Name ?? "???");
                    prgDisassembly[i].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE;
                }

                if (dwFields.GetAddressOffset())
                {
                    prgDisassembly[i].bstrAddressOffset = string.Format("{0," + addressFieldWidth + "}", instructionStart);
                    prgDisassembly[i].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESSOFFSET;
                }

                if (dwFields.GetDocumentUrl())
                {
                    // "For text documents that can be represented as file names, the bstrDocumentUrl
                    // field is filled in with the file name where the source can be found, using the
                    // format file://file name."
                    string sourcePath = _executionContext.Location.GetSourcePath();
                    Uri sourceUri;
                    if (!string.IsNullOrEmpty(sourcePath) && Uri.TryCreate(sourcePath, UriKind.Absolute, out sourceUri))
                    {
                        prgDisassembly[i].bstrDocumentUrl = sourceUri.AbsoluteUri;
                        // if it starts with file:/// one of the / characters will show in disassembly view
                        if (prgDisassembly[i].bstrDocumentUrl.StartsWith("file:///"))
                            prgDisassembly[i].bstrDocumentUrl = "file://" + prgDisassembly[i].bstrDocumentUrl.Substring("file:///".Length);

                        prgDisassembly[i].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_DOCUMENTURL;
                    }
                }

                if (dwFields.GetOperands())
                {
                    prgDisassembly[i].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS;

                    bool includeSymbolNames = dwFields.GetOperandsSymbols();
                    if (includeSymbolNames)
                        prgDisassembly[i].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS;

                    // operand 0
                    switch (instruction.OpCode.OperandType)
                    {
                    case JavaOperandType.InlineI1:
                        prgDisassembly[i].bstrOperands = instruction.Operands.InlineSByte.ToString();
                        break;

                    case JavaOperandType.InlineI2:
                        prgDisassembly[i].bstrOperands = instruction.Operands.InlineInt16.ToString();
                        break;

                    case JavaOperandType.InlineShortBranchTarget:
                    case JavaOperandType.InlineBranchTarget:
                        prgDisassembly[i].bstrOperands = (instructionStart + instruction.Operands.Operand1).ToString();
                        break;

                    case JavaOperandType.InlineLookupSwitch:
                        prgDisassembly[i].bstrOperands = "Switch?";
                        break;

                    case JavaOperandType.InlineTableSwitch:
                        prgDisassembly[i].bstrOperands = "TableSwitch?";
                        break;

                    case JavaOperandType.InlineVar:
                    case JavaOperandType.InlineVar_I1:
                        if (includeSymbolNames)
                        {
                            int localIndex = _bytecode[instructionStart + 1];
                            int testLocation = instructionStart;
                            if (instruction.OpCode.StackBehaviorPop != JavaStackBehavior.Pop0)
                            {
                                // this is a store instruction - the variable might not be visible until the following instruction
                                testLocation += instruction.Size;
                            }

                            ILocation currentLocation = _executionContext.Location.GetMethod().GetLocationOfCodeIndex(testLocation);
                            var local = localVariables.SingleOrDefault(variable => variable.GetSlot() == localIndex && variable.GetIsVisible(currentLocation));
                            if (local != null)
                            {
                                prgDisassembly[i].bstrOperands = local.GetName();
                            }
                        }

                        if (string.IsNullOrEmpty(prgDisassembly[i].bstrOperands))
                        {
                            prgDisassembly[i].bstrOperands = "#" + instruction.Operands.VariableSlot.ToString();
                        }

                        break;

                    case JavaOperandType.InlineShortConst:
                    case JavaOperandType.InlineConst:
                    case JavaOperandType.InlineField:
                    case JavaOperandType.InlineMethod:
                    case JavaOperandType.InlineMethod_U1_0:
                    case JavaOperandType.InlineType:
                    case JavaOperandType.InlineType_U1:
                        if (includeSymbolNames)
                        {
                            int index = instruction.Operands.ConstantPoolIndex;
                            var entry = constantPool[index - 1];
                            prgDisassembly[i].bstrOperands = entry.ToString(constantPool);
                        }

                        if (string.IsNullOrEmpty(prgDisassembly[i].bstrOperands))
                        {
                            prgDisassembly[i].bstrOperands = "#" + instruction.Operands.ConstantPoolIndex.ToString();
                        }

                        break;

                    case JavaOperandType.InlineArrayType:
                        prgDisassembly[i].bstrOperands = "T_" + instruction.Operands.ArrayType.ToString().ToUpperInvariant();
                        break;

                    case JavaOperandType.InlineNone:
                        if (includeSymbolNames)
                        {
                            int? localIndex = null;

                            switch (instruction.OpCode.OpCode)
                            {
                            case JavaOpCodeTag.Aload_0:
                            case JavaOpCodeTag.Astore_0:
                            case JavaOpCodeTag.Dload_0:
                            case JavaOpCodeTag.Dstore_0:
                            case JavaOpCodeTag.Fload_0:
                            case JavaOpCodeTag.Fstore_0:
                            case JavaOpCodeTag.Iload_0:
                            case JavaOpCodeTag.Istore_0:
                            case JavaOpCodeTag.Lload_0:
                            case JavaOpCodeTag.Lstore_0:
                                localIndex = 0;
                                break;

                            case JavaOpCodeTag.Aload_1:
                            case JavaOpCodeTag.Astore_1:
                            case JavaOpCodeTag.Dload_1:
                            case JavaOpCodeTag.Dstore_1:
                            case JavaOpCodeTag.Fload_1:
                            case JavaOpCodeTag.Fstore_1:
                            case JavaOpCodeTag.Iload_1:
                            case JavaOpCodeTag.Istore_1:
                            case JavaOpCodeTag.Lload_1:
                            case JavaOpCodeTag.Lstore_1:
                                localIndex = 1;
                                break;

                            case JavaOpCodeTag.Aload_2:
                            case JavaOpCodeTag.Astore_2:
                            case JavaOpCodeTag.Dload_2:
                            case JavaOpCodeTag.Dstore_2:
                            case JavaOpCodeTag.Fload_2:
                            case JavaOpCodeTag.Fstore_2:
                            case JavaOpCodeTag.Iload_2:
                            case JavaOpCodeTag.Istore_2:
                            case JavaOpCodeTag.Lload_2:
                            case JavaOpCodeTag.Lstore_2:
                                localIndex = 2;
                                break;

                            case JavaOpCodeTag.Aload_3:
                            case JavaOpCodeTag.Astore_3:
                            case JavaOpCodeTag.Dload_3:
                            case JavaOpCodeTag.Dstore_3:
                            case JavaOpCodeTag.Fload_3:
                            case JavaOpCodeTag.Fstore_3:
                            case JavaOpCodeTag.Iload_3:
                            case JavaOpCodeTag.Istore_3:
                            case JavaOpCodeTag.Lload_3:
                            case JavaOpCodeTag.Lstore_3:
                                localIndex = 3;
                                break;
                            }

                            if (localIndex.HasValue)
                            {
                                int testLocation = instructionStart;
                                if (instruction.OpCode.StackBehaviorPop != JavaStackBehavior.Pop0)
                                {
                                    // this is a store instruction - the variable might not be visible until the following instruction
                                    testLocation += instruction.Size;
                                }

                                ILocation currentLocation = _executionContext.Location.GetMethod().GetLocationOfCodeIndex(testLocation);
                                var local = localVariables.SingleOrDefault(variable => variable.GetSlot() == localIndex && variable.GetIsVisible(currentLocation));
                                if (local != null)
                                {
                                    prgDisassembly[i].bstrOperands = local.GetName();
                                }
                            }
                        }

                        break;

                    default:
                        prgDisassembly[i].bstrOperands = string.Empty;
                        break;
                    }

                    // operand 1
                    switch (instruction.OpCode.OperandType)
                    {
                    case JavaOperandType.InlineVar_I1:
                        prgDisassembly[i].bstrOperands += " " + instruction.Operands.Increment.ToString();
                        break;

                    case JavaOperandType.InlineMethod_U1_0:
                        prgDisassembly[i].bstrOperands += " " + instruction.Operands.Operand2.ToString();
                        break;

                    case JavaOperandType.InlineType_U1:
                        prgDisassembly[i].bstrOperands += " " + instruction.Operands.Dimensions.ToString();
                        break;

                    default:
                        break;
                    }

                    // operand 2
                    if (instruction.OpCode.OperandType == JavaOperandType.InlineMethod_U1_0)
                    {
                        prgDisassembly[i].bstrOperands += " 0";
                    }
                }

                if (dwFields.GetPosition())
                {
                    try
                    {
                        ILocation location = _executionContext.Location.GetMethod().GetLocationOfCodeIndex(instructionStart);
                        prgDisassembly[i].posBeg.dwLine = (uint)location.GetLineNumber();
                        prgDisassembly[i].posBeg.dwColumn = 0;
                        prgDisassembly[i].posEnd = prgDisassembly[i].posBeg;
                        prgDisassembly[i].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION;
                    }
                    catch (Exception e)
                    {
                        if (ErrorHandler.IsCriticalException(e))
                            throw;

                        prgDisassembly[i].posBeg = default(TEXT_POSITION);
                        prgDisassembly[i].posEnd = default(TEXT_POSITION);
                        prgDisassembly[i].dwFields &= ~enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION;
                    }
                }

                if (dwFields.GetFlags())
                {
                    // TODO: determine when the following condition is met?
                    //   "Indicates that this instruction is one of the next instructions to be executed (there may be more than one)."
                    bool active = false;
                    if (active)
                        prgDisassembly[i].dwFlags |= enum_DISASSEMBLY_FLAGS.DF_INSTRUCTION_ACTIVE;

                    // Check for location information to determine when this condition is met:
                    //   "Indicates that this instruction has source. Some instructions, such as profiling or garbage collection code, have no corresponding source."
                    bool hasSource = prgDisassembly[i].dwFields.GetPosition();
                    if (hasSource)
                        prgDisassembly[i].dwFlags |= enum_DISASSEMBLY_FLAGS.DF_HASSOURCE;

                    // The current single-method disassembly only includes source from a single file, so this is for all but the first line:
                    //   "Indicates that this instruction is in a different document than the previous one."
                    bool documentChange = i == 0 && _currentInstructionIndex == 0;
                    if (documentChange)
                        prgDisassembly[i].dwFlags |= enum_DISASSEMBLY_FLAGS.DF_DOCUMENTCHANGE;

                    // Javac removes code that is statically determined to be unreachable (even in debug mode), so this is false:
                    //   "Indicates that this instruction will not be executed."
                    bool disabled = false;
                    if (disabled)
                        prgDisassembly[i].dwFlags |= enum_DISASSEMBLY_FLAGS.DF_DISABLED;

                    // This is always false in bytecode:
                    //   "Indicates that this instruction is really data (not code)."
                    bool data = false;
                    if (data)
                        prgDisassembly[i].dwFlags |= enum_DISASSEMBLY_FLAGS.DF_DATA;

                    // The Java debugging information format does not include document checksum information
                    bool documentChecksum = false;
                    if (documentChecksum)
                        prgDisassembly[i].dwFlags |= enum_DISASSEMBLY_FLAGS.DF_DOCUMENT_CHECKSUM;

                    prgDisassembly[i].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_FLAGS;
                }

                if (dwFields.GetByteOffset() && prgDisassembly[i].dwFields.GetPosition())
                {
                    //   "The number of bytes the instruction is from the beginning of the code line."
                    int byteOffset = 0;
                    for (int j = _currentInstructionIndex + i - 1; j >= 0; j--)
                    {
                        JavaInstruction priorInstruction = _disassembledMethod.Instructions[j];
                        try
                        {
                            ILocation location = _executionContext.Location.GetMethod().GetLocationOfCodeIndex(priorInstruction.Offset);
                            if (location.GetLineNumber() != prgDisassembly[i].posBeg.dwLine)
                                break;

                            byteOffset = instruction.Offset - priorInstruction.Offset;
                        }
                        catch (Exception e)
                        {
                            if (ErrorHandler.IsCriticalException(e))
                                throw;

                            break;
                        }
                    }

                    prgDisassembly[i].dwByteOffset = (uint)Math.Max(0, byteOffset);
                    prgDisassembly[i].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_BYTEOFFSET;
                }

                if (dwFields.GetSymbol())
                {
                    switch (instruction.OpCode.OperandType)
                    {
                    case JavaOperandType.InlineLookupSwitch:
                        prgDisassembly[i].bstrSymbol = "// switch";
                        break;

                    case JavaOperandType.InlineTableSwitch:
                        prgDisassembly[i].bstrSymbol = "// table switch";
                        break;

                    default:
                        break;
                    }

                    if (prgDisassembly[i].bstrSymbol != null)
                        prgDisassembly[i].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL;
                }
            }

            _currentInstructionIndex += (int)actualInstructions;
            pdwInstructionsRead = actualInstructions;
            return actualInstructions == dwInstructions ? VSConstants.S_OK : VSConstants.S_FALSE;
        }
コード例 #8
0
        public int Read(uint numInstructions, enum_DISASSEMBLY_STREAM_FIELDS fields,
                        out uint numInstructionsRead, DisassemblyData[] disassembly)
        {
            numInstructionsRead = 0;
            SbAddress sbAddress = _target.ResolveLoadAddress(_address);

            if (sbAddress == null)
            {
                return(VSConstants.S_FALSE);
            }

            bool withSource = ((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION) != 0) ||
                              ((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_DOCUMENTURL) != 0) ||
                              ((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_BYTEOFFSET) != 0);

            List <Instruction> instructions =
                GetInstructions(sbAddress, numInstructions, withSource);

            for (int i = 0; i < instructions.Count; i++)
            {
                Instruction instruction = instructions[i];
                _address = instruction.Address;
                if ((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS) != 0)
                {
                    disassembly[i].dwFields   |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS;
                    disassembly[i].bstrAddress = $"0x{instruction.Address:x16}";
                }

                if ((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID) != 0)
                {
                    disassembly[i].dwFields       |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID;
                    disassembly[i].uCodeLocationId = instruction.Address;
                }

                if ((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE) != 0)
                {
                    disassembly[i].dwFields  |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE;
                    disassembly[i].bstrOpcode = instruction.Text;
                }
                if ((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL) != 0)
                {
                    if (instruction.Symbol != null)
                    {
                        disassembly[i].dwFields  |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL;
                        disassembly[i].bstrSymbol = instruction.Symbol;
                    }
                }
                if ((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_DOCUMENTURL) != 0)
                {
                    disassembly[i].bstrDocumentUrl = instruction.Document;
                    disassembly[i].dwFields       |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_DOCUMENTURL;
                }
                if ((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION) != 0)
                {
                    if (instruction.HasSource)
                    {
                        disassembly[i].posBeg.dwColumn = 0;
                        disassembly[i].posBeg.dwLine   = instruction.StartLine;
                        disassembly[i].posEnd.dwColumn = 0;
                        disassembly[i].posEnd.dwLine   = instruction.EndLine;
                        disassembly[i].dwFields       |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION;
                    }
                }
                if ((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_FLAGS) != 0)
                {
                    disassembly[i].dwFlags =
                        instruction.HasSource ? enum_DISASSEMBLY_FLAGS.DF_HASSOURCE : 0;
                    if (instruction.DocumentChanged)
                    {
                        disassembly[i].dwFlags |= enum_DISASSEMBLY_FLAGS.DF_DOCUMENTCHANGE;
                    }
                    disassembly[i].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_FLAGS;
                }
                if ((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_BYTEOFFSET) != 0)
                {
                    if (instruction.HasSource)
                    {
                        disassembly[i].dwByteOffset = instruction.ByteOffset;
                        disassembly[i].dwFields    |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_BYTEOFFSET;
                    }
                }
            }

            numInstructionsRead = Convert.ToUInt32(instructions.Count);
            return(numInstructionsRead > 0 ? VSConstants.S_OK : VSConstants.S_FALSE);
        }
コード例 #9
0
        /// <summary>
        /// Reads instructions starting from the current position in the disassembly stream.
        /// </summary>
        /// <param name="dwInstructions">[in] The number of instructions to disassemble. This value is also the maximum length of the prgDisassembly array.</param>
        /// <param name="dwFields">[in] A combination of flags from the DISASSEMBLY_STREAM_FIELDS enumeration that indicate which fields of prgDisassembly are to be filled out.</param>
        /// <param name="pdwInstructionsRead">[out] Returns the number of instructions actually disassembled.</param>
        /// <param name="prgDisassembly">[out] An array of DisassemblyData structures that is filled in with the disassembled code, one structure per disassembled instruction. The length of this array is dictated by the dwInstructions parameter.</param>
        /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
        /// <remarks>
        /// The maximum number of instructions that are available in the current scope can be obtained by calling the IDebugDisassemblyStream2.GetSize method.
        ///
        /// The current position where the next instruction is read from can be changed by calling the IDebugDisassemblyStream2.Seek method.
        ///
        /// The DSF_OPERANDS_SYMBOLS flag can be added to the DSF_OPERANDS flag in the dwFields parameter to indicate that symbol names should be used when disassembling instructions.
        /// </remarks>
        public int Read(uint dwInstructions, enum_DISASSEMBLY_STREAM_FIELDS dwFields, out uint pdwInstructionsRead, DisassemblyData[] prgDisassembly)
        {
            pdwInstructionsRead = 0;

            uint actualInstructions = Math.Min(dwInstructions, (uint)(_disassembledMethod.Instructions.Count - _currentInstructionIndex));

            if (prgDisassembly == null || prgDisassembly.Length < dwInstructions)
            {
                return(VSConstants.E_INVALIDARG);
            }

            IMethod method = _executionContext.Location.GetMethod();
            ReadOnlyCollection <ILocalVariable>    localVariables = method.GetHasVariableInfo() ? method.GetVariables() : new ReadOnlyCollection <ILocalVariable>(new ILocalVariable[0]);
            ReadOnlyCollection <ConstantPoolEntry> constantPool   = _executionContext.Location.GetDeclaringType().GetConstantPool();

            int addressFieldWidth = 1;
            int addressFieldRange = 10 * addressFieldWidth;

            while (addressFieldRange <= _bytecode.Length)
            {
                addressFieldWidth++;
                addressFieldRange *= 10;
            }

            for (int i = 0; i < actualInstructions; i++)
            {
                JavaInstruction instruction      = _disassembledMethod.Instructions[_currentInstructionIndex + i];
                int             instructionStart = instruction.Offset;
                int             instructionSize  = instruction.Size;

#if false // bstrAddress is supposed to refer to an absolute offset
                if (dwFields.GetAddress())
                {
                    prgDisassembly[i].bstrAddress = string.Format("{0," + addressFieldWidth + "}", instructionStart);
                    prgDisassembly[i].dwFields   |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS;
                }
#endif

                if (dwFields.GetCodeBytes())
                {
                    prgDisassembly[i].bstrCodeBytes = string.Join(" ", _bytecode.Skip(instructionStart).Take(instructionSize).Select(x => x.ToString("X2")));
                    prgDisassembly[i].dwFields     |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODEBYTES;
                }

                if (dwFields.GetCodeLocationId())
                {
                    prgDisassembly[i].uCodeLocationId = (ulong)instructionStart;
                    prgDisassembly[i].dwFields       |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID;
                }

                if (dwFields.GetOpCode())
                {
                    prgDisassembly[i].bstrOpcode = string.Format("[{0}]{1}", _evaluationStackDepths[_currentInstructionIndex + i], instruction.OpCode.Name ?? "???");
                    prgDisassembly[i].dwFields  |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE;
                }

                if (dwFields.GetAddressOffset())
                {
                    prgDisassembly[i].bstrAddressOffset = string.Format("{0," + addressFieldWidth + "}", instructionStart);
                    prgDisassembly[i].dwFields         |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESSOFFSET;
                }

                if (dwFields.GetDocumentUrl())
                {
                    // "For text documents that can be represented as file names, the bstrDocumentUrl
                    // field is filled in with the file name where the source can be found, using the
                    // format file://file name."
                    string sourcePath = _executionContext.Location.GetSourcePath();
                    Uri    sourceUri;
                    if (!string.IsNullOrEmpty(sourcePath) && Uri.TryCreate(sourcePath, UriKind.Absolute, out sourceUri))
                    {
                        prgDisassembly[i].bstrDocumentUrl = sourceUri.AbsoluteUri;
                        // if it starts with file:/// one of the / characters will show in disassembly view
                        if (prgDisassembly[i].bstrDocumentUrl.StartsWith("file:///"))
                        {
                            prgDisassembly[i].bstrDocumentUrl = "file://" + prgDisassembly[i].bstrDocumentUrl.Substring("file:///".Length);
                        }

                        prgDisassembly[i].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_DOCUMENTURL;
                    }
                }

                if (dwFields.GetOperands())
                {
                    prgDisassembly[i].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS;

                    bool includeSymbolNames = dwFields.GetOperandsSymbols();
                    if (includeSymbolNames)
                    {
                        prgDisassembly[i].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS;
                    }

                    // operand 0
                    switch (instruction.OpCode.OperandType)
                    {
                    case JavaOperandType.InlineI1:
                        prgDisassembly[i].bstrOperands = instruction.Operands.InlineSByte.ToString();
                        break;

                    case JavaOperandType.InlineI2:
                        prgDisassembly[i].bstrOperands = instruction.Operands.InlineInt16.ToString();
                        break;

                    case JavaOperandType.InlineShortBranchTarget:
                    case JavaOperandType.InlineBranchTarget:
                        prgDisassembly[i].bstrOperands = (instructionStart + instruction.Operands.Operand1).ToString();
                        break;

                    case JavaOperandType.InlineLookupSwitch:
                        prgDisassembly[i].bstrOperands = "Switch?";
                        break;

                    case JavaOperandType.InlineTableSwitch:
                        prgDisassembly[i].bstrOperands = "TableSwitch?";
                        break;

                    case JavaOperandType.InlineVar:
                    case JavaOperandType.InlineVar_I1:
                        if (includeSymbolNames)
                        {
                            int localIndex   = _bytecode[instructionStart + 1];
                            int testLocation = instructionStart;
                            if (instruction.OpCode.StackBehaviorPop != JavaStackBehavior.Pop0)
                            {
                                // this is a store instruction - the variable might not be visible until the following instruction
                                testLocation += instruction.Size;
                            }

                            ILocation currentLocation = _executionContext.Location.GetMethod().GetLocationOfCodeIndex(testLocation);
                            var       local           = localVariables.SingleOrDefault(variable => variable.GetSlot() == localIndex && variable.GetIsVisible(currentLocation));
                            if (local != null)
                            {
                                prgDisassembly[i].bstrOperands = local.GetName();
                            }
                        }

                        if (string.IsNullOrEmpty(prgDisassembly[i].bstrOperands))
                        {
                            prgDisassembly[i].bstrOperands = "#" + instruction.Operands.VariableSlot.ToString();
                        }

                        break;

                    case JavaOperandType.InlineShortConst:
                    case JavaOperandType.InlineConst:
                    case JavaOperandType.InlineField:
                    case JavaOperandType.InlineMethod:
                    case JavaOperandType.InlineMethod_U1_0:
                    case JavaOperandType.InlineType:
                    case JavaOperandType.InlineType_U1:
                        if (includeSymbolNames)
                        {
                            int index = instruction.Operands.ConstantPoolIndex;
                            var entry = constantPool[index - 1];
                            prgDisassembly[i].bstrOperands = entry.ToString(constantPool);
                        }

                        if (string.IsNullOrEmpty(prgDisassembly[i].bstrOperands))
                        {
                            prgDisassembly[i].bstrOperands = "#" + instruction.Operands.ConstantPoolIndex.ToString();
                        }

                        break;

                    case JavaOperandType.InlineArrayType:
                        prgDisassembly[i].bstrOperands = "T_" + instruction.Operands.ArrayType.ToString().ToUpperInvariant();
                        break;

                    case JavaOperandType.InlineNone:
                        if (includeSymbolNames)
                        {
                            int?localIndex = null;

                            switch (instruction.OpCode.OpCode)
                            {
                            case JavaOpCodeTag.Aload_0:
                            case JavaOpCodeTag.Astore_0:
                            case JavaOpCodeTag.Dload_0:
                            case JavaOpCodeTag.Dstore_0:
                            case JavaOpCodeTag.Fload_0:
                            case JavaOpCodeTag.Fstore_0:
                            case JavaOpCodeTag.Iload_0:
                            case JavaOpCodeTag.Istore_0:
                            case JavaOpCodeTag.Lload_0:
                            case JavaOpCodeTag.Lstore_0:
                                localIndex = 0;
                                break;

                            case JavaOpCodeTag.Aload_1:
                            case JavaOpCodeTag.Astore_1:
                            case JavaOpCodeTag.Dload_1:
                            case JavaOpCodeTag.Dstore_1:
                            case JavaOpCodeTag.Fload_1:
                            case JavaOpCodeTag.Fstore_1:
                            case JavaOpCodeTag.Iload_1:
                            case JavaOpCodeTag.Istore_1:
                            case JavaOpCodeTag.Lload_1:
                            case JavaOpCodeTag.Lstore_1:
                                localIndex = 1;
                                break;

                            case JavaOpCodeTag.Aload_2:
                            case JavaOpCodeTag.Astore_2:
                            case JavaOpCodeTag.Dload_2:
                            case JavaOpCodeTag.Dstore_2:
                            case JavaOpCodeTag.Fload_2:
                            case JavaOpCodeTag.Fstore_2:
                            case JavaOpCodeTag.Iload_2:
                            case JavaOpCodeTag.Istore_2:
                            case JavaOpCodeTag.Lload_2:
                            case JavaOpCodeTag.Lstore_2:
                                localIndex = 2;
                                break;

                            case JavaOpCodeTag.Aload_3:
                            case JavaOpCodeTag.Astore_3:
                            case JavaOpCodeTag.Dload_3:
                            case JavaOpCodeTag.Dstore_3:
                            case JavaOpCodeTag.Fload_3:
                            case JavaOpCodeTag.Fstore_3:
                            case JavaOpCodeTag.Iload_3:
                            case JavaOpCodeTag.Istore_3:
                            case JavaOpCodeTag.Lload_3:
                            case JavaOpCodeTag.Lstore_3:
                                localIndex = 3;
                                break;
                            }

                            if (localIndex.HasValue)
                            {
                                int testLocation = instructionStart;
                                if (instruction.OpCode.StackBehaviorPop != JavaStackBehavior.Pop0)
                                {
                                    // this is a store instruction - the variable might not be visible until the following instruction
                                    testLocation += instruction.Size;
                                }

                                ILocation currentLocation = _executionContext.Location.GetMethod().GetLocationOfCodeIndex(testLocation);
                                var       local           = localVariables.SingleOrDefault(variable => variable.GetSlot() == localIndex && variable.GetIsVisible(currentLocation));
                                if (local != null)
                                {
                                    prgDisassembly[i].bstrOperands = local.GetName();
                                }
                            }
                        }

                        break;

                    default:
                        prgDisassembly[i].bstrOperands = string.Empty;
                        break;
                    }

                    // operand 1
                    switch (instruction.OpCode.OperandType)
                    {
                    case JavaOperandType.InlineVar_I1:
                        prgDisassembly[i].bstrOperands += " " + instruction.Operands.Increment.ToString();
                        break;

                    case JavaOperandType.InlineMethod_U1_0:
                        prgDisassembly[i].bstrOperands += " " + instruction.Operands.Operand2.ToString();
                        break;

                    case JavaOperandType.InlineType_U1:
                        prgDisassembly[i].bstrOperands += " " + instruction.Operands.Dimensions.ToString();
                        break;

                    default:
                        break;
                    }

                    // operand 2
                    if (instruction.OpCode.OperandType == JavaOperandType.InlineMethod_U1_0)
                    {
                        prgDisassembly[i].bstrOperands += " 0";
                    }
                }

                if (dwFields.GetPosition())
                {
                    try
                    {
                        ILocation location = _executionContext.Location.GetMethod().GetLocationOfCodeIndex(instructionStart);
                        prgDisassembly[i].posBeg.dwLine   = (uint)location.GetLineNumber();
                        prgDisassembly[i].posBeg.dwColumn = 0;
                        prgDisassembly[i].posEnd          = prgDisassembly[i].posBeg;
                        prgDisassembly[i].dwFields       |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION;
                    }
                    catch (Exception e)
                    {
                        if (ErrorHandler.IsCriticalException(e))
                        {
                            throw;
                        }

                        prgDisassembly[i].posBeg    = default(TEXT_POSITION);
                        prgDisassembly[i].posEnd    = default(TEXT_POSITION);
                        prgDisassembly[i].dwFields &= ~enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION;
                    }
                }

                if (dwFields.GetFlags())
                {
                    // TODO: determine when the following condition is met?
                    //   "Indicates that this instruction is one of the next instructions to be executed (there may be more than one)."
                    bool active = false;
                    if (active)
                    {
                        prgDisassembly[i].dwFlags |= enum_DISASSEMBLY_FLAGS.DF_INSTRUCTION_ACTIVE;
                    }

                    // Check for location information to determine when this condition is met:
                    //   "Indicates that this instruction has source. Some instructions, such as profiling or garbage collection code, have no corresponding source."
                    bool hasSource = prgDisassembly[i].dwFields.GetPosition();
                    if (hasSource)
                    {
                        prgDisassembly[i].dwFlags |= enum_DISASSEMBLY_FLAGS.DF_HASSOURCE;
                    }

                    // The current single-method disassembly only includes source from a single file, so this is for all but the first line:
                    //   "Indicates that this instruction is in a different document than the previous one."
                    bool documentChange = i == 0 && _currentInstructionIndex == 0;
                    if (documentChange)
                    {
                        prgDisassembly[i].dwFlags |= enum_DISASSEMBLY_FLAGS.DF_DOCUMENTCHANGE;
                    }

                    // Javac removes code that is statically determined to be unreachable (even in debug mode), so this is false:
                    //   "Indicates that this instruction will not be executed."
                    bool disabled = false;
                    if (disabled)
                    {
                        prgDisassembly[i].dwFlags |= enum_DISASSEMBLY_FLAGS.DF_DISABLED;
                    }

                    // This is always false in bytecode:
                    //   "Indicates that this instruction is really data (not code)."
                    bool data = false;
                    if (data)
                    {
                        prgDisassembly[i].dwFlags |= enum_DISASSEMBLY_FLAGS.DF_DATA;
                    }

                    // The Java debugging information format does not include document checksum information
                    bool documentChecksum = false;
                    if (documentChecksum)
                    {
                        prgDisassembly[i].dwFlags |= enum_DISASSEMBLY_FLAGS.DF_DOCUMENT_CHECKSUM;
                    }

                    prgDisassembly[i].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_FLAGS;
                }

                if (dwFields.GetByteOffset() && prgDisassembly[i].dwFields.GetPosition())
                {
                    //   "The number of bytes the instruction is from the beginning of the code line."
                    int byteOffset = 0;
                    for (int j = _currentInstructionIndex + i - 1; j >= 0; j--)
                    {
                        JavaInstruction priorInstruction = _disassembledMethod.Instructions[j];
                        try
                        {
                            ILocation location = _executionContext.Location.GetMethod().GetLocationOfCodeIndex(priorInstruction.Offset);
                            if (location.GetLineNumber() != prgDisassembly[i].posBeg.dwLine)
                            {
                                break;
                            }

                            byteOffset = instruction.Offset - priorInstruction.Offset;
                        }
                        catch (Exception e)
                        {
                            if (ErrorHandler.IsCriticalException(e))
                            {
                                throw;
                            }

                            break;
                        }
                    }

                    prgDisassembly[i].dwByteOffset = (uint)Math.Max(0, byteOffset);
                    prgDisassembly[i].dwFields    |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_BYTEOFFSET;
                }

                if (dwFields.GetSymbol())
                {
                    switch (instruction.OpCode.OperandType)
                    {
                    case JavaOperandType.InlineLookupSwitch:
                        prgDisassembly[i].bstrSymbol = "// switch";
                        break;

                    case JavaOperandType.InlineTableSwitch:
                        prgDisassembly[i].bstrSymbol = "// table switch";
                        break;

                    default:
                        break;
                    }

                    if (prgDisassembly[i].bstrSymbol != null)
                    {
                        prgDisassembly[i].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL;
                    }
                }
            }

            _currentInstructionIndex += (int)actualInstructions;
            pdwInstructionsRead       = actualInstructions;
            return(actualInstructions == dwInstructions ? VSConstants.S_OK : VSConstants.S_FALSE);
        }
コード例 #10
0
 /// <summary>
 /// Initialize/use the uCodeLocationId field.
 /// </summary>
 public static bool GetCodeLocationId(this enum_DISASSEMBLY_STREAM_FIELDS fields)
 {
     return((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID) != 0);
 }
コード例 #11
0
        public int Read(uint dwInstructions, enum_DISASSEMBLY_STREAM_FIELDS dwFields, out uint pdwInstructionsRead, DisassemblyData[] prgDisassembly)
        {
            uint iOp = 0;

            IEnumerable <DisasmInstruction> instructions = null;

            _engine.DebuggedProcess.WorkerThread.RunOperation(async() =>
            {
                instructions = await _engine.DebuggedProcess.Disassembly.FetchInstructions(_addr, (int)dwInstructions);
            });
            if (instructions == null || (instructions.First().Addr - _addr > dwInstructions))
            {
                // bad address range, return '??'
                for (iOp = 0; iOp < dwInstructions; _addr++, ++iOp)
                {
                    prgDisassembly[iOp] = FetchBadInstruction(dwFields);
                }
                pdwInstructionsRead = iOp;
                return(Constants.S_OK);
            }

            // return '??' for bad addresses at start of range
            for (iOp = 0; _addr < instructions.First().Addr; _addr++, iOp++)
            {
                prgDisassembly[iOp] = FetchBadInstruction(dwFields);
            }
            foreach (DisasmInstruction instruction in instructions)
            {
                if (iOp >= dwInstructions)
                {
                    break;
                }
                _addr = instruction.Addr;

                if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS) != 0)
                {
                    prgDisassembly[iOp].dwFields   |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS;
                    prgDisassembly[iOp].bstrAddress = instruction.AddressString;
                }

                if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID) != 0)
                {
                    prgDisassembly[iOp].dwFields       |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID;
                    prgDisassembly[iOp].uCodeLocationId = instruction.Addr;
                }

                if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL) != 0)
                {
                    if (instruction.Offset == 0)
                    {
                        prgDisassembly[iOp].dwFields  |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL;
                        prgDisassembly[iOp].bstrSymbol = instruction.Symbol ?? string.Empty;
                    }
                }

                if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE) != 0)
                {
                    prgDisassembly[iOp].dwFields  |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE;
                    prgDisassembly[iOp].bstrOpcode = instruction.Opcode;
                }

                iOp++;
            }
            ;

            if (iOp < dwInstructions)
            {
                // Didn't get enough instructions. Must have run out of valid memory address range.
                Tuple <ulong, ulong> range = new Tuple <ulong, ulong>(0, 0);
                _engine.DebuggedProcess.WorkerThread.RunOperation(async() =>
                {
                    range = await _engine.DebuggedProcess.FindValidMemoryRange(_addr, 10, 0);
                });
                // return '??' for bad addresses at end of range
                for (_addr = range.Item2; iOp < dwInstructions; _addr++, iOp++)
                {
                    prgDisassembly[iOp] = FetchBadInstruction(dwFields);
                }
            }
            pdwInstructionsRead = iOp;

            return(pdwInstructionsRead != 0 ? Constants.S_OK : Constants.S_FALSE);
        }
コード例 #12
0
 /// <summary>
 /// Include symbol names in the bstrOperands field.
 /// </summary>
 public static bool GetOperandsSymbols(this enum_DISASSEMBLY_STREAM_FIELDS fields)
 {
     return((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS) != 0);
 }
コード例 #13
0
 /// <summary>
 /// Initialize/use the bstrAddress field.
 /// </summary>
 public static bool GetAddress(this enum_DISASSEMBLY_STREAM_FIELDS fields)
 {
     return((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS) != 0);
 }
コード例 #14
0
 /// <summary>
 /// Initialize/use the dwFlags field.
 /// </summary>
 public static bool GetFlags(this enum_DISASSEMBLY_STREAM_FIELDS fields)
 {
     return((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_FLAGS) != 0);
 }
コード例 #15
0
 /// <summary>
 /// Initialize/use the dwByteOffset field.
 /// </summary>
 public static bool GetByteOffset(this enum_DISASSEMBLY_STREAM_FIELDS fields)
 {
     return((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_BYTEOFFSET) != 0);
 }
コード例 #16
0
 /// <summary>
 /// Initialize/use the bstrDocumentUrl field.
 /// </summary>
 public static bool GetDocumentUrl(this enum_DISASSEMBLY_STREAM_FIELDS fields)
 {
     return((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_DOCUMENTURL) != 0);
 }
コード例 #17
0
 /// <summary>
 /// Initialize/use the posBeg and posEnd fields.
 /// </summary>
 public static bool GetPosition(this enum_DISASSEMBLY_STREAM_FIELDS fields)
 {
     return((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION) != 0);
 }
コード例 #18
0
 /// <summary>
 /// Initialize/use the bstrOpCode field.
 /// </summary>
 public static bool GetOpCode(this enum_DISASSEMBLY_STREAM_FIELDS fields)
 {
     return((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE) != 0);
 }
コード例 #19
0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int Read (uint dwInstructions, enum_DISASSEMBLY_STREAM_FIELDS dwFields, out uint pdwInstructionsRead, DisassemblyData [] prgDisassembly)
    {
      // 
      // Reads instructions starting from the current position in the disassembly stream.
      // 

      LoggingUtils.PrintFunction ();

      try
      {
        ulong startAddress = m_codeContext.Address.MemoryAddress;

        ulong endAddress = startAddress + ((ulong)(dwInstructions) * 4); // TODO: 4 for a 32-bit instruction set?

        string disassemblyCommand = string.Format ("-data-disassemble -s 0x{0:X8} -e 0x{1:X8} -- 1", startAddress, endAddress);

        MiResultRecord resultRecord = m_debugger.GdbClient.SendSyncCommand (disassemblyCommand);

        MiResultRecord.RequireOk (resultRecord, disassemblyCommand);

        if (!resultRecord.HasField ("asm_insns"))
        {
          throw new InvalidOperationException ("-data-disassemble result missing 'asm_insns' field");
        }

        MiResultValueList assemblyRecords = (MiResultValueList) resultRecord ["asm_insns"] [0];

        long maxInstructions = Math.Min (assemblyRecords.Values.Count, dwInstructions);

        if (maxInstructions == 0)
        {
          throw new InvalidOperationException ();
        }

        int currentInstruction = 0;

        for (int i = 0; i < assemblyRecords.Values.Count; ++i)
        {
          MiResultValue recordValue = assemblyRecords [i];

          if (recordValue.Variable.Equals ("src_and_asm_line"))
          {
            // 
            // Parse mixed-mode disassembly reports.
            // 

            uint line = recordValue ["line"] [0].GetUnsignedInt ();

            string file = recordValue ["file"] [0].GetString ();

            MiResultValueList lineAsmInstructionValues = (MiResultValueList) recordValue ["line_asm_insn"] [0];

            foreach (MiResultValue instructionValue in lineAsmInstructionValues.Values)
            {
              string address = instructionValue ["address"] [0].GetString ();

              if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS) != 0)
              {
                prgDisassembly [currentInstruction].bstrAddress = address;

                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS;
              }

              if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESSOFFSET) != 0)
              {
                string offset = instructionValue ["offset"] [0].GetString ();

                prgDisassembly [currentInstruction].bstrAddressOffset = offset;

                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESSOFFSET;
              }

              if (((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE) != 0) || ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS) != 0) || ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS) != 0))
              {
                string inst = instructionValue ["inst"] [0].GetString ();

                string [] operations = inst.Split (new string [] { "\\t" }, StringSplitOptions.None);

                if (operations.Length > 0)
                {
                  prgDisassembly [currentInstruction].bstrOpcode = operations [0];

                  prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE;
                }

                if (operations.Length > 1)
                {
                  prgDisassembly [currentInstruction].bstrOperands = operations [1];

                  prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS;
                }

                if (operations.Length > 2)
                {
                  prgDisassembly [currentInstruction].bstrOperands += " " + operations [2];

                  prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS;
                }
              }

              if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL) != 0)
              {
                string functionName = instructionValue ["func-name"] [0].GetString ();

                prgDisassembly [currentInstruction].bstrSymbol = functionName;

                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL;
              }

              if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID) != 0)
              {
                DebuggeeAddress instructionAddress = new DebuggeeAddress (address);

                prgDisassembly [currentInstruction].uCodeLocationId = instructionAddress.MemoryAddress;

                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID;
              }

              if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION) != 0)
              {
                prgDisassembly [currentInstruction].posBeg.dwLine = line;

                prgDisassembly [currentInstruction].posBeg.dwColumn = 0;

                prgDisassembly [currentInstruction].posEnd.dwLine = line;

                prgDisassembly [currentInstruction].posEnd.dwColumn = uint.MaxValue;

                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION;
              }

              if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_DOCUMENTURL) != 0)
              {
                prgDisassembly [currentInstruction].bstrDocumentUrl = "file://" + file;

                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_DOCUMENTURL;
              }

              if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_BYTEOFFSET) != 0)
              {
                uint offset = instructionValue ["offset"] [0].GetUnsignedInt ();

                prgDisassembly [currentInstruction].dwByteOffset = offset;

                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_BYTEOFFSET;
              }

              if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_FLAGS) != 0)
              {
                prgDisassembly [currentInstruction].dwFlags |= enum_DISASSEMBLY_FLAGS.DF_HASSOURCE;

                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_FLAGS;
              }

              if (++currentInstruction >= maxInstructions)
              {
                break;
              }
            }
          }
        }

        pdwInstructionsRead = (uint) currentInstruction;

        return Constants.S_OK;
      }
      catch (Exception e)
      {
        LoggingUtils.HandleException (e);

        pdwInstructionsRead = 0;

        return Constants.E_FAIL;
      }
    }
コード例 #20
0
 /// <summary>
 /// Initialize/use the bstrSymbol field.
 /// </summary>
 public static bool GetSymbol(this enum_DISASSEMBLY_STREAM_FIELDS fields)
 {
     return((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL) != 0);
 }
コード例 #21
0
        public int Read(uint dwInstructions, enum_DISASSEMBLY_STREAM_FIELDS dwFields, out uint pdwInstructionsRead, DisassemblyData[] prgDisassembly)
        {
            pdwInstructionsRead = 0;

            if (_method == null)
            {
                return(HResults.E_DISASM_NOTAVAILABLE);
            }

            var method   = _method.Method;
            var insCount = method.Body.Instructions.Count;

            bool wantsDocumentUrl = (dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_DOCUMENTURL) != 0;
            bool wantsPosition    = (dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION) != 0;
            bool wantsByteOffset  = (dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_BYTEOFFSET) != 0;
            bool wantsFlags       = (dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_FLAGS) != 0;

            for (pdwInstructionsRead = 0; pdwInstructionsRead < dwInstructions; ++pdwInstructionsRead, ++_instructionPointer)
            {
                int ip = _instructionPointer;

                if (ip >= insCount)
                {
                    break;
                }

                var insd = new DisassemblyData();
                var ins  = method.Body.Instructions[ip];


                if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS) != 0)
                {
                    insd.bstrAddress = _method.FormatAddress(ins);
                    insd.dwFields   |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS;
                }

                if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID) != 0)
                {
                    insd.uCodeLocationId = (ulong)ins.Offset;
                    insd.dwFields       |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID;
                }

                if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE) != 0)
                {
                    insd.bstrOpcode = _method.FormatOpCode(ins);
                    insd.dwFields  |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE;
                }

                if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS) != 0)
                {
                    insd.bstrOperands = _method.FormatOperands(ins);
                    insd.dwFields    |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS;
                }

                if (wantsDocumentUrl || wantsPosition || wantsByteOffset || wantsFlags)
                {
                    var source    = _method.FindSourceCode(ins.Offset);
                    var hasSource = source != null && !source.IsSpecial;

                    bool isSameDocAsPrevious, isSameDocPos;

                    if (hasSource)
                    {
                        isSameDocAsPrevious = _prevSource != null &&
                                              !_prevSource.IsSpecial &&
                                              _prevSource.Document.Path == source.Document.Path;
                        isSameDocPos = _prevSource != null && !_prevSource.IsSpecial &&
                                       isSameDocAsPrevious &&
                                       source.Position.CompareTo(_prevSource.Position) == 0;
                    }
                    else
                    {
                        isSameDocAsPrevious = (source == null && _prevSource == null) || (source != null && _prevSource != null && _prevSource.IsSpecial);
                        isSameDocPos        = isSameDocAsPrevious;
                    }

                    if (wantsDocumentUrl && (!isSameDocAsPrevious || _justSeeked))
                    {
                        if (hasSource)
                        {
                            insd.bstrDocumentUrl = "file://" + source.Document.Path;
                            insd.dwFields       |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_DOCUMENTURL;
                        }
                        // how do I clear the document?
                    }

                    int byteOffset = 0;

                    if ((wantsByteOffset || wantsPosition) && hasSource)
                    {
                        if (isSameDocPos)
                        {
                            byteOffset = ins.Offset - _prevSourceInstructionOffset;
                        }
                        else
                        {
                            byteOffset = 0;
                            _prevSourceInstructionOffset = ins.Offset;
                        }
                    }

                    if (wantsPosition && hasSource && !isSameDocPos)
                    {
                        var pos = source.Position;

                        insd.posBeg.dwLine   = (uint)(pos.Start.Line - 1);
                        insd.posBeg.dwColumn = (uint)(pos.Start.Column - 1);
                        insd.posEnd.dwLine   = (uint)(pos.End.Line - 1);
                        insd.posEnd.dwColumn = (uint)(pos.End.Column - 1);

                        if (insd.posEnd.dwLine - insd.posBeg.dwLine > 3) // never show more than 3 lines.
                        {
                            insd.posEnd.dwLine = insd.posBeg.dwLine + 3;
                        }

                        // Is this just me? I have no idea why my VS throws an exception when using this.
                        //insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION;
                    }

                    if (wantsByteOffset && hasSource)
                    {
                        insd.dwByteOffset = (uint)byteOffset;
                        insd.dwFields    |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_BYTEOFFSET;
                    }

                    if (wantsFlags)
                    {
                        if (!isSameDocAsPrevious)
                        {
                            insd.dwFlags |= enum_DISASSEMBLY_FLAGS.DF_DOCUMENTCHANGE;
                        }
                        if (hasSource)
                        {
                            insd.dwFlags |= enum_DISASSEMBLY_FLAGS.DF_HASSOURCE;
                        }

                        //if (_loc.Location.Index == (ulong)ins.Offset)
                        //    insd.dwFlags |= enum_DISASSEMBLY_FLAGS.DF_INSTRUCTION_ACTIVE;


                        insd.dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_FLAGS;
                    }

                    if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS) != 0)
                    {
                        if (!hasSource && !isSameDocPos)
                        {
                            insd.dwFields  |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS;
                            insd.bstrSymbol = "(generated instructions)";
                        }
                        else if (hasSource && !isSameDocPos)
                        {
                            // workaround to show something at least
                            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS) != 0)
                            {
                                insd.dwFields  |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS;
                                insd.bstrSymbol = "File Position: " + source.Position.Start + " - " + source.Position.End;
                            }
                        }
                    }

                    _justSeeked = false;
                    _prevSource = source;
                }

                prgDisassembly[pdwInstructionsRead] = insd;
            }

            return(pdwInstructionsRead == 0 || _instructionPointer >= insCount ? VSConstants.S_FALSE : VSConstants.S_OK);
        }
コード例 #22
0
 /// <summary>
 /// Initialize/use the bstrCodeBytes field.
 /// </summary>
 public static bool GetCodeBytes(this enum_DISASSEMBLY_STREAM_FIELDS fields)
 {
     return((fields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODEBYTES) != 0);
 }