* patch by J. Gareth Moreton which avoids that the optimizer causes reads of invalid memory, resolves #35187

git-svn-id: trunk@41667 -
This commit is contained in:
florian 2019-03-10 10:48:50 +00:00
parent f52ea868dd
commit d657373933
3 changed files with 120 additions and 7 deletions

1
.gitattributes vendored
View File

@ -16551,6 +16551,7 @@ tests/webtbs/tw3506.pp svneol=native#text/plain
tests/webtbs/tw35139.pp svneol=native#text/plain
tests/webtbs/tw35139a.pp svneol=native#text/plain
tests/webtbs/tw35149.pp svneol=native#text/plain
tests/webtbs/tw35187.pp svneol=native#text/pascal
tests/webtbs/tw3523.pp svneol=native#text/plain
tests/webtbs/tw3529.pp svneol=native#text/plain
tests/webtbs/tw3531.pp svneol=native#text/plain

View File

@ -3484,44 +3484,44 @@ unit aoptx86;
MatchOpType(taicpu(hp1),top_const,top_reg) and
(taicpu(hp1).oper[1]^.reg = taicpu(p).oper[1]^.reg) then
begin
taicpu(p).opcode := A_MOV;
//taicpu(p).opcode := A_MOV;
case taicpu(p).opsize Of
S_BL:
begin
DebugMsg(SPeepholeOptimization + 'var13',p);
taicpu(p).changeopsize(S_L);
taicpu(hp1).changeopsize(S_L);
taicpu(hp1).loadConst(0,taicpu(hp1).oper[0]^.val and $ff);
end;
S_WL:
begin
DebugMsg(SPeepholeOptimization + 'var14',p);
taicpu(p).changeopsize(S_L);
taicpu(hp1).changeopsize(S_L);
taicpu(hp1).loadConst(0,taicpu(hp1).oper[0]^.val and $ffff);
end;
S_BW:
begin
DebugMsg(SPeepholeOptimization + 'var15',p);
taicpu(p).changeopsize(S_W);
taicpu(hp1).changeopsize(S_W);
taicpu(hp1).loadConst(0,taicpu(hp1).oper[0]^.val and $ff);
end;
{$ifdef x86_64}
S_BQ:
begin
DebugMsg(SPeepholeOptimization + 'var16',p);
taicpu(p).changeopsize(S_Q);
taicpu(hp1).changeopsize(S_Q);
taicpu(hp1).loadConst(
0, taicpu(hp1).oper[0]^.val and $ff);
end;
S_WQ:
begin
DebugMsg(SPeepholeOptimization + 'var17',p);
taicpu(p).changeopsize(S_Q);
taicpu(hp1).changeopsize(S_Q);
taicpu(hp1).loadConst(0, taicpu(hp1).oper[0]^.val and $ffff);
end;
S_LQ:
begin
DebugMsg(SPeepholeOptimization + 'var18',p);
taicpu(p).changeopsize(S_Q);
taicpu(hp1).changeopsize(S_Q);
taicpu(hp1).loadConst(
0, taicpu(hp1).oper[0]^.val and $ffffffff);
end;

112
tests/webtbs/tw35187.pp Normal file
View File

@ -0,0 +1,112 @@
program tw35187;
{ %cpu=i386,x86_64 }
{ %opt=-O1 }
{ NOTE: SIGSEGV won't trigger if GetMem is used because it allocates pages from a large pre-reserved heap. [Kit] }
{$IFDEF TARGET_VALID}
{$UNDEF TARGET_VALID}
{$ENDIF TARGET_VALID}
{$IFDEF WINDOWS}
uses
Windows;
{$DEFINE TARGET_VALID}
{$ENDIF}
{$IFDEF UNIX}
uses
BaseUnix, SysCall;
function fpmprotect(Addr: Pointer; Len: PtrUInt; Prot: LongInt): LongInt; inline;
begin
fpmprotect := Do_SysCall(syscall_nr_mprotect, TSysParam(Addr), Len, Prot);
end;
{$DEFINE TARGET_VALID}
{$ENDIF}
{$IFNDEF TARGET_VALID}
{$ERROR No memory allocation routine available }
{$ENDIF TARGET_VALID}
const
TestBlock: packed array[0..127] of Char = 'The quick brown fox jumps over the lazy dog, Victor jagt zw'#148'lf Boxk'#132'mpfer quer '#129'ber den gro'#225'en Sylter Deich.'#10#13'0123456789?!"#%'#251#253#252;
Expected: packed array[0..255] of Char = '54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672C20566963746F72206A616774207A77946C6620426F786B846D70666572207175657220816265722064656E2067726FE1656E2053796C7465722044656963682E0A0D303132333435363738393F21222325FBFDFC';
HexDigits: packed array[0..$F] of Char = '0123456789ABCDEF';
var
Buf: packed array[0..255] of Char;
HexPtr: PChar;
P: PByte;
I: DWord;
HeapBlock, HeapMarker: PByte;
begin
WriteLn(TestBlock);
FillChar(Buf, SizeOf(Buf), 0);
{ Reserve two 4K memory pages: one that is read-write followed by one that
has no access rights at all and will trigger SIGSEGV if encroached }
{$IFDEF WINDOWS}
HeapBlock := VirtualAlloc(
VirtualAlloc(nil, 8192, MEM_RESERVE, PAGE_READWRITE),
4096,
MEM_COMMIT,
PAGE_READWRITE
);
if not Assigned(HeapBlock) then
begin
WriteLn('Memory allocation failure');
Halt(1);
end;
HeapMarker := HeapBlock + 3968; { 4096 - 128 }
{$ENDIF WINDOWS}
{$IFDEF UNIX}
HeapBlock := fpmmap(nil, 8192, PROT_NONE, MAP_ANON or MAP_PRIVATE, -1, 0);
if not Assigned(HeapBlock) or (fpmprotect(HeapBlock, 4096, PROT_READ or PROT_WRITE) <> 0) then
begin
WriteLn('Memory allocation failure');
Halt(1);
end;
HeapMarker := HeapBlock + 3968; { 4096 - 128 }
{$ENDIF UNIX}
Move(TestBlock, HeapMarker^, SizeOf(TestBlock));
HexPtr := @Buf;
for I := 0 to SizeOf(TestBlock) - 1 do
begin
P := HeapMarker + I;
HexPtr^ := HexDigits[P^ shr 4]; { first nybble }
Write(HexPtr^);
Inc(HexPtr);
{ #35187: This instruction causes an access violation on the last byte
because it tries to read a word instead of a byte. }
HexPtr^ := HexDigits[P^ and $F]; { second nybble }
Write(HexPtr^);
Inc(HexPtr);
end;
{$IFDEF WINDOWS}
VirtualFree(HeapBlock, 0, MEM_RELEASE);
{$ENDIF WINDOWS}
{$IFDEF UNIX}
fpmunmap(HeapBlock, 8192);
{$ENDIF UNIX}
WriteLn();
for I := 0 to SizeOf(TestBlock) - 1 do
if Buf[I] <> Expected[I] then
begin
WriteLn('Error at index ', I, '; expected ', Expected[I], ' got ', Buf[I]);
Halt(1);
end;
WriteLn('ok');
end.