assemblyarmapple-m1armv8

How can I handle SIGINT in Apple M1 assembly code?


I am trying to learn assembly for the Apple M1. I want to write a program that goes into an infinite loop and then exits with status 123 when control-c is pressed. I have written the following program:

// foo.s
.align 2
.text
.global _main

_main:
  mov x0, #2
  adrp x1, sigint_handler@page
  add x1, x1, sigint_handler@pageoff
  mov x2, #0
  mov x8, 0x8c
  svc 0

loop:
  b loop

sigint_handler:
  mov x0, #123
  mov x16, #1
  svc 0

It can be assembled with:

as foo.s -arch arm64 -o foo.o
ld -arch arm64 -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -lSystem -o foo foo.o

And run with:

./foo

When I press control-c, the program exits with status 130:

echo $?
130

I was expecting a status code of 123 because of the sigint_handler.

I don't think I'm registering the sigint_handler correctly. What am I doing wrong?

Thanks

Edit:

After more trying based on Nate's comments, I now have this code:

.align 2

.data
nsa: .skip 24

.text
.global _main

_main:
  // Populate the __sigaction nsa struct:
  // https://opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/sys/signal.h.auto.html

  adrp x0, nsa@page
  add x0, x0, nsa@pageoff

  adrp x1, sigint_handler@page
  add x1, x1, sigint_handler@pageoff
  str x1, [x0, #0]

  // I'm not sure what to do here:
  mov x1, #0
  str x1, [x0, #8]
  str x1, [x0, #16]

  // Make service call 46:
  // int sigaction(int signum, struct __sigaction *nsa, struct sigaction *osa);
  // https://opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master

  mov x0, #2 // SIGINT
  adrp x1, nsa@page
  add x1, x1, nsa@pageoff
  mov x2, #0 // NULL
  mov x16, #46
  svc 0

loop:
  b loop

sigint_handler:
  mov x0, #123
  mov x16, #1
  svc 0

I'm trying to build a __sigaction *nsa struct so that I can make a valid sigaction service call. This isn't working and I get a segmentation fault when I control-c. I'm not really sure of the sizeof this struct and how to populate its fields correctly.


Solution

  • I got it to work using this relatively simple code:

    .align 2
    .text
    .global _main
    
    _main:
      mov x0, #2
      adrp x1, sigint_handler@page
      add x1, x1, sigint_handler@pageoff
      bl _signal
    
    loop:
      b loop
    
    sigint_handler:
      mov x0, #123
      mov x16, #1
      svc 0
    

    I achieved this by starting with a simple C program:

    // foo.c
    #include <signal.h>
    
    void handler(int signal) {}
    
    void main(void) {
      signal(SIGINT, handler);
    }
    

    Then I used gcc to output assembly:

    gcc -S -o foo.s foo.c
    

    Which produced the following:

        .section    __TEXT,__text,regular,pure_instructions
        .build_version macos, 13, 0 sdk_version 13, 3
        .globl  _handler                        ; -- Begin function handler
        .p2align    2
    _handler:                               ; @handler
        .cfi_startproc
    ; %bb.0:
        sub sp, sp, #16
        .cfi_def_cfa_offset 16
        str w0, [sp, #12]
        add sp, sp, #16
        ret
        .cfi_endproc
                                            ; -- End function
        .globl  _main                           ; -- Begin function main
        .p2align    2
    _main:                                  ; @main
        .cfi_startproc
    ; %bb.0:
        stp x29, x30, [sp, #-16]!           ; 16-byte Folded Spill
        .cfi_def_cfa_offset 16
        mov x29, sp
        .cfi_def_cfa w29, 16
        .cfi_offset w30, -8
        .cfi_offset w29, -16
        mov w0, #2
        adrp    x1, _handler@PAGE
        add x1, x1, _handler@PAGEOFF
        bl  _signal
        ldp x29, x30, [sp], #16             ; 16-byte Folded Reload
        ret
        .cfi_endproc
                                            ; -- End function
    .subsections_via_symbols
    

    I then picked out the lines that register the signal handler. I'm not sure where _signal comes from - I presume it's built into the macOS assembler. If anyone can explain that part, I would greatly appreciate it. Thanks