在/glibc/sysdeps/unix/sysv/linux/这个目录,如果平台不需要特制化的改动会在使用目录下的文件。如果需要特制化的代码,就会在这个目录创建平台特定的目录,实现其特制的代码。
/glibc/sysdeps/unix/sysv/linux/sigreturn.c
/* The sigreturn syscall cannot be explicitly called on Linux, only
implicitly by returning from a signal handler. */
#include
signal/sigreturn.c
int
__sigreturn (struct sigcontext *context)
{
__set_errno (ENOSYS);
return -1;
}
stub_warning (sigreturn)
weak_alias (__sigreturn, sigreturn)
0x26 =
/*
* This error code is special: arch syscall entry code will return
* -ENOSYS if users try to call a syscall that doesn't exist. To keep
* failures of syscalls that really do exist distinguishable from
* failures due to attempts to use a nonexistent syscall, syscall
* implementations should refrain from returning -ENOSYS.
*/
#define ENOSYS 38 /* Invalid system call number */
(gdb) disass __sigreturn
Dump of assembler code for function sigreturn:
0x0000000000036f90 <+0>: mov 0x38feb9(%rip),%rax # 0x3c6e50
0x0000000000036f97 <+7>: movl $0x26,%fs:(%rax); 这里可以看到直接讲errno放到了线程相关数据的某一个位置。
0x0000000000036f9e <+14>: mov $0xffffffff,%eax
0x0000000000036fa3 <+19>:
即使是O2的优化,还是会调用库函数__errno_location。原因在于errno的相对位置在库函数里确定的,离开库函数,应用找不到errno的地址。这里也可以看到
(gdb) disass main
Dump of assembler code for function main:
0x0000000000400500 <+0>: sub $0x8,%rsp
0x0000000000400504 <+4>: callq 0x4004e0 __errno_location@plt
(gdb) disass __errno_location
Dump of assembler code for function __errno_location@plt:
0x00000000004004e0 <+0>: jmpq *0x200b32(%rip) # 0x601018 __errno_location@got.plt
0x00000000004004e6 <+6>: pushq $0x0
0x00000000004004eb <+11>: jmpq 0x4004d0
libc-2.28.so
(gdb) disass __errno_location
Dump of assembler code for function __errno_location:
0x000000000003af80 <+0>: endbr64
0x000000000003af84 <+4>: mov 0x383edd(%rip),%rax # 0x3bee68 0x3bee68-0x383edd=0x3af8b
0x000000000003af8b <+11>: add %fs:0x0,%rax
0x000000000003af94 <+20>: retq
End of assembler dump.