fpc/tests/webtbs/tw35187.pp
Jonas Maebe fd42c3fb01 * only enable tw35187 for Windows and Linux, since it uses syscalls under unix
(which are not supported on all unix targets; feel free to re-enable for
     specific unix targets if the test has been verified to compile there)
   o also fixed placement of dotest directives: they have to come before any
     part of the program code

git-svn-id: trunk@41717 -
2019-03-16 19:14:17 +00:00

114 lines
3.1 KiB
ObjectPascal

{ %target=win32,win64,linux }
{ %cpu=i386,x86_64 }
{ %opt=-O1 }
program tw35187;
{ 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.