syscall(2) - wariua/manpages-ko GitHub Wiki

NAME

syscall - 간접적 μ‹œμŠ€ν…œ 호좜

SYNOPSIS

#define _GNU_SOURCE         /* feature_test_macros(7) μ°Έκ³  */
#include <unistd.h>
#include <sys/syscall.h>    /* SYS_xxx μ •μ˜ */

long syscall(long number, ...);

DESCRIPTION

syscall()은 μž‘μ€ 라이브러리 ν•¨μˆ˜μ΄λ©°, μ§€μ •ν•œ 번호 number와 μ§€μ •ν•œ μΈμžλ“€μ„ κ°€μ§„ μ–΄μ…ˆλΈ”λ¦¬ μ–Έμ–΄ μΈν„°νŽ˜μ΄μŠ€μ˜ μ‹œμŠ€ν…œ ν˜ΈμΆœμ„ λΆ€λ₯Έλ‹€. 예λ₯Ό λ“€μ–΄ C λΌμ΄λΈŒλŸ¬λ¦¬μ— 래퍼 ν•¨μˆ˜κ°€ μ—†λŠ” μ‹œμŠ€ν…œ ν˜ΈμΆœμ„ λΆ€λ₯Ό λ•Œ syscall()이 μœ μš©ν•˜λ‹€.

syscall()은 μ‹œμŠ€ν…œ ν˜ΈμΆœμ„ ν•˜κΈ° 전에 CPU λ ˆμ§€μŠ€ν„°λ“€μ„ μ €μž₯ν•΄ 두고, μ‹œμŠ€ν…œ 호좜 λ°˜ν™˜ ν›„ κ·Έ λ ˆμ§€μŠ€ν„°λ“€μ„ λ³΅μ›ν•˜λ©°, 였λ₯˜ λ°œμƒ μ‹œ μ‹œμŠ€ν…œ 호좜이 λ°˜ν™˜ν•œ 였λ₯˜ μ½”λ“œλ₯Ό errno(3)에 μ €μž₯ν•œλ‹€.

μ‹œμŠ€ν…œ 호좜 번호 μƒμˆ˜λ“€μ„ 헀더 파일 <sys/syscall.h>μ—μ„œ 찾을 수 μžˆλ‹€.

RETURN VALUE

λΆ€λ₯΄λ €κ³  ν•˜λŠ” μ‹œμŠ€ν…œ 호좜이 λ°˜ν™˜ 값을 κ·œμ •ν•œλ‹€. 일반적으둜 λ°˜ν™˜ κ°’ 0은 성곡을 λ‚˜νƒ€λ‚Έλ‹€. λ°˜ν™˜ κ°’ -1은 였λ₯˜λ₯Ό λ‚˜νƒ€λ‚΄λ©° errno에 였λ₯˜ μ½”λ“œκ°€ μ €μž₯λœλ‹€.

NOTES

4BSDμ—μ„œ syscall()이 처음 λ“±μž₯ν–ˆλ‹€.

μ•„ν‚€ν…μ²˜λ³„ μš”κ΅¬ 사항

각각의 μ•„ν‚€ν…μ²˜ ABIλ§ˆλ‹€ μ‹œμŠ€ν…œ ν˜ΈμΆœμ„ μ–΄λ–»κ²Œ μ»€λ„λ‘œ μ „λ‹¬ν•˜λŠ”μ§€μ— λŒ€ν•œ λ‚˜λ¦„μ˜ μš”κ΅¬ 사항이 μžˆλ‹€. glibc λž˜νΌκ°€ μžˆλŠ” μ‹œμŠ€ν…œ 호좜(즉, λŒ€λΆ€λΆ„μ˜ μ‹œμŠ€ν…œ 호좜)μ—μ„œλŠ” μ•„ν‚€ν…μ²˜μ— λ§žλŠ” λ°©μ‹μœΌλ‘œ 인자λ₯Ό λ ˆμ§€μŠ€ν„°λ‘œ λ³΅μ‚¬ν•˜λŠ” μ„ΈλΆ€ 사항듀을 glibcκ°€ 닀뀄 μ€€λ‹€. ν•˜μ§€λ§Œ syscall()을 μ΄μš©ν•΄ μ‹œμŠ€ν…œ ν˜ΈμΆœμ„ ν•  λ•ŒλŠ” ν˜ΈμΆœμžκ°€ μ•„ν‚€ν…μ²˜λ³„ μ„ΈλΆ€ 사항듀을 닀뀄야 ν•  μˆ˜λ„ μžˆλ‹€. νŠΉμ • 32λΉ„νŠΈ μ•„ν‚€ν…μ²˜λ“€μ—μ„œ 이런 μš”κ΅¬ 사항을 κ°€μž₯ ν”νžˆ λ§Œλ‚˜κ²Œ λœλ‹€.

예λ₯Ό λ“€μ–΄ ARM μ•„ν‚€ν…μ²˜ μž„λ² λ””λ“œ ABI(EABI)μ—μ„œλŠ” 64λΉ„νŠΈ κ°’(κ°€λ Ή long long)을 짝수 번 λ ˆμ§€μŠ€ν„° μŒμ— μ •λ ¬μ‹œμΌœμ•Ό ν•œλ‹€. κ·Έλž˜μ„œ 리틀 μ—”λ””μ–Έ λͺ¨λ“œ EABI ARM μ•„ν‚€ν…μ²˜μ—μ„œ glibcκ°€ μ œκ³΅ν•˜λŠ” 래퍼 λŒ€μ‹  syscall()을 μ‚¬μš©ν•œλ‹€λ©΄ readahead() μ‹œμŠ€ν…œ ν˜ΈμΆœμ„ λ‹€μŒκ³Ό 같이 λΆ€λ₯΄κ²Œ 될 것이닀.

syscall(SYS_readahead, fd, 0,
        (unsigned int) (offset & 0xFFFFFFFF),
        (unsigned int) (offset >> 32),
        count);

offset μΈμžκ°€ 64λΉ„νŠΈμ΄κ³  첫 번째 인자(fd)λ₯Ό r0둜 μ „λ‹¬ν•˜λ―€λ‘œ ν˜ΈμΆœμžκ°€ 64λΉ„νŠΈ 값을 직접 μͺΌκ°œκ³  μ •λ ¬ν•΄μ„œ r2/r3 λ ˆμ§€μŠ€ν„° 쌍으둜 μ „λ‹¬λ˜κ²Œ ν•΄μ•Ό ν•œλ‹€. 즉 r1에 더미 값을 λ„£λŠ”λ‹€ (두 번째 인자 0). μͺΌκ°œκΈ°κ°€ (ν”Œλž«νΌμ— λŒ€ν•œ C ABI에 λ”°λ₯Έ) μ—”λ””μ–Έ κ·œμ•½μ„ λ”°λ₯΄λ„둝 ν•˜λŠ” 데에도 주의λ₯Ό κΈ°μšΈμ—¬μ•Ό ν•œλ‹€.

O32 ABI의 MIPS, 32λΉ„νŠΈ ABI의 PowerPC 및 parisc, 그리고 Xtensaμ—μ„œλ„ λΉ„μŠ·ν•œ λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆλ‹€.

참고둜 parisc C ABIμ—μ„œλ„ μ •λ ¬λœ λ ˆμ§€μŠ€ν„° μŒμ„ μ‚¬μš©ν•˜μ§€λ§Œ 쀑간 계측을 μ΄μš©ν•΄ μ‚¬μš©μž κ³΅κ°„μ—κ²Œ 문제λ₯Ό 감좰 μ€€λ‹€.

영ν–₯ λ°›λŠ” μ‹œμŠ€ν…œ ν˜ΈμΆœμ€ fadvise64_64(2), ftruncate64(2), posix_fadvise(2), pread64(2), pwrite64(2), readahead(2), sync_file_range(2), truncate64(2)이닀.

_llseek(2), preadv(2), preadv2(2), pwritev(2), pwritev2(2)처럼 직접 64λΉ„νŠΈ 값을 μͺΌκ°œκ³  ν•©μΉ˜λŠ” μ‹œμŠ€ν…œ ν˜ΈμΆœλ“€μ€ 영ν–₯을 λ°›μ§€ μ•ŠλŠ”λ‹€. 역사적 μž”μž¬λ“€μ˜ λ©‹μ§„ 세계에 온 것을 ν™˜μ˜ν•œλ‹€.

μ•„ν‚€ν…μ²˜ 호좜 κ·œμ•½

μ•„ν‚€ν…μ²˜λ§ˆλ‹€ 컀널을 ν˜ΈμΆœν•˜κ³  인자λ₯Ό μ „λ‹¬ν•˜λŠ” λ‚˜λ¦„μ˜ 방식이 μžˆλ‹€. μ—¬λŸ¬ μ•„ν‚€ν…μ²˜μ˜ μ„ΈλΆ€ 사항듀이 μ•„λž˜ 두 ν‘œμ— λ‚˜μ—΄λ˜μ–΄ μžˆλ‹€.

첫 번째 ν‘œλŠ” μ»€λ„λ‘œ μ „ν™˜ν•˜λŠ” 데 μ“°λŠ” μΈμŠ€νŠΈλŸ­μ…˜ (μ»€λ„λ‘œ μ „ν™˜ν•˜λŠ” μ΅œλ‹¨ λ‚΄μ§€ μ΅œμ„ μ˜ 방법이 아닐 μˆ˜λ„ 있으며, κ·Έλž˜μ„œ vdso(7)λ₯Ό μ°Έκ³ ν•΄μ•Ό ν•  μˆ˜λ„ 있음), μ‹œμŠ€ν…œ 호좜 번호λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 데 μ“°λŠ” λ ˆμ§€μŠ€ν„°, 컀널 호좜 κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜λŠ” 데 μ“°λŠ” λ ˆμ§€μŠ€ν„°(λ“€), 였λ₯˜λ₯Ό μ•Œλ¦¬λŠ” 데 μ“°λŠ” λ ˆμ§€μŠ€ν„°λ₯Ό 보여 μ€€λ‹€.

μ•„ν‚€ν…μ²˜/ABI μΈμŠ€νŠΈλŸ­μ…˜ μ‹œμŠ€ν…œ
호좜 #
λ°˜ν™˜
κ°’
λ°˜ν™˜
κ°’ 2
였λ₯˜ μ°Έκ³ 
alpha callsys v0 v0 a4 a3 1, 6
arc trap0 r8 r0 - -
arm/OABI swi NR - a1 - - 2
arm/EABI swi 0x0 r7 r0 r1 -
arm64 svc #0 x8 x0 x1 -
blackfin excpt 0x0 P0 R0 - -
i386 int $0x80 eax eax edx -
ia64 break 0x100000 r15 r8 r9 r10 1, 6
m68k trap #0 d0 d0 - -
microblaze brki r14,8 r12 r3 - -
mips syscall v0 v0 v1 a3 1, 6
nios2 trap r2 r2 - r7
parisc ble 0x100(%sr2, %r0) r20 r28 - -
powerpc sc r0 r3 - r0 1
riscv scall a7 a0 a1 -
s390 svc 0 r1 r2 r3 - 3
s390x svc 0 r1 r2 r3 - 3
superh trap #0x17 r3 r0 r1 - 4, 6
sparc/32 t 0x10 g1 o0 o1 psr/csr 1, 6
sparc/64 t 0x6d g1 o0 o1 psr/csr 1, 6
tile swint1 R10 R00 - R01 1
x86-64 syscall rax rax rdx - 5
x32 syscall rax rax rdx - 5
xtensa syscall a2 a2 - -

μ°Έκ³ :

[1] λͺ‡λͺ‡ μ•„ν‚€ν…μ²˜μ—μ„œλŠ” λ ˆμ§€μŠ€ν„° ν•˜λ‚˜λ₯Ό λΆˆλ¦¬μ–ΈμœΌλ‘œ μ‚¬μš©ν•΄ (0은 였λ₯˜ μ—†μŒ, -1은 였λ₯˜ λ‚˜νƒ€λƒ„) μ‹œμŠ€ν…œ 호좜이 μ‹€νŒ¨ν–ˆλŠ”μ§€ μ•Œλ¦°λ‹€. μ‹€μ œ 였λ₯˜ 값은 λ§ˆμ°¬κ°€μ§€λ‘œ λ°˜ν™˜ λ ˆμ§€μŠ€ν„°μ— λ‹΄λŠ”λ‹€. sparcμ—μ„œλŠ” λ ˆμ§€μŠ€ν„° 전체 λŒ€μ‹  ν”„λ‘œμ„Έμ„œ μƒνƒœ λ ˆμ§€μŠ€ν„°(psr)의 캐리 λΉ„νŠΈ(csr)λ₯Ό μ‚¬μš©ν•œλ‹€.

[2] NR이 μ‹œμŠ€ν…œ 호좜 λ²ˆν˜Έμ΄λ‹€.

[3] s390κ³Ό s390xμ—μ„œλŠ” NR(μ‹œμŠ€ν…œ 호좜 번호)κ°€ 256보닀 μž‘μœΌλ©΄ svc NR둜 직접 전달할 μˆ˜λ„ μžˆλ‹€.

[4] SuperHμ—μ„œλŠ” 트랩 λ²ˆν˜Έκ°€ 전달 인자의 μ΅œλŒ€ 개수λ₯Ό κ·œμ •ν•œλ‹€. trap #0x10은 인자 0개인 μ‹œμŠ€ν…œ 호좜과 μ‚¬μš©ν•  수 있고, trap #0x11은 μΈμžκ°€ 0κ°œλ‚˜ 1개인 μ‹œμŠ€ν…œ 호좜과 μ‚¬μš©ν•  수 있고, 그런 μ‹μœΌλ‘œ ν•΄μ„œ trap #0x17은 인자 7개인 μ‹œμŠ€ν…œ ν˜ΈμΆœμ„ μœ„ν•œ 것이닀.

[5] x32 ABIλŠ” x86-64 ABI와 μ‹œμŠ€ν…œ 호좜 ν…Œμ΄λΈ”μ„ κ³΅μœ ν•˜λ˜ λͺ‡ κ°€μ§€ λ―Έλ¬˜ν•œ 차이가 μžˆλ‹€.

  • x32 ABI ν•˜μ—μ„œ μ‹œμŠ€ν…œ 호좜이 μ΄λ€„μ§€λŠ” κ±Έ λ‚˜νƒ€λ‚΄κΈ° μœ„ν•΄μ„œ μ‹œμŠ€ν…œ 호좜 λ²ˆν˜Έμ— μΆ”κ°€λ‘œ __X32_SYSCALL_BIT λΉ„νŠΈλ₯Ό OR ν•œλ‹€. ν”„λ‘œμ„ΈμŠ€μ—μ„œ μ‚¬μš©ν•˜λŠ” ABIκ°€ μ‹œκ·Έλ„ μ²˜λ¦¬λ‚˜ μ‹œμŠ€ν…œ 호좜 μž¬μ‹œμž‘μ„ ν¬ν•¨ν•œ 일뢀 ν”„λ‘œμ„ΈμŠ€ λ™μž‘ 방식에 영ν–₯을 μ€€λ‹€.

  • x32μ—μ„œ long 및 포인터 νƒ€μž…μ˜ 크기가 λ‹€λ₯΄κΈ° λ•Œλ¬Έμ— 일뢀 ꡬ쑰체의 (μ „λΆ€λŠ” μ•„λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ struct timevalμ΄λ‚˜ struct rlimit은 64λΉ„νŠΈλ₯Ό μ“΄λ‹€.) λ°°μΉ˜κ°€ λ‹€λ₯΄λ‹€. 이λ₯Ό 닀루기 μœ„ν•΄ μ‹œμŠ€ν…œ 호좜 ν…Œμ΄λΈ”μ— λ²ˆν˜Έκ°€ (__X32_SYSCALL_BITλŠ” μ œμ™Έν•˜κ³ ) 512λΆ€ν„° μ‹œμž‘ν•˜λŠ” μ‹œμŠ€ν…œ ν˜ΈμΆœλ“€μ΄ 좔가돼 μžˆλ‹€. 예λ₯Ό λ“€μ–΄ __NR_readvκ°€ x86-64 ABIμ—λŠ” 19둜 μ •μ˜λΌ 있고 x32 ABIμ—λŠ” __X32_SYSCALL_BIT | 515둜 μ •μ˜λΌ μžˆλ‹€. 이런 μΆ”κ°€ μ‹œμŠ€ν…œ 호좜 λŒ€λΆ€λΆ„μ€ 사싀 i386 ν˜Έν™˜μ„± μ œκ³΅μ„ μœ„ν•œ μ‹œμŠ€ν…œ ν˜ΈμΆœλ“€κ³Ό λ™μΌν•˜λ‹€. ν•˜μ§€λ§Œ preadv2(2)처럼 λˆˆμ— λ„λŠ” μ˜ˆμ™Έλ„ μžˆλŠ”λ°, 4λ°”μ΄νŠΈ 포인터 및 크기λ₯Ό μ“°λŠ” struct iovec ν•­λͺ©(컀널 μš©μ–΄λ‘œλŠ” "compat_iovec")을 μ‚¬μš©ν•˜λ©΄μ„œλ„ 여타 ABIμ—μ„œμ²˜λŸΌ 8λ°”μ΄νŠΈ pos 인자λ₯Ό λ‘˜μ΄ μ•„λ‹Œ ν•œ λ ˆμ§€μŠ€ν„°λ‘œ μ „λ‹¬ν•œλ‹€.

[6] 일뢀 μ•„ν‚€ν…μ²˜(Alpha, IA-64, MIPS, SuperH, sparc/32, sparc/64)μ—μ„œλŠ” μΆ”κ°€ λ ˆμ§€μŠ€ν„°(μœ„ ν‘œμ˜ "λ°˜ν™˜ κ°’ 2")λ₯Ό μ‚¬μš©ν•΄μ„œ pipe(2) μ‹œμŠ€ν…œ 호좜의 두 번째 λ°˜ν™˜ 값을 되돌렀 μ€€λ‹€. Alpha에선 μ•„ν‚€ν…μ²˜ ν•œμ • μ‹œμŠ€ν…œ 호좜인 getxpid(2), getxuid(2), getxgid(2)μ—μ„œλ„ 이 기법을 μ“΄λ‹€. λ‹€λ₯Έ μ•„ν‚€ν…μ²˜λ“€μ—μ„  System V ABI에 μ •μ˜λΌ μžˆλŠ” κ²½μš°μ‘°μ°¨λ„ μ‹œμŠ€ν…œ 호좜 μΈν„°νŽ˜μ΄μŠ€μ—μ„œ 두 번째 λ°˜ν™˜ κ°’ λ ˆμ§€μŠ€ν„°λ₯Ό μ“°μ§€ μ•ŠλŠ”λ‹€.

두 번째 ν‘œλŠ” μ‹œμŠ€ν…œ 호좜 μΈμžλ“€μ„ μ „λ‹¬ν•˜λŠ” 데 μ“°λŠ” λ ˆμ§€μŠ€ν„°λ“€μ„ 보여 μ€€λ‹€.

μ•„ν‚€ν…μ²˜/ABI arg1 arg2 arg3 arg4 arg5 arg6 arg7 μ°Έκ³ 
alpha a0 a1 a2 a3 a4 a5 -
arc r0 r1 r2 r3 r4 r5 -
arm/OABI a1 a2 a3 a4 v1 v2 v3
arm/EABI r0 r1 r2 r3 r4 r5 r6
arm64 x0 x1 x2 x3 x4 x5 -
blackfin R0 R1 R2 R3 R4 R5 -
i386 ebx ecx edx esi edi ebp -
ia64 out0 out1 out2 out3 out4 out5 -
m68k d1 d2 d3 d4 d5 a0 -
microblaze r5 r6 r7 r8 r9 r10 -
mips/o32 a0 a1 a2 a3 - - - 1
mips/n32,64 a0 a1 a2 a3 a4 a5 -
nios2 r4 r5 r6 r7 r8 r9 -
parisc r26 r25 r24 r23 r22 r21 -
powerpc r3 r4 r5 r6 r7 r8 r9
riscv a0 a1 a2 a3 a4 a5 -
s390 r2 r3 r4 r5 r6 r7 -
s390x r2 r3 r4 r5 r6 r7 -
superh r4 r5 r6 r7 r0 r1 r2
sparc/32 o0 o1 o2 o3 o4 o5 -
sparc/64 o0 o1 o2 o3 o4 o5 -
tile R00 R01 R02 R03 R04 R05 -
x86-64 rdi rsi rdx r10 r8 r9 -
x32 rdi rsi rdx r10 r8 r9 -
xtensa a6 a3 a4 a5 a8 a9 -

μ°Έκ³ :

[1] mips/o32 μ‹œμŠ€ν…œ 호좜 κ·œμ•½μ—μ„œλŠ” 5λ²ˆμ—μ„œ 8λ²ˆκΉŒμ§€ μΈμžλ“€μ„ μ‚¬μš©μž μŠ€νƒμœΌλ‘œ μ „λ‹¬ν•œλ‹€.

참고둜 이 ν‘œλ“€μ΄ 호좜 κ·œμ•½ 전체λ₯Ό ν¬κ΄„ν•˜λŠ” 것은 μ•„λ‹ˆλ‹€. 일뢀 μ•„ν‚€ν…μ²˜μ—μ„œ μ—¬κΈ° λ‚˜μ—΄ μ•ˆ 된 λ‹€λ₯Έ λ ˆμ§€μŠ€ν„°λ“€μ„ 마ꡬ κ±΄λ“œλ¦΄ μˆ˜λ„ μžˆλ‹€.

EXAMPLE

#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <signal.h>

int
main(int argc, char *argv[])
{
    pid_t tid;

    tid = syscall(SYS_gettid);
    syscall(SYS_tgkill, getpid(), tid, SIGHUP);
}

SEE ALSO

_syscall(2), intro(2), syscalls(2), errno(3), vdso(7)


2018-04-30

⚠️ **GitHub.com Fallback** ⚠️