역할과 입력
- r7: 32비트 EABI 시스템 호출 번호
- 복구 대상 레지스터와 마스크는 사용자 시그널 프레임에 있습니다.
원본 .S · 빌드 조건: Makefile · 명령·주소 표기 읽는 법
47줄 · SHA-256: bad45c2718dede1d6ad4635eac39bcce0488fa384e9b1a76b1147dae388ae771
구조와 흐름
EABI 번호와 코드 범위
unistd_compat_32.h는 빌드 과정에서 생성되는 호환 시스템 호출 번호 헤더입니다. .globl은 코드 범위의 시작·끝을 외부 C 코드가 참조할 수 있게 합니다.
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * AArch32 sigreturn code.
4 * Based on the kuser helpers in arch/arm/kernel/entry-armv.S.
5 *
6 * Copyright (C) 2005-2011 Nicolas Pitre <nico@fluxnic.net>
7 * Copyright (C) 2012-2018 ARM Ltd.
8 *
9 * For ARM syscalls, the syscall number has to be loaded into r7.
10 * We do not support an OABI userspace.
11 *
12 * For Thumb syscalls, we also pass the syscall number via r7. We therefore
13 * need two 16-bit instructions.
14 */
15
16#include <asm/unistd_compat_32.h>
17
18 .section .rodata
19 .globl __aarch32_sigret_code_start
20__aarch32_sigret_code_start:
- L16
- AArch32 호환 시스템 호출 번호를 가져옵니다. 뒤의 sigreturn·rt_sigreturn 기계어는 AArch64 x8 ABI가 아니라 AArch32 r7 번호를 사용하므로 호환 번호 정의가 필요합니다. #include는 전처리 단계에서 헤더 내용을 가져옵니다. CPU가 이 줄에서 함수를 호출하는 동작은 없습니다.
- L18
- .rodata — 지정된 섹션에 이후 코드/데이터를 출력합니다.
- L19
- AArch32 시그널 복귀 명령 모음의 시작 기호를 다른 커널 코드가 찾을 수 있게 내보냅니다. 여기 있는 바이트를 사용자 복귀 트램펄린에 배치할 때 시작과 끝 기호로 범위를 계산합니다. 이 표기는 심벌을 다른 오브젝트에서도 참조할 수 있게 하며 CPU가 실행하는 명령을 추가하지 않습니다.
- L20
- __aarch32_sigret_code_start 라벨: 다음 코드나 데이터의 위치에 이름을 붙입니다.
sigreturn의 ARM·Thumb 바이트
ARM 형식은 4바이트 MOV r7,#번호와 4바이트 SVC입니다. Thumb 형식에서 0x27xx는 MOVS r7,#imm8, 0xdfxx는 SVC #imm8입니다. 따라서 31·32행 원문 주석의 svc/mov 표시는 실제 바이트 순서와 반대입니다. 코드 바이트를 기준으로 읽어야 합니다.
21
22 /*
23 * ARM Code
24 */
25 .byte __NR_compat32_sigreturn, 0x70, 0xa0, 0xe3 // mov r7, #__NR_compat32_sigreturn
26 .byte __NR_compat32_sigreturn, 0x00, 0x00, 0xef // svc #__NR_compat32_sigreturn
27
28 /*
29 * Thumb code
30 */
31 .byte __NR_compat32_sigreturn, 0x27 // svc #__NR_compat32_sigreturn
32 .byte __NR_compat32_sigreturn, 0xdf // mov r7, #__NR_compat32_sigreturn
33
- L25
- 이 .byte 자체는 CPU 명령이 아니라, 어셈블 단계에서 각 값을 1바이트씩 내보내는 지시문입니다. 이 파일에서는 그 바이트열이 명령어 인코딩이며, 시그널 복귀 시 CPU가 이를 AArch32 명령으로 실행합니다. 리틀 엔디언 ARM 명령 MOV r7,#sigreturn을 바이트로 만듭니다. r7은 AArch32 EABI 시스템 호출 번호 레지스터이며, 뒤의 SVC가 사용자 시그널 프레임에 보관한 문맥을 커널에서 검사·복원하도록 요청하게 합니다.
- L26
- 이 .byte 자체는 CPU 명령이 아니라, 어셈블 단계에서 각 값을 1바이트씩 내보내는 지시문입니다. 이 파일에서는 그 바이트열이 명령어 인코딩이며, 시그널 복귀 시 CPU가 이를 AArch32 명령으로 실행합니다. ARM 상태의 SVC를 바이트로 만듭니다. 직전 r7의 sigreturn 번호와 함께 커널에 들어가 시그널 이전 상태를 복원합니다. 일반 함수의 LR로 단순 RET하는 동작과 다릅니다.
- L31
- 이 .byte 자체는 CPU 명령이 아니라, 어셈블 단계에서 각 값을 1바이트씩 내보내는 지시문입니다. 이 파일에서는 그 바이트열이 명령어 인코딩이며, 시그널 복귀 시 CPU가 이를 AArch32 명령으로 실행합니다. 0x27xx는 Thumb MOVS r7,#imm 인코딩이므로 sigreturn 번호를 r7에 넣습니다. 이 줄의 원문 주석 SVC는 다음 줄과 뒤바뀌어 있어 실제 바이트를 기준으로 해석해야 합니다.
- L32
- 이 .byte 자체는 CPU 명령이 아니라, 어셈블 단계에서 각 값을 1바이트씩 내보내는 지시문입니다. 이 파일에서는 그 바이트열이 명령어 인코딩이며, 시그널 복귀 시 CPU가 이를 AArch32 명령으로 실행합니다. 0xdfxx는 Thumb SVC 인코딩입니다. 앞에서 설정한 r7의 sigreturn 번호로 커널 복귀 서비스를 요청합니다. 원문에 MOV라고 적혀 있어도 실제 명령은 SVC입니다.
rt_sigreturn과 범위 끝
같은 구조에 rt_sigreturn 번호를 사용합니다. 43·44행 Thumb 주석도 동일하게 뒤바뀌어 있습니다. 이 파일은 레지스터를 직접 복원하지 않고 시스템 호출을 요청합니다. 실제 복원은 커널의 시그널 처리 코드에서 수행합니다.
34 /*
35 * ARM code
36 */
37 .byte __NR_compat32_rt_sigreturn, 0x70, 0xa0, 0xe3 // mov r7, #__NR_compat32_rt_sigreturn
38 .byte __NR_compat32_rt_sigreturn, 0x00, 0x00, 0xef // svc #__NR_compat32_rt_sigreturn
39
40 /*
41 * Thumb code
42 */
43 .byte __NR_compat32_rt_sigreturn, 0x27 // svc #__NR_compat32_rt_sigreturn
44 .byte __NR_compat32_rt_sigreturn, 0xdf // mov r7, #__NR_compat32_rt_sigreturn
45
46 .globl __aarch32_sigret_code_end
47__aarch32_sigret_code_end:
- L37
- 이 .byte 자체는 CPU 명령이 아니라, 어셈블 단계에서 각 값을 1바이트씩 내보내는 지시문입니다. 이 파일에서는 그 바이트열이 명령어 인코딩이며, 시그널 복귀 시 CPU가 이를 AArch32 명령으로 실행합니다. ARM 상태의 MOV r7,#rt_sigreturn을 만듭니다. rt_sigreturn은 확장된 시그널 프레임·마스크를 포함한 복귀 ABI를 사용하며 일반 sigreturn과 별도 호출 번호입니다.
- L38
- 이 .byte 자체는 CPU 명령이 아니라, 어셈블 단계에서 각 값을 1바이트씩 내보내는 지시문입니다. 이 파일에서는 그 바이트열이 명령어 인코딩이며, 시그널 복귀 시 CPU가 이를 AArch32 명령으로 실행합니다. ARM SVC로 rt_sigreturn을 요청합니다. 커널이 사용자 프레임의 레지스터·시그널 상태를 검사하고 복원하는 경로로 들어갑니다.
- L43
- 이 .byte 자체는 CPU 명령이 아니라, 어셈블 단계에서 각 값을 1바이트씩 내보내는 지시문입니다. 이 파일에서는 그 바이트열이 명령어 인코딩이며, 시그널 복귀 시 CPU가 이를 AArch32 명령으로 실행합니다. Thumb MOVS r7,#rt_sigreturn의 바이트입니다. 0x27xx 인코딩과 호출 번호를 기준으로 해석하며 이 줄의 SVC 주석은 맞지 않습니다.
- L44
- 이 .byte 자체는 CPU 명령이 아니라, 어셈블 단계에서 각 값을 1바이트씩 내보내는 지시문입니다. 이 파일에서는 그 바이트열이 명령어 인코딩이며, 시그널 복귀 시 CPU가 이를 AArch32 명령으로 실행합니다. Thumb SVC의 0xdfxx 인코딩입니다. rt_sigreturn 복귀 서비스를 요청하고, 원래 응용 프로그램의 PC·SP 등은 커널 복원 경로에서 결정됩니다.
- L46
- __aarch32_sigret_code_end — 심볼을 다른 오브젝트에서도 참조할 수 있게 합니다.
- L47
- __aarch32_sigret_code_end 라벨: 다음 코드나 데이터의 위치에 이름을 붙입니다.
매크로 정의와 확장
각 정의는 v6.18.37 원문입니다. 역슬래시 인자는 사용 위치의 값으로 치환되며, 안쪽 매크로와 조건부 블록은 이후 단계에서 다시 처리됩니다.
상수·구조체 오프셋
S_*·THREAD_*·FREGS_* 등의 구조체 오프셋은 빌드한 C 구조체 배치에서 생성됩니다. 숫자를 고정하지 않고 원래 기호를 사용했습니다.