حبيب محمد الأمين محمد الهـاد <ha.ala...@gmail.com> writes:

> I reproduced your same error, and figured out the cause. I'll just embed
> it as a diff inline, you'll spot it in the script instantly :).

AFAICT we are out of the cross-compilation woods and straight into the
OpenBSD mitigations paradise :) I pushed a tiny patch which takes care
of -fPIC at which point cross-compiling works:

% _build/stage1/bin/aarch64-unknown-openbsd-ghc -o a /tmp/a.hs

It produces a somewhat working binary:

% file a
a: ELF 64-bit LSB shared object, AArch64, version 1
% ./a
Hello World
[1]    13634 trace trap (core dumped)  ./a
(gdb) r
Starting program: /home/greg/a
Hello World

Program received signal SIGTRAP, Trace/breakpoint trap.
0x0000001f6f167a1c in StgRun ()
(gdb) bt
#0  0x0000001f6f167a1c in StgRun ()
#1  0x000000702fc5caf0 [PAC] in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) disassemble
Dump of assembler code for function StgRun:
   0x0000001f6f167950 <+0>:     bti     c
   0x0000001f6f167954 <+4>:     adrp    x15, 0x1f6f1bf000
   0x0000001f6f167958 <+8>:     ldr     x15, [x15, #2952]
   0x0000001f6f16795c <+12>:    eor     x15, x15, x30
   0x0000001f6f167960 <+16>:    paciasp
   0x0000001f6f167964 <+20>:    str     x30, [sp, #-96]!
   0x0000001f6f167968 <+24>:    stp     x28, x27, [sp, #16]
   0x0000001f6f16796c <+28>:    stp     x26, x25, [sp, #32]
   0x0000001f6f167970 <+32>:    stp     x24, x23, [sp, #48]
   0x0000001f6f167974 <+36>:    stp     x22, x21, [sp, #64]
   0x0000001f6f167978 <+40>:    stp     x20, x19, [sp, #80]
   0x0000001f6f16797c <+44>:    stp     x29, x30, [sp, #-16]!
   0x0000001f6f167980 <+48>:    mov     x29, sp
   0x0000001f6f167984 <+52>:    stp     x16, x17, [sp, #-16]!
   0x0000001f6f167988 <+56>:    stp     x19, x20, [sp, #-16]!
   0x0000001f6f16798c <+60>:    stp     x21, x22, [sp, #-16]!
   0x0000001f6f167990 <+64>:    stp     x23, x24, [sp, #-16]!
   0x0000001f6f167994 <+68>:    stp     x25, x26, [sp, #-16]!
   0x0000001f6f167998 <+72>:    stp     x27, x28, [sp, #-16]!
   0x0000001f6f16799c <+76>:    stp     d8, d9, [sp, #-16]!
   0x0000001f6f1679a0 <+80>:    stp     d10, d11, [sp, #-16]!
   0x0000001f6f1679a4 <+84>:    stp     d12, d13, [sp, #-16]!
   0x0000001f6f1679a8 <+88>:    stp     d14, d15, [sp, #-16]!
   0x0000001f6f1679ac <+92>:    sub     sp, sp, #0x4, lsl #12
   0x0000001f6f1679b0 <+96>:    mov     x19, x1
   0x0000001f6f1679b4 <+100>:   br      x0
   0x0000001f6f1679b8 <+104>:   add     sp, sp, #0x4, lsl #12
   0x0000001f6f1679bc <+108>:   mov     x0, x22
   0x0000001f6f1679c0 <+112>:   ldp     d14, d15, [sp], #16
   0x0000001f6f1679c4 <+116>:   ldp     d12, d13, [sp], #16
   0x0000001f6f1679c8 <+120>:   ldp     d10, d11, [sp], #16
   0x0000001f6f1679cc <+124>:   ldp     d8, d9, [sp], #16
   0x0000001f6f1679d0 <+128>:   ldp     x27, x28, [sp], #16
   0x0000001f6f1679d4 <+132>:   ldp     x25, x26, [sp], #16
   0x0000001f6f1679d8 <+136>:   ldp     x23, x24, [sp], #16
   0x0000001f6f1679dc <+140>:   ldp     x21, x22, [sp], #16
   0x0000001f6f1679e0 <+144>:   ldp     x19, x20, [sp], #16
   0x0000001f6f1679e4 <+148>:   ldp     x16, x17, [sp], #16
   0x0000001f6f1679e8 <+152>:   ldp     x29, x30, [sp], #16
   0x0000001f6f1679ec <+156>:   ldp     x20, x19, [sp, #80]
   0x0000001f6f1679f0 <+160>:   ldp     x22, x21, [sp, #64]
   0x0000001f6f1679f4 <+164>:   ldp     x24, x23, [sp, #48]
   0x0000001f6f1679f8 <+168>:   ldp     x26, x25, [sp, #32]
   0x0000001f6f1679fc <+172>:   ldp     x28, x27, [sp, #16]
   0x0000001f6f167a00 <+176>:   ldr     x30, [sp], #96
   0x0000001f6f167a04 <+180>:   adrp    x9, 0x1f6f1bf000
   0x0000001f6f167a08 <+184>:   autiasp
   0x0000001f6f167a0c <+188>:   ldr     x9, [x9, #2952]
   0x0000001f6f167a10 <+192>:   eor     x15, x15, x30
   0x0000001f6f167a14 <+196>:   subs    x15, x15, x9
   0x0000001f6f167a18 <+200>:   cbz     x15, 0x1f6f167a20 <StgRun+208>
=> 0x0000001f6f167a1c <+204>:   brk     #0x1
   0x0000001f6f167a20 <+208>:   ret
End of assembler dump.

This code is very special (it is mostly coded in arm64 assembly[0]).  We
could really use help from somebody who understands what is happening in
our arm64 epilogue that this magical Haskell runtime is running afoul
of. It looks like retguard, so maybe just somehow marking this function
with no-retguard-please is enough?

My hypothesis for why the same works on amd64 is they have an explicit
retq, so we don't get to inject retguard in there. That function is like
this:
$ objdump -d 
/usr/local/lib/ghc-9.6.6/lib/x86_64-openbsd-ghc-9.6.6/rts-1.0.2/libHSrts-1.0.2.a
...
  4f:   4c 8b 64 24 10          mov    0x10(%rsp),%r12
  54:   4c 8b 6c 24 18          mov    0x18(%rsp),%r13
  59:   4c 8b 74 24 20          mov    0x20(%rsp),%r14
  5e:   4c 8b 7c 24 28          mov    0x28(%rsp),%r15
  63:   48 83 c4 30             add    $0x30,%rsp
  67:   c3                      retq
  68:   4c 33 1c 24             xor    (%rsp),%r11
  6c:   4c 3b 1d 00 00 00 00    cmp    0(%rip),%r11        # 73 <StgReturn+0x37>
  73:   74 0a                   je     7f <StgReturn+0x43>
  75:   cc                      int3
  76:   cc                      int3
  77:   cc                      int3
  78:   cc                      int3
  79:   cc                      int3
  7a:   cc                      int3
  7b:   cc                      int3
  7c:   cc                      int3
  7d:   cc                      int3
  7e:   cc                      int3
  7f:   c3                      retq

[0]https://gitlab.haskell.org/blackgnezdo/ghc/-/blob/ghc-9.10.1-openbsd/rts/StgCRun.c?ref_type=heads#L833

Thanks
Greg

Reply via email to