Linux 시스템 호출 테이블은 어디에서 찾을 수 있나요?

Linux 시스템 호출 테이블은 어디에서 찾을 수 있나요?

많은 사람들이 온라인에서 참조하는 것을 봤습니다.

arch/x86/entry/syscalls/syscall_64.tbl

시스템 호출 테이블의 경우 훌륭하게 작동합니다. 그런데 그걸 참고하는 분들이 많더라구요

/include/uapi/asm-generic/unistd.h

이는 일반적으로 헤더 패키지에 있습니다. 어떻게 syscall_64.tbl표시하나요?

0 common  read      sys_read

정답을 맞추고 unistd.h표시하세요.

#define __NR_io_setup 0
__SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup)

__NR_read그러면 다음과 같이 표시됩니다 .

#define __NR_read 63
__SYSCALL(__NR_read, sys_read)

왜 1이 아니고 63인가요? 를 어떻게 이해해야 합니까 /include/uapi/asm-generic/unistd.h? /usr/include/asm/아직 있다

/usr/include/asm/unistd_x32.h
#define __NR_read (__X32_SYSCALL_BIT + 0)
#define __NR_write (__X32_SYSCALL_BIT + 1)
#define __NR_open (__X32_SYSCALL_BIT + 2)
#define __NR_close (__X32_SYSCALL_BIT + 3)
#define __NR_stat (__X32_SYSCALL_BIT + 4)

/usr/include/asm/unistd_64.h
#define __NR_read 0
#define __NR_write 1
#define __NR_open 2
#define __NR_close 3
#define __NR_stat 4

/usr/include/asm/unistd_32.h
#define __NR_restart_syscall 0
#define __NR_exit 1           
#define __NR_fork 2           
#define __NR_read 3           
#define __NR_write 4          

unistd누군가 이 파일들의 차이점을 말해 줄 수 있나요? 어떻게 unistd.h작동하는지 설명해주세요. 시스템 호출 테이블을 찾는 가장 좋은 방법은 무엇입니까?

답변1

이런 종류의 일을 조사할 때 컴파일러에게 직접 물어보는 것이 유용하다는 것을 알았습니다.터미널에서 표준 C/GCC 사전 정의 매크로 인쇄세부):

printf SYS_read | gcc -include sys/syscall.h -E -

이는 관련된 헤더(Debian의 경우)가 /usr/include/x86_64-linux-gnu/sys/syscall.h, /usr/include/x86_64-linux-gnu/asm/unistd.h, /usr/include/x86_64-linux-gnu/asm/unistd_64.h및 임을 보여주며 x86-64에서는 0인 /usr/include/x86_64-linux-gnu/bits/syscall.h시스템 호출 번호를 인쇄합니다 .read

크로스 컴파일러 환경에서 적절한 시스템 헤더를 설치하면 다른 아키텍처에 대한 시스템 호출 번호를 찾을 수 있습니다. 32비트 x86의 경우 이는 간단합니다.

printf SYS_read | gcc -include sys/syscall.h -m32 -E -

다른 헤더 파일을 포함 /usr/include/asm/unistd_32.h하고 숫자 3을 인쇄합니다.

따라서 사용자 공간 관점에서 볼 때 32비트 x86 시스템 호출은 에서 정의 asm/unistd_32.h되고 64비트 x86 시스템 호출은 에서 정의됩니다 asm/unistd_64.h. asm/unistd_x32.h사용x32 ABI.

uapi/asm-generic/unistd.h아키텍처별 시스템 호출 테이블이 없는 아키텍처에서 사용되는 기본 시스템 호출을 나열합니다.

커널에서 참조는 약간 다르며 아키텍처에 따라 다릅니다(공통 시스템 호출 테이블을 사용하지 않는 아키텍처의 경우). 이것이 바로 이와 같은 파일이 들어오는 곳입니다 (결국 arch/x86/entry/syscalls/syscall_64.tbl사용자 공간 등에서 unistd_64.h사용되는 헤더 파일을 생성합니다). 해당 주제에 대한 두 개의 LWN 기사에서 시스템 호출에 대한 자세한 내용을 확인할 수 있습니다.시스템 호출 분석 1부그리고시스템 호출 분석 2부.

답변2

서로 다른 아키텍처는 서로 다른 파일에서 서로 다른 시스템 호출 번호를 정의합니다.

시스템 호출 번호는 아키텍처마다 다릅니다. 예를 들면 다음과 같습니다.

include/uapi/asm-generic/unistd.harch/*정의

include/uapi/asm-generic/unistd.h모든 아키텍처의 시스템 호출 번호를 통합하려는 새로운 시도라고 생각합니다 .

그러나 시스템 호출 API를 중단하지 않고는 시스템 호출 번호를 변경할 수 없으므로 통합 노력 이전의 이전 아키텍처(x86, x86_64 및 arm 포함)는 arch/arm64에 남아 있으며 새 unistd.hAPI를 얻습니다.

이 관련 질문에는 매개변수를 포함하여 시스템 호출의 전체 목록을 가져오는 자동화된 방법이 필요합니다.https://stackoverflow.com/questions/6604007/how-can-i-get-a-list-of-linux-system-calls-and-number-of-args-they-take-automati

strace소스 코드

저는 이 도구를 신뢰하며 데이터를 깔끔하게 유지합니다 linux/. 예를 들면 다음과 같습니다.

aarch64는 #include아치와 아무 관련이 없습니다.64/syscallent.h나는 그것을 전에 언급했다.

strace이 테이블에는 매개변수의 개수가 포함되어 있지만 실제 매개변수 유형은 포함되어 있지 않으며 해당 테이블이 인코딩된 위치를 알고 싶습니다 .

glibc소스 코드

답변3

Linux에서 지원되는 각 아키텍처에 대한 모든 시스템 호출을 나열하는 페이지가 있습니다.

https://marcin.juszkiewicz.com.pl/download/tables/syscalls.html

답변4

이 답변은 버전 을 다루는 것이 없기 때문에 asm-generic버전을 다루지 않습니다 . 1unistd.h

에 명시된 바와 같이 syscalls(2):

대략적으로 말하면, 에 정의된 시스템 호출 번호 __NR_xxx에 속하는 코드는 /usr/include/asm/unistd.hLinux 커널 소스 코드의 루틴()에서 찾을 수 있습니다 sys_xxx.

즉, 올바른 시스템 호출 번호는 에서 찾을 수 있습니다 /usr/include/asm/unistd.h. 이제 일반적인 x86 시스템에서는 asm/unistd_*.h대상에 따라 파일 중 하나만 포함됩니다.

64비트 프로그램의 시스템 호출 번호는 이고 asm/unistd_64.h32비트 프로그램의 시스템 호출 번호는 입니다 asm/unistd_32.h(또는 거의 동등한 _x32.h변형). 32비트와 64비트 아키텍처는 실제로 완전히 다른 운영 체제이기 때문에 둘은 다릅니다. 여러 가지 이유로 동일한 시스템 호출 세트를 공유하지만 순서는 다릅니다.

대부분은 C 래퍼도 포함하므로 syscall(2)직접 사용할 필요가 거의 없습니다.


1 목적이 무엇인지 모르기 때문입니다.

관련 정보