From b73bed0fed70a82fd889a977227df251d85d38a2 Mon Sep 17 00:00:00 2001 From: ccrause Date: Sun, 14 Apr 2024 13:45:28 +0200 Subject: [PATCH] FpDebug: Handle partial overlap between breakpoint data and AData buffer. By CCrause. MR: !279 --- components/fpdebug/fpdbgclasses.pp | 42 ++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/components/fpdebug/fpdbgclasses.pp b/components/fpdebug/fpdbgclasses.pp index 2008434e26..b6398a6dcd 100644 --- a/components/fpdebug/fpdbgclasses.pp +++ b/components/fpdebug/fpdbgclasses.pp @@ -1625,13 +1625,45 @@ procedure TGenericBreakPointTargetHandler.MaskBreakpointsInReadData(const AAdres const ASize: Cardinal; var AData); var MapEnumData: TFpBreakPointMap.TFpBreakPointMapEnumerationData; - offset: TDbgPtr; + i, len: TDBGPtr; + PtrOrig: Pointer; begin for MapEnumData in BreakMap do begin - if not HPtr(MapEnumData.TargetHandlerDataPtr)^.ErrorSetting and (MapEnumData.Location >= AAdress) and (MapEnumData.Location < (AAdress+ASize)) then - begin - offset := MapEnumData.Location - AAdress; - P_BRK_STORE(@AData + offset)^ := HPtr(MapEnumData.TargetHandlerDataPtr)^.OrigValue; + // Does break instruction fall completely outside AData + if (MapEnumData.Location + SizeOf(_BRK_STORE) <= AAdress) or + (MapEnumData.Location >= (AAdress + ASize)) or + HPtr(MapEnumData.TargetHandlerDataPtr)^.ErrorSetting then + continue; + + if (MapEnumData.Location >= AAdress) and (MapEnumData.Location + SizeOf(_BRK_STORE) <= (AAdress + ASize)) then begin + // Breakpoint is completely inside AData + // MapEnumData.Location >= AAdress + i := MapEnumData.Location - AAdress; + P_BRK_STORE(@AData + i)^ := HPtr(MapEnumData.TargetHandlerDataPtr)^.OrigValue; + end + else + if (MapEnumData.Location < AAdress) then begin + // Breakpoint starts on or partially overlaps with start of AData + // Breakpoint may overhang past end of AData + // AAdress > MapEnumData.Location + i := AAdress - MapEnumData.Location; + // i < SizeOf(_BRK_STORE) / since MapEnumData.Location + SizeOf(_BRK_STORE) > AAdress + len := SizeOf(_BRK_STORE) - i; + // Do not write past end of AData + if len > ASize then + len := ASize; + + PtrOrig := @HPtr(MapEnumData.TargetHandlerDataPtr)^.OrigValue; + move(PByte(PtrOrig+i)^, PByte(@AData)^, len); + end + else begin + // Breakpoint partially overlaps with end of AData + // MapEnumData.Location > AAdress + // MapEnumData.Location < AAdress + ASize; + i := MapEnumData.Location - AAdress; + len := ASize - i; // AAdress + ASize - MapEnumData.Location; + PtrOrig := @HPtr(MapEnumData.TargetHandlerDataPtr)^.OrigValue; + move(PByte(PtrOrig)^, PByte(@AData+i)^, len); end; end; end;