1
/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
2
This file is part of the GNU C Library.
3
Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
4
Modification for FreeBSD contributed by Petr Salinger, 2006.
6
The GNU C Library is free software; you can redistribute it and/or
7
modify it under the terms of the GNU Lesser General Public
8
License as published by the Free Software Foundation; either
9
version 2.1 of the License, or (at your option) any later version.
11
The GNU C Library is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
Lesser General Public License for more details.
16
You should have received a copy of the GNU Lesser General Public
17
License along with the GNU C Library; if not, write to the Free
18
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23
#include <pt-machine.h>
25
# include <linuxthreads/internals.h>
28
/* Syscalls with more than 6 arguments are not supported here. */
30
#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
33
# define PSEUDO(name, syscall_name, args) \
37
jne L(pseudo_cancel); \
38
DO_CALL (syscall_name, args); \
39
jb SYSCALL_ERROR_LABEL; \
42
/* Save registers that might get destroyed. */ \
46
/* Restore registers. */ \
49
/* The return value from CENABLE is argument for CDISABLE. */ \
51
movl $SYS_ify (syscall_name), %eax; \
53
popq %rdi; cfi_adjust_cfa_offset(-8); \
54
pushfq; cfi_adjust_cfa_offset(8); \
55
/* Save %rax since it's the return/error code from the syscall. */ \
58
popfq; cfi_adjust_cfa_offset(-8); \
59
/* fetch the error code from the syscall. */ \
60
popq %rax; cfi_adjust_cfa_offset(-8); \
61
/* adjust rsp, do not change flags */ \
62
popq %rdx; cfi_adjust_cfa_offset(-8); \
63
jb SYSCALL_ERROR_LABEL; \
66
# define PUSHARGS_0 /* Nothing. */
67
# define PUSHARGS_1 PUSHARGS_0 movq %rdi, 8(%rsp);
68
# define PUSHARGS_2 PUSHARGS_1 movq %rsi, 16(%rsp);
69
# define PUSHARGS_3 PUSHARGS_2 movq %rdx, 24(%rsp);
70
# define PUSHARGS_4 PUSHARGS_3 movq %rcx, 32(%rsp);
71
# define PUSHARGS_5 PUSHARGS_4 movq %r8, 40(%rsp);
72
# define PUSHARGS_6 PUSHARGS_5 movq %r9, 48(%rsp);
74
# define POPARGS_0 /* Nothing. */
75
# define POPARGS_1 POPARGS_0 movq 8(%rsp), %rdi;
76
# define POPARGS_2 POPARGS_1 movq 16(%rsp), %rsi;
77
# define POPARGS_3 POPARGS_2 movq 24(%rsp), %rdx;
78
# define POPARGS_4 POPARGS_3 movq 32(%rsp), %r10;
79
# define POPARGS_5 POPARGS_4 movq 40(%rsp), %r8;
80
# define POPARGS_6 POPARGS_5 movq 48(%rsp), %r9;
82
/* We always have to align the stack before calling a function. */
83
# define SAVESTK_0 subq $24, %rsp;cfi_adjust_cfa_offset(24);
84
# define SAVESTK_1 SAVESTK_0
85
# define SAVESTK_2 SAVESTK_1
86
# define SAVESTK_3 subq $40, %rsp;cfi_adjust_cfa_offset(40);
87
# define SAVESTK_4 SAVESTK_3
88
# define SAVESTK_5 subq $56, %rsp;cfi_adjust_cfa_offset(56);
89
# define SAVESTK_6 SAVESTK_5
91
# define RESTSTK_0 /* Nothing. */
92
# define RESTSTK_1 RESTSTK_0
93
# define RESTSTK_2 RESTSTK_1
94
# define RESTSTK_3 addq $16, %rsp;cfi_adjust_cfa_offset(-16);
95
# define RESTSTK_4 RESTSTK_3
96
# define RESTSTK_5 addq $32, %rsp;cfi_adjust_cfa_offset(-32);
97
# define RESTSTK_6 RESTSTK_5
99
# ifdef IS_IN_libpthread
100
# define CENABLE call __pthread_enable_asynccancel;
101
# define CDISABLE call __pthread_disable_asynccancel;
102
# define __local_multiple_threads __pthread_multiple_threads
103
# elif !defined NOT_IN_libc
104
# define CENABLE call __libc_enable_asynccancel;
105
# define CDISABLE call __libc_disable_asynccancel;
106
# define __local_multiple_threads __libc_multiple_threads
108
# define CENABLE call __librt_enable_asynccancel@plt;
109
# define CDISABLE call __librt_disable_asynccancel@plt;
112
# if defined IS_IN_libpthread || !defined NOT_IN_libc
113
# ifndef __ASSEMBLER__
114
extern int __local_multiple_threads attribute_hidden;
115
# define SINGLE_THREAD_P \
116
__builtin_expect (__local_multiple_threads == 0, 1)
118
# define SINGLE_THREAD_P cmpl $0, __local_multiple_threads(%rip)
123
# ifndef __ASSEMBLER__
124
# define SINGLE_THREAD_P \
125
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
126
p_header.data.multiple_threads) == 0, 1)
128
# define SINGLE_THREAD_P cmpl $0, %fs:MULTIPLE_THREADS_OFFSET
133
#elif !defined __ASSEMBLER__
135
/* This code should never be used but we define it anyhow. */
136
# define SINGLE_THREAD_P (1)
137
# define NO_CANCELLATION 1
141
#ifndef __ASSEMBLER__
142
# define RTLD_SINGLE_THREAD_P \
143
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
144
p_header.data.multiple_threads) == 0, 1)