2017-03-05 1 views
1

syscall 테이블의 일부 시스템 호출이 /ptregs 인 이유는 무엇입니까? arch/x86/entry/syscalls/syscall_64.tbl에서/syscall 테이블의 ptregs

예 :

54  64  setsockopt    sys_setsockopt 
55  64  getsockopt    sys_getsockopt 
56  common clone     sys_clone/ptregs 
57  common fork     sys_fork/ptregs 
58  common vfork     sys_vfork/ptregs 
59  64  execve     sys_execve/ptregs 
60  common exit     sys_exit 
61  common wait4     sys_wait4 

답변

1

이의 (a struct pt_regs으로) 스택에 배치 전체 레지스터 덤프를 요구하는 특별한 시스템 호출이다. 이것은 32 비트와 비교하여 더 많은 레지스터를 가지고 있기 때문에 64 비트 x86 아키텍처에만 해당됩니다.

시스템 호출 핸들러 (arch/x86/entry/entry_64.S:entry_SYSCALL_64)는 시스템 호출 항목에 스택의 대부분의 레지스터를 저장합니다. 이것은 부분적으로 ptrace()를 지원하고 C로 작성된 실제 시스템 호출 핸들러에 인수를 전달하기 위해 부분적으로 수행됩니다 (이 이유는 asmlinkage 스펙을 갖고 있기 때문에 스택에서 인수를 가져옵니다). 시스템 호출에는 최대 6 개의 인수 (rdi, rsi, rdx, r10, r8, r9)가 있으며 일부 레지스터는 SYSCALL 부기 (rax, rcx, r11)에 사용됩니다. rbp, rbx, r12, r13, r14, r15 (callee-saved)를 저장할 필요가 없으므로 성능상의 이유로 항목에 저장되지 않습니다. 시스템 콜 핸들링이 완료되면 사용자 공간으로 돌아 오기 전에 레지스터가이 백업에서 복원됩니다.

그러나 (는 execve 같은(), 포크(), sigreturn(), 등) 일부 시스템 호출은 struct pt_regs에, (RBX, R12-R15, RBP 포함) 스택에 모든 레지스터가 필요 . 이러한 시스템 호출로 인해 사용자 공간이 다른 위치에서 실행을 다시 시작할 수 있기 때문에 정확한 레지스터 값을 저장해야합니다. syscall_64.tbl에 /ptregs으로 표시되어 다음과 같은 마술이 일어납니다.

일반적으로 시스템 호출 처리기 테이블 (sys_call_table)에는 C 함수에 대한 포인터가 들어 있습니다. 그러나 특수 시스템 호출의 경우 핸들러는 small assembly thunks이며 먼저 여분의 레지스터를 저장 한 다음 C 코드로 이동합니다 (느린 경로의 기능). 테이블의 /ptregs 접미어는 C 함수 대신 이러한 스텁을 처리기 테이블에 삽입하도록 스크립트에 지시합니다.

관련 문제