英文:
How can I handle SIGINT in Apple M1 assembly code?
问题
你的汇编代码看起来有一些问题。我会帮你指出问题并提供修复方案。
首先,你的__sigaction
结构似乎没有正确地初始化。下面是修复的代码:
.align 2
.data
nsa:
.quad 0 // sa_handler
.long 0 // sa_flags
.quad 0 // sa_restorer
.long 0 // sa_mask
.text
.global _main
_main:
// Populate the __sigaction nsa struct:
adrp x0, nsa@page
add x0, x0, nsa@pageoff
adrp x1, sigint_handler@page
add x1, x1, sigint_handler@pageoff
str x1, [x0, #0] // sa_handler
ldr x1, [x0, #4] // Load sa_flags field
orr x1, x1, #1 // Set SA_RESTART flag
str x1, [x0, #4] // Store it back
// Make service call 46:
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
这个修复添加了正确的初始化和设置了SA_RESTART
标志,这样你的信号处理程序就应该按预期工作了。希望这可以帮助你解决问题。如果你还有其他问题,可以继续提问。
英文:
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.
答案1
得分: 0
我用这个相对简单的代码使它工作了:
.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
我通过从一个简单的C程序开始来实现这个:
// foo.c
#include <signal.h>
void handler(int signal) {}
void main(void) {
signal(SIGINT, handler);
}
然后我使用gcc将其输出为汇编:
gcc -S -o foo.s foo.c
这将生成以下内容:
.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
然后我挑选出注册信号处理程序的那些行。我不确定_signal是从哪里来的 - 我假设它内置在macOS汇编程序中。如果有人能解释这一部分,我将不胜感激。谢谢。
英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论