Skip to content

Problem on RPI5 with Python13 #510

@comdora

Description

@comdora

Hi,
using the last version of P4D on RPI 5 leads to Exception External SIGSEGV.
Problem is in method function GetCallBack(Self: TObject; Method: Pointer; ArgNum: Integer;
CallType: TCallType): Pointer;

nmap didn't allocate the memory.

I have solved this problem changing the method code in way

{$IFDEF CPUARM64}
function  GetCallBack(Self: TObject; Method: Pointer; ArgNum: Integer;
  CallType: TCallType): Pointer;
const
  S1: array[0..79] of byte = (
//big-endian
//offset  <_start>:
  $fd, $7b, $bf, $a9,  //	stp	x29, x30, [sp, #-16]!
  $fd, $03, $00, $91,  //	mov	x29, sp
  $e0, $07, $bf, $a9,  //	stp	x0, x1, [sp, #-16]!
  $e2, $0f, $bf, $a9,  //	stp	x2, x3, [sp, #-16]!
  $e4, $17, $bf, $a9,  //	stp	x4, x5, [sp, #-16]!
  $e6, $1f, $bf, $a9,  //	stp	x6, x7, [sp, #-16]!
  $0a, $00, $00, $10,  //	adr	x10, #0 <_start+0x18>
  $40, $15, $40, $f9,  //	ldr	x0, [x10, #40]
  $49, $19, $40, $f9,  //	ldr	x9, [x10, #48]
  $e7, $2f, $c1, $a8,  //	ldp	x7, x11, [sp], #16
  $e5, $1b, $c1, $a8,  //	ldp	x5, x6, [sp], #16
  $e3, $13, $c1, $a8,  //	ldp	x3, x4, [sp], #16
  $e1, $0b, $c1, $a8,  //	ldp	x1, x2, [sp], #16
  $20, $01, $3f, $d6,  //	blr	x9
  $fd, $7b, $c1, $a8,  //	ldp	x29, x30, [sp], #16
  $c0, $03, $5f, $d6,  //	ret
  $00, $00, $00, $00,  //	.word	0x00000000 //Self
  $00, $00, $00, $00,  //	.word	0x00000000
  $00, $00, $00, $00,  //	.word	0x00000000 //Method
  $00, $00, $00, $00   //	.word	0x00000000
);
const
  PageSize = 4096;
var
  P, Q: PByte;
  LLiteralPool: TArray<pointer>;
  I: Integer;
  addr: Pointer;
begin
  GetCodeMem(Q, SizeOf(S1));
  if Q = nil then
  begin
    addr := fpMmap(nil, PageSize, PROT_READ or PROT_WRITE or PROT_EXEC, MAP_PRIVATE or MAP_ANONYMOUS, -1, 0);
    if addr = Pointer(-1) then
    	{$IFDEF UNIX}
      raise Exception.Create('mmap failed: ' + SysErrorMessage(GetLastOSError));
    	{$ENDIF}
    Q := PByte(addr);
  end;

  P := Q;
  Move(S1, P^, SizeOf(S1));

  LLiteralPool := TArray<pointer>.Create(Self, Method);

  Inc(P, Length(S1) - (Length(LLiteralPool) * SizeOf(pointer)));
  for I := Low(LLiteralPool) to High(LLiteralPool) do begin
    Move(LLiteralPool[I], P^, SizeOf(pointer));
    Inc(P, SizeOf(pointer));
  end;
  {$IFDEF UNIX}
  if fpMprotect(Pointer(Q), SizeOf(S1), PROT_READ or PROT_EXEC) <> 0 then
    raise Exception.Create('mprotect failed: ' + SysErrorMessage(GetLastOSError));
  {$ENDIF}

  {$IF DEFINED(OSX) AND DEFINED(CPUARM64)}
    {
      macOS for M1 has a bug (Apple Feedback FB8994773) in which mprotect
      rejects a permission change from NONE -> RWX.
      Solution: give RW permission, make memory changes, then change RW to X
    }
    //X permission to the entire page for executions...
    if mprotect(CodeMemPages, PageSize, PROT_EXEC) <> 0 then
      raise EMProtectError.CreateFmt('MProtect error: %s', [
        SysErrorMessage({$IFDEF FPC}GetLastOSError{$ELSE}GetLastError{$ENDIF}())]);
  {$IFEND}

  Result := Pointer(Q); //set arm mode
end;
{$ENDIF CPUARM64}      

Maybe that will help to someone.

Best regards
Bojan

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions