private unsafe void SearchBlock <T, THelper>(Action <DbgMemory> yield, Span <byte> bytes, ulong searchMask, ulong searchValue, ulong page) where T : unmanaged where THelper : struct, IIntegralTypeHelper <T> { THelper helper = default; T value = helper.ConvertUlong(searchValue); T mask = helper.ConvertUlong(searchMask); var dwords = MemoryMarshal.Cast <byte, T>(bytes); for (int i = 0; i < dwords.Length; i++) { if (helper.AreEqual(helper.BitwiseAnd(dwords[i], mask), value)) { int byteIdx = i * sizeof(T); ulong address = page + (ulong)byteIdx; var valueBytes = bytes.Slice(byteIdx, sizeof(T)).ToArray(); var result = new DbgMemory(address, valueBytes, Debugger) { DefaultDisplayFormat = helper.DisplayFormat }; yield(result); } } }
protected override void ProcessRecord() { base.ProcessRecord(); if (0 == Address) { Address = NextAddressToDump; } if (!MyInvocation.BoundParameters.ContainsKey("DefaultDisplayFormat")) { DefaultDisplayFormat = NextDefaultFormat; } if (!MyInvocation.BoundParameters.ContainsKey("LengthInBytes")) { if (DefaultDisplayFormat != NextDefaultFormat) { // We're switching formats; may need to also switch the default size. LengthInBytes = _GetDefaultReadSize(DefaultDisplayFormat); } else { LengthInBytes = NextDefaultLengthInBytes; } } if (0 == LengthInBytes) { LengthInBytes = _GetDefaultReadSize(DefaultDisplayFormat); } // Okay, we've got a length + display format, but one or the other may be // defaulted. In that case, we want to make sure that the LengthInBytes is // compatible with the display format. (And actually, even if they were both // explicitly specified, we /still/ want to make sure they are compatible.) // // For instance, if the LengthInBytes was explicitly specified as 4, and the // display format got defaulted to PointersWithAscii, on a 64-bit target, we // are not going to be able to display anything (because we won't have read // even a single full pointer)--we need to downgrade the display format to fit // the size requested, if possible. if (!_IsDisplayFormatCompatibleWithReadSize(LengthInBytes, DefaultDisplayFormat, Debugger.PointerSize)) { var compatibleDisplayFormat = _GetDefaultDisplayFormatForSize(LengthInBytes, Debugger.PointerSize); if (MyInvocation.BoundParameters.ContainsKey("DefaultDisplayFormat")) { SafeWriteWarning("The specified display format ({0}) is not compatible with the byte length requested ({1}). The {2} format will be used instead.", DefaultDisplayFormat, LengthInBytes, compatibleDisplayFormat); } // else just silently fix it up. DefaultDisplayFormat = compatibleDisplayFormat; } if (!MyInvocation.BoundParameters.ContainsKey("DefaultDisplayColumns")) { DefaultDisplayColumns = NextDefaultNumColumns; } var raw = Debugger.ReadMem(Address, LengthInBytes, false); if (raw.Length != LengthInBytes) { WriteWarning(Util.Sprintf("Actual memory read (0x{0:x} bytes) is less than requested (0x{1:x} bytes).", raw.Length, LengthInBytes)); } var mem = new DbgMemory(Address, raw, Debugger.TargetIs32Bit, false, // TODO: actually determine endianness Debugger); mem.DefaultDisplayFormat = DefaultDisplayFormat; mem.DefaultDisplayColumns = DefaultDisplayColumns; NextAddressToDump = Address + (ulong)raw.Length; NextDefaultFormat = DefaultDisplayFormat; NextDefaultLengthInBytes = LengthInBytes; NextDefaultNumColumns = DefaultDisplayColumns; WriteObject(mem); DbgProvider.SetAutoRepeatCommand(Util.Sprintf("{0}", MyInvocation.InvocationName)); } // end ProcessRecord()
protected override void ProcessRecord() { base.ProcessRecord(); if (0 == Address) { Address = NextAddressToDump; } if (!MyInvocation.BoundParameters.ContainsKey("DefaultDisplayFormat")) { DefaultDisplayFormat = NextDefaultFormat; } if (!MyInvocation.BoundParameters.ContainsKey("LengthInBytes")) { if (DefaultDisplayFormat != NextDefaultFormat) { // We're switching formats; may need to also switch the default size. LengthInBytes = _GetDefaultReadSize(DefaultDisplayFormat); } else { LengthInBytes = NextDefaultLengthInBytes; } } if (0 == LengthInBytes) { LengthInBytes = _GetDefaultReadSize(DefaultDisplayFormat); } if (!MyInvocation.BoundParameters.ContainsKey("DefaultDisplayColumns")) { DefaultDisplayColumns = NextDefaultNumColumns; } var raw = Debugger.ReadMem(Address, LengthInBytes, false); if (raw.Length != LengthInBytes) { WriteWarning(Util.Sprintf("Actual memory read (0x{0:x} bytes) is less than requested (0x{1:x} bytes).", raw.Length, LengthInBytes)); } var mem = new DbgMemory(Address, raw, Debugger.TargetIs32Bit, false, // TODO: actually determine endianness Debugger); mem.DefaultDisplayFormat = DefaultDisplayFormat; mem.DefaultDisplayColumns = DefaultDisplayColumns; NextAddressToDump = Address + (ulong)raw.Length; NextDefaultFormat = DefaultDisplayFormat; NextDefaultLengthInBytes = LengthInBytes; NextDefaultNumColumns = DefaultDisplayColumns; WriteObject(mem); DbgProvider.SetAutoRepeatCommand(Util.Sprintf("{0}", MyInvocation.InvocationName)); } // end ProcessRecord()