Ejemplo n.º 1
0
        public int Seek(enum_SEEK_START dwSeekStart, IDebugCodeContext2 pCodeContext, ulong uCodeLocationId, long iInstructions)
        {
            if (dwSeekStart == enum_SEEK_START.SEEK_START_CODECONTEXT)
            {
                AD7MemoryAddress addr = pCodeContext as AD7MemoryAddress;
                _addr = addr.Address;
            }
            else if (dwSeekStart == enum_SEEK_START.SEEK_START_CODELOCID)
            {
                _addr = (uint)uCodeLocationId;
            }

            //if (iInstructions != 0)
            //{
            //    IEnumerable<DisasmInstruction> instructions = null;
            //    _engine.DebuggedProcess.WorkerThread.RunOperation(async () =>
            //    {
            //        instructions = await _engine.DebuggedProcess.Disassembly.FetchInstructions(_addr, (int)iInstructions);
            //    });
            //    if (instructions == null)
            //    {
            //        return VSConstants.E_FAIL;
            //    }
            //    _addr = instructions.ElementAt(0).Addr;
            //}
            return(VSConstants.S_OK);
        }
Ejemplo n.º 2
0
        public int Seek(enum_SEEK_START dwSeekStart, IDebugCodeContext2 pCodeContext, ulong uCodeLocationId, long iInstructions)
        {
            if (dwSeekStart == enum_SEEK_START.SEEK_START_CODECONTEXT)
            {
                AD7MemoryAddress addr = pCodeContext as AD7MemoryAddress;
                _addr = addr.Address;
            }
            else if (dwSeekStart == enum_SEEK_START.SEEK_START_CODELOCID)
            {
                _addr = (uint)uCodeLocationId;
            }

            if (iInstructions != 0)
            {
                DebuggedProcess process = DebuggedProcess.g_Process;
                IEnumerable <DisasmInstruction> instructions = null;
                process.WorkerThread.RunOperation(async() =>
                {
                    instructions = await process.Disassembly.FetchInstructions(_addr, (int)iInstructions);
                });
                if (instructions == null)
                {
                    return(Constants.E_FAIL);
                }
                _addr = instructions.ElementAt(0).Addr;
            }
            return(Constants.S_OK);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Moves the read pointer in the disassembly stream a given number of instructions relative to a specified position.
        /// </summary>
        /// <param name="dwSeekStart">
        /// [in] A value from the SEEK_START enumeration that specifies the relative position to begin the seek process.
        /// </param>
        /// <param name="pCodeContext">
        /// [in] The IDebugCodeContext2 object representing the code context that the seek operation is relative to. This
        /// parameter is used only if dwSeekStart = SEEK_START_CODECONTEXT; otherwise, this parameter is ignored and can be
        /// a null value.
        /// </param>
        /// <param name="uCodeLocationId">
        /// [in] The code location identifier that the seek operation is relative to. This parameter is used if
        /// dwSeekStart = SEEK_START_CODELOCID; otherwise, this parameter is ignored and can be set to 0. See the Remarks
        /// section for the IDebugDisassemblyStream2.GetCodeLocationId method for a description of a code location identifier.
        /// </param>
        /// <param name="iInstructions">
        /// [in] The number of instructions to move relative to the position specified in dwSeekStart. This value can be
        /// negative to move backwards.
        /// </param>
        /// <returns>
        /// If successful, returns S_OK. Returns S_FALSE if the seek position was to a point beyond the list of available
        /// instructions. Otherwise, returns an error code.
        /// </returns>
        /// <remarks>
        /// If the seek was to a position before the beginning of the list, the read position is set to the first instruction
        /// in the list. If the see was to a position after the end of the list, the read position is set to the last
        /// instruction in the list.
        /// </remarks>
        public int Seek(enum_SEEK_START dwSeekStart, IDebugCodeContext2 pCodeContext, ulong uCodeLocationId, long iInstructions)
        {
            switch (dwSeekStart)
            {
            case enum_SEEK_START.SEEK_START_BEGIN:
                _currentInstructionIndex = 0;
                break;

            case enum_SEEK_START.SEEK_START_CODECONTEXT:
                int error = GetCodeLocationId(pCodeContext, out uCodeLocationId);
                if (!ErrorHandler.Succeeded(error))
                {
                    return(error);
                }

                goto case enum_SEEK_START.SEEK_START_CODELOCID;

            case enum_SEEK_START.SEEK_START_CODELOCID:
                _currentInstructionIndex = _disassembledMethod.Instructions.FindIndex(i => i.Offset == (int)uCodeLocationId);
                if (_currentInstructionIndex < 0)
                {
                    throw new ArgumentException();
                }

                break;

            case enum_SEEK_START.SEEK_START_CURRENT:
                break;

            case enum_SEEK_START.SEEK_START_END:
                _currentInstructionIndex = _disassembledMethod.Instructions.Count;
                break;

            default:
                throw new ArgumentException("Invalid seek start location.");
            }

            _currentInstructionIndex += (int)iInstructions;
            if (_currentInstructionIndex >= 0 && _currentInstructionIndex <= _disassembledMethod.Instructions.Count)
            {
                return(VSConstants.S_OK);
            }

            _currentInstructionIndex = Math.Max(0, _currentInstructionIndex);
            _currentInstructionIndex = Math.Min(_disassembledMethod.Instructions.Count, _currentInstructionIndex);
            return(VSConstants.S_FALSE);
        }
Ejemplo n.º 4
0
        public int Seek(enum_SEEK_START dwSeekStart, IDebugCodeContext2 pCodeContext, ulong uCodeLocationId, long iInstructions)
        {
            _justSeeked = true;
            _prevSource = null;
            _prevSourceInstructionOffset = -1;

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

            var method = _method.Method;

            var insCount = method.Body.Instructions.Count;
            int newPos;

            switch (dwSeekStart)
            {
            case enum_SEEK_START.SEEK_START_BEGIN:
                newPos = (int)iInstructions;
                break;

            case enum_SEEK_START.SEEK_START_END:

                newPos = insCount + (int)iInstructions;
                break;

            case enum_SEEK_START.SEEK_START_CURRENT:
                newPos = _instructionPointer + (int)iInstructions;
                break;

            default:
                return(VSConstants.E_NOTIMPL);
            }

            _instructionPointer = newPos < 0 ? 0 : newPos >= insCount ? insCount - 1 : newPos;

            if (newPos < 0 || newPos >= insCount)
            {
                return(VSConstants.S_FALSE);
            }

            return(VSConstants.S_OK);
        }
Ejemplo n.º 5
0
        public int Seek(enum_SEEK_START dwSeekStart, IDebugCodeContext2 pCodeContext, ulong uCodeLocationId, long iInstructions)
        {
            if (dwSeekStart == enum_SEEK_START.SEEK_START_CODECONTEXT)
            {
                AD7MemoryAddress addr = pCodeContext as AD7MemoryAddress;
                _addr = addr.Address;
            }
            else if (dwSeekStart == enum_SEEK_START.SEEK_START_CODELOCID)
            {
                _addr = uCodeLocationId;
            }

            if (iInstructions >= 0)
            {
                return(SeekForward(iInstructions));
            }
            else
            {
                return(SeekBack(-iInstructions));
            }
        }
Ejemplo n.º 6
0
        public int Seek(enum_SEEK_START dwSeekStart, IDebugCodeContext2 pCodeContext, ulong uCodeLocationId, long iInstructions)
        {
            if (dwSeekStart == enum_SEEK_START.SEEK_START_CODECONTEXT)
            {
                AD7MemoryAddress addr = pCodeContext as AD7MemoryAddress;
                _addr = addr.Address;
            }
            else if (dwSeekStart == enum_SEEK_START.SEEK_START_CODELOCID)
            {
                _addr = (uint)uCodeLocationId;
            }

            if (iInstructions != 0)
            {
                IEnumerable<DisasmInstruction> instructions = null;
                _engine.DebuggedProcess.WorkerThread.RunOperation(async () =>
                {
                    instructions = await _engine.DebuggedProcess.Disassembly.FetchInstructions(_addr, (int)iInstructions);
                });
                if (instructions == null)
                {
                    return Constants.E_FAIL;
                }
                _addr = instructions.ElementAt(0).Addr;
            }
            return Constants.S_OK;
        }
Ejemplo n.º 7
0
        public int Seek(enum_SEEK_START dwSeekStart, IDebugCodeContext2 pCodeContext, ulong uCodeLocationId, long iInstructions)
        {
            _justSeeked = true;
            _prevSource = null;
            _prevSourceInstructionOffset = -1;

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

            var method = _method.Method;

            var insCount = method.Body.Instructions.Count;
            int newPos;

            switch (dwSeekStart)
            {
                case enum_SEEK_START.SEEK_START_BEGIN:
                    newPos = (int)iInstructions;
                    break;
                case enum_SEEK_START.SEEK_START_END:

                    newPos = insCount + (int)iInstructions;
                    break;
                case enum_SEEK_START.SEEK_START_CURRENT:
                    newPos = _instructionPointer + (int)iInstructions;
                    break;
                default:
                    return VSConstants.E_NOTIMPL;
            }

            _instructionPointer = newPos < 0 ? 0 : newPos >= insCount ? insCount - 1 : newPos;

            if (newPos < 0 || newPos >= insCount)
                return VSConstants.S_FALSE;

            return VSConstants.S_OK;
        }
Ejemplo n.º 8
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int Seek(enum_SEEK_START dwSeekStart, IDebugCodeContext2 pCodeContext, ulong uCodeLocationId, long iInstructions)
        {
            //
            // Moves the read pointer in the disassembly stream a given number of instructions relative to a specified position.
            //

            LoggingUtils.PrintFunction();

            try
            {
                switch (dwSeekStart)
                {
                case enum_SEEK_START.SEEK_START_BEGIN:
                {
                    //
                    // Starts seeking at the beginning of the current document.
                    //

                    throw new NotImplementedException();
                }

                case enum_SEEK_START.SEEK_START_END:
                {
                    //
                    // Starts seeking at the end of the current document.
                    //

                    throw new NotImplementedException();
                }

                case enum_SEEK_START.SEEK_START_CURRENT:
                {
                    //
                    // Starts seeking at the current position of the current document.
                    //

                    ulong offsetAddress = m_codeContext.Address.MemoryAddress;

                    if (iInstructions > 0)
                    {
                        offsetAddress += (ulong)(iInstructions * 4);
                    }
                    else if (iInstructions < 0)
                    {
                        offsetAddress += (ulong)(Math.Abs(iInstructions) * 4);
                    }

                    m_codeContext.Address = new DebuggeeAddress(offsetAddress);

                    break;
                }

                case enum_SEEK_START.SEEK_START_CODECONTEXT:
                {
                    //
                    // Starts seeking at the given code context of the current document.
                    //

                    DebuggeeCodeContext codeContext = (pCodeContext as DebuggeeCodeContext);

                    ulong offsetAddress = codeContext.Address.MemoryAddress;

                    if (iInstructions > 0)
                    {
                        offsetAddress += (ulong)(iInstructions * 4);
                    }
                    else if (iInstructions < 0)
                    {
                        offsetAddress += (ulong)(Math.Abs(iInstructions) * 4);
                    }

                    m_codeContext.Address = new DebuggeeAddress(offsetAddress);

                    break;
                }

                case enum_SEEK_START.SEEK_START_CODELOCID:
                {
                    //
                    // Starts seeking at the given code location identifier.
                    //

                    ulong offsetAddress = uCodeLocationId;

                    if (iInstructions > 0)
                    {
                        offsetAddress += (ulong)(iInstructions * 4);
                    }
                    else if (iInstructions < 0)
                    {
                        offsetAddress += (ulong)(Math.Abs(iInstructions) * 4);
                    }

                    m_codeContext.Address = new DebuggeeAddress(offsetAddress);

                    break;
                }
                }

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

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

                return(Constants.E_FAIL);
            }
        }
        /// <summary>
        /// Moves the read pointer in the disassembly stream a given number of instructions relative to a specified position.
        /// </summary>
        /// <param name="dwSeekStart">
        /// [in] A value from the SEEK_START enumeration that specifies the relative position to begin the seek process.
        /// </param>
        /// <param name="pCodeContext">
        /// [in] The IDebugCodeContext2 object representing the code context that the seek operation is relative to. This
        /// parameter is used only if dwSeekStart = SEEK_START_CODECONTEXT; otherwise, this parameter is ignored and can be
        /// a null value.
        /// </param>
        /// <param name="uCodeLocationId">
        /// [in] The code location identifier that the seek operation is relative to. This parameter is used if
        /// dwSeekStart = SEEK_START_CODELOCID; otherwise, this parameter is ignored and can be set to 0. See the Remarks
        /// section for the IDebugDisassemblyStream2.GetCodeLocationId method for a description of a code location identifier.
        /// </param>
        /// <param name="iInstructions">
        /// [in] The number of instructions to move relative to the position specified in dwSeekStart. This value can be
        /// negative to move backwards.
        /// </param>
        /// <returns>
        /// If successful, returns S_OK. Returns S_FALSE if the seek position was to a point beyond the list of available
        /// instructions. Otherwise, returns an error code.
        /// </returns>
        /// <remarks>
        /// If the seek was to a position before the beginning of the list, the read position is set to the first instruction
        /// in the list. If the see was to a position after the end of the list, the read position is set to the last
        /// instruction in the list.
        /// </remarks>
        public int Seek(enum_SEEK_START dwSeekStart, IDebugCodeContext2 pCodeContext, ulong uCodeLocationId, long iInstructions)
        {
            switch (dwSeekStart)
            {
            case enum_SEEK_START.SEEK_START_BEGIN:
                _currentInstructionIndex = 0;
                break;

            case enum_SEEK_START.SEEK_START_CODECONTEXT:
                int error = GetCodeLocationId(pCodeContext, out uCodeLocationId);
                if (!ErrorHandler.Succeeded(error))
                    return error;

                goto case enum_SEEK_START.SEEK_START_CODELOCID;

            case enum_SEEK_START.SEEK_START_CODELOCID:
                _currentInstructionIndex = _disassembledMethod.Instructions.FindIndex(i => i.Offset == (int)uCodeLocationId);
                if (_currentInstructionIndex < 0)
                    throw new ArgumentException();

                break;

            case enum_SEEK_START.SEEK_START_CURRENT:
                break;

            case enum_SEEK_START.SEEK_START_END:
                _currentInstructionIndex = _disassembledMethod.Instructions.Count;
                break;

            default:
                throw new ArgumentException("Invalid seek start location.");
            }

            _currentInstructionIndex += (int)iInstructions;
            if (_currentInstructionIndex >= 0 && _currentInstructionIndex <= _disassembledMethod.Instructions.Count)
                return VSConstants.S_OK;

            _currentInstructionIndex = Math.Max(0, _currentInstructionIndex);
            _currentInstructionIndex = Math.Min(_disassembledMethod.Instructions.Count, _currentInstructionIndex);
            return VSConstants.S_FALSE;
        }
Ejemplo n.º 10
0
        public int Seek(enum_SEEK_START seekStart, IDebugCodeContext2 codeContext,
                        ulong codeLocationId, long numInstructions)
        {
            if (seekStart == enum_SEEK_START.SEEK_START_CODECONTEXT)
            {
                _address = codeContext.GetAddress();
            }
            else if (seekStart == enum_SEEK_START.SEEK_START_CODELOCID)
            {
                _address = codeLocationId;
            }

            SbAddress sbAddress = _target.ResolveLoadAddress(_address);

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

            if (numInstructions > 0)
            {
                // seek forward
                numInstructions++;
                List <InstructionInfo> instructions =
                    _target.ReadInstructionInfos(sbAddress, (uint)numInstructions, _flavor);
                if (instructions.Count > 0)
                {
                    numInstructions = Math.Min(numInstructions, instructions.Count);
                    _address        = instructions[(int)numInstructions - 1].Address;
                }
            }
            else if (numInstructions < 0)
            {
                // TODO: Get opcode sizes from LLDB.
                // Hard-code the opcode sizes for x86_64. Currently LLDB doesn't expose this
                // information, and this is the only architecture we support.
                uint minOpcodeSize = 1;
                uint maxOpcodeSize = 15;

                // When seeking backwards we don't know the exact address since x86_64 is a variable
                // size instruction architecture. Instead we figure out the max range to fit a
                // specific number of instructions.
                uint maxRangeForInstructions = (uint)Math.Abs(numInstructions) * maxOpcodeSize;

                // Since x86_64 is a variable size instruction architecture we don't know the exact
                // number of instructions in a specific address range. Assume the smallest opcode
                // size and that will be the number of instructions we need to read.
                uint maxNumberInstructions = maxRangeForInstructions / minOpcodeSize;

                // Using the start address and the max possible range, we can determine the lower
                // bound for where we should start reading instructions from.
                ulong endAddress = _address - maxRangeForInstructions;

                // The instruction where we should start the seek.
                List <InstructionInfo> startInstructionList =
                    _target.ReadInstructionInfos(sbAddress, 1, _flavor);
                if (startInstructionList.Count == 0)
                {
                    Trace.WriteLine(
                        "Failed to seek backwards. Unable to read " +
                        $"instruction at 0x{_address:X} so we have no start point for the seek");
                    return(VSConstants.E_FAIL);
                }

                InstructionInfo startInstruction = startInstructionList[0];

                // We know there is an instruction around the |endAddress| but we don't know exactly
                // where it starts (because variable size instructions). LLDB will stop reading if
                // it runs into a bad instruction. We use that to our advantage and start reading
                // instructions from the |endAddress| + offset until LLDB returns us the number of
                // instructions we requested. We can then be fairly certain |endAddress| + offset is
                // the address to a valid instruction.
                int startIndex = -1;
                List <InstructionInfo> validInstructions = null;
                for (ulong i = 0; i < maxOpcodeSize; i++)
                {
                    ulong     seekAddress               = endAddress + i;
                    SbAddress seekSbAddress             = _target.ResolveLoadAddress(seekAddress);
                    List <InstructionInfo> instructions = _target.ReadInstructionInfos(
                        seekSbAddress, maxNumberInstructions + 1, _flavor);
                    // Shortcut: Continue if we did not get enough instructions.
                    if (instructions == null || instructions.Count < Math.Abs(numInstructions))
                    {
                        continue;
                    }
                    // Only accept the instructions if our start instruction is there.
                    try
                    {
                        startIndex = instructions.BinarySearch(startInstruction,
                                                               new InstructionComparator());
                        if (startIndex >= 0)
                        {
                            validInstructions = instructions;
                            break;
                        }
                    }
                    catch (InvalidOperationException e)
                    {
                        Trace.WriteLine(e);
                    }
                }

                if (startIndex < 0)
                {
                    Trace.WriteLine(
                        "Failed to seek backwards. Unable to find an instruction with " +
                        $"address 0x{_address:X} so we have no start point for the seek");
                    return(VSConstants.E_FAIL);
                }

                // Add the |startIndex| and the negative |numInstructions| to get the index of the
                // instruction to which we want to seek.
                int seekIndex = startIndex + (int)numInstructions;
                if (validInstructions == null || seekIndex < 0 ||
                    seekIndex >= validInstructions.Count)
                {
                    Trace.WriteLine($"Failed to seek backwards. Seek index {seekIndex} is out " +
                                    "of range");
                    return(VSConstants.E_FAIL);
                }
                _address = validInstructions[seekIndex].Address;
            }

            return(VSConstants.S_OK);
        }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int Seek (enum_SEEK_START dwSeekStart, IDebugCodeContext2 pCodeContext, ulong uCodeLocationId, long iInstructions)
    {
      // 
      // Moves the read pointer in the disassembly stream a given number of instructions relative to a specified position.
      // 

      LoggingUtils.PrintFunction ();

      try
      {
        switch (dwSeekStart)
        {
          case enum_SEEK_START.SEEK_START_BEGIN:
          {
            // 
            // Starts seeking at the beginning of the current document.
            // 

            throw new NotImplementedException ();
          }

          case enum_SEEK_START.SEEK_START_END:
          {
            // 
            // Starts seeking at the end of the current document.
            // 

            throw new NotImplementedException ();
          }

          case enum_SEEK_START.SEEK_START_CURRENT:
          {
            // 
            // Starts seeking at the current position of the current document.
            // 

            ulong offsetAddress = m_codeContext.Address.MemoryAddress;

            if (iInstructions > 0)
            {
              offsetAddress += (ulong)(iInstructions * 4);
            }
            else if (iInstructions < 0)
            {
              offsetAddress += (ulong)(Math.Abs (iInstructions) * 4);
            }

            m_codeContext.Address = new DebuggeeAddress (offsetAddress);

            break;
          }

          case enum_SEEK_START.SEEK_START_CODECONTEXT:
          {
            // 
            // Starts seeking at the given code context of the current document.
            // 

            DebuggeeCodeContext codeContext = (pCodeContext as DebuggeeCodeContext);

            ulong offsetAddress = codeContext.Address.MemoryAddress;

            if (iInstructions > 0)
            {
              offsetAddress += (ulong)(iInstructions * 4);
            }
            else if (iInstructions < 0)
            {
              offsetAddress += (ulong)(Math.Abs (iInstructions) * 4);
            }

            m_codeContext.Address = new DebuggeeAddress (offsetAddress);

            break;
          }

          case enum_SEEK_START.SEEK_START_CODELOCID:
          {
            // 
            // Starts seeking at the given code location identifier. 
            // 

            ulong offsetAddress = uCodeLocationId;

            if (iInstructions > 0)
            {
              offsetAddress += (ulong)(iInstructions * 4);
            }
            else if (iInstructions < 0)
            {
              offsetAddress += (ulong)(Math.Abs (iInstructions) * 4);
            }

            m_codeContext.Address = new DebuggeeAddress (offsetAddress);

            break;
          }
        }

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

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

        return Constants.E_FAIL;
      }
    }