3 This software is a copyrighted work licensed under the terms of the
4 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
13 #define _NOMNTENT_FUNCS
15 #undef _NOMNTENT_FUNCS
19 #define CYGTLS_INITIALIZED 0xc763173f
22 # define CYG_MAX_PATH 260
29 #define TLS_STACK_SIZE 256
31 #include "cygthread.h"
33 #define TP_NUM_C_BUFS 50
34 #define TP_NUM_W_BUFS 50
42 /* Defined here to support auto rebuild of tlsoffsets.h. */
45 /* Make sure that c_cnt and w_cnt are always the first two members of this
46 class, and never change the size (32 bit), unless you also change the
47 mov statements in sigbe! */
58 char *c_buf
[TP_NUM_C_BUFS
];
59 WCHAR
*w_buf
[TP_NUM_W_BUFS
];
62 void clear () { memset (this, 0, sizeof *this); }
65 friend class tmp_pathbuf
;
74 short port_proto_addrtype
;
83 t_hostent
, t_protoent
, t_servent
90 char pass
[_PASSWORD_LEN
];
99 unsigned available_drives
;
102 char mnt_fsname
[CYG_MAX_PATH
];
103 char mnt_dir
[CYG_MAX_PATH
];
109 LONG
*ser_num
; // note: malloced
110 HANDLE
*w4
; // note: malloced
113 /* strerror errno.cc */
114 char strerror_buf
[sizeof ("Unknown error -2147483648")];
115 char strerror_r_buf
[sizeof ("Unknown error -2147483648")];
118 char timezone_buf
[20];
121 char signamebuf
[sizeof ("Unknown signal 4294967295 ")];
124 char *ntoa_buf
; // note: malloced
125 unionent
*hostent_buf
; // note: malloced
126 unionent
*protoent_buf
; // note: malloced
127 unionent
*servent_buf
; // note: malloced
130 char unknown_thread_name
[30];
139 tls_pathbuf pathbufs
;
143 typedef struct struct_waitq
149 void *rusage
; /* pointer to potential rusage */
150 struct struct_waitq
*next
;
154 /* Changes to the below structure may require acompanying changes to the
155 gawk parser in the shell script 'gentls_offsets' */
157 extern "C" int __sjfault (jmp_buf);
158 extern "C" int __ljfault (jmp_buf, int);
160 typedef uintptr_t __tlsstack_t
;
164 public: /* Do NOT remove this public: line, it's a marker for gentls_offsets. */
165 /* offsetoff (class _cygtls, local_clib) *must* be 0. */
166 struct _reent local_clib
;
167 struct _local_storage locals
;
169 void (*func
) (int, siginfo_t
*, void *);
176 sigset_t sigwait_mask
;
178 siginfo_t
*sigwait_info
;
179 HANDLE signal_arrived
;
180 bool will_wait_for_signal
;
182 long __align
; /* Needed to align context to 16 byte. */
184 /* context MUST be aligned to 16 byte, otherwise RtlCaptureContext fails.
185 If you prepend cygtls members here, make sure context stays 16 byte
186 aligned. The gentls_offsets script checks for that now and fails
187 if the alignment is wrong. */
192 class cygthread
*_ctinfo
;
199 __tlsstack_t
*stackptr
;
200 __tlsstack_t stack
[TLS_STACK_SIZE
];
201 unsigned initialized
;
203 public: /* Do NOT remove this public: line, it's a marker for gentls_offsets. */
204 void init_thread (void *, DWORD (*) (void *, void *));
205 static void call (DWORD (*) (void *, void *), void *);
207 void push (__tlsstack_t addr
) {*stackptr
++ = (__tlsstack_t
) addr
;}
209 __tlsstack_t
retaddr () {return stackptr
[-1];}
210 bool isinitialized () const
212 return initialized
== CYGTLS_INITIALIZED
;
214 bool interrupt_now (CONTEXT
*, siginfo_t
&, void *, struct sigaction
&);
215 void interrupt_setup (siginfo_t
&, void *, struct sigaction
&);
217 bool inside_kernel (CONTEXT
*);
218 void signal_debugger (siginfo_t
&);
221 operator HANDLE () const {return tid
? tid
->win32_obj_id
: NULL
;}
223 int call_signal_handler ();
224 void remove_wq (DWORD
);
225 void fixup_after_fork ();
229 HANDLE
get_signal_arrived (bool wait_for_lock
= true)
236 signal_arrived
= CreateEvent (NULL
, false, false, NULL
);
240 return signal_arrived
;
242 void wait_signal_arrived (bool setit
, HANDLE
& h
)
245 will_wait_for_signal
= false;
248 h
= get_signal_arrived ();
249 will_wait_for_signal
= true;
252 void set_signal_arrived ()
254 SetEvent (get_signal_arrived (false));
256 void reset_signal_arrived ()
259 ResetEvent (signal_arrived
);
261 void unwait_signal_arrived ()
263 will_wait_for_signal
= false;
265 void handle_SIGCONT ();
266 static void cleanup_early(struct _reent
*);
268 void call2 (DWORD (*) (void *, void *), void *, void *);
269 void remove_pending_sigs ();
273 #include "cygerrno.h"
276 #define _my_tls (*((_cygtls *) ((PBYTE) NtCurrentTeb()->Tib.StackBase \
277 - __CYGTLS_PADSIZE__)))
278 extern _cygtls
*_main_tls
;
279 extern _cygtls
*_sig_tls
;
289 san (PVOID _ret
) __attribute__ ((always_inline
))
291 _clemente
= _my_tls
.andreas
;
292 _my_tls
.andreas
= this;
293 _cnt
= _my_tls
.locals
.pathbufs
._counters
;
294 /* myfault_altstack_handler needs the current stack pointer and the
295 address of the _except block to restore the context correctly.
296 See comment preceeding myfault_altstack_handler in exception.cc. */
297 ret
= (DWORD64
) _ret
;
298 __asm__
volatile ("movq %%rsp,%0": "=o" (frame
));
300 ~san () __attribute__ ((always_inline
))
302 _my_tls
.andreas
= _clemente
;
304 /* This is the first thing called in the __except handler. The attribute
305 "returns_twice" makes sure that GCC disregards any register value set
306 earlier in the function, so this call serves as a register barrier. */
307 void leave () __attribute__ ((returns_twice
));
310 /* Exception handling macros. This is a handmade SEH try/except. */
311 #define __mem_barrier __asm__ __volatile__ ("" ::: "memory")
314 __label__ __l_try, __l_except, __l_endtry; \
316 san __sebastian (&&__l_except); \
318 " .seh_handler _ZN9exception7myfaultEP17_EXCEPTION_RECORDPvP8_CONTEXTP19_DISPATCHER_CONTEXT, @except \n" \
319 " .seh_handlerdata \n" \
321 " .rva %l[__l_try],%l[__l_endtry],%l[__l_except],%l[__l_except] \n" \
323 : : : : __l_try, __l_endtry, __l_except); \
331 #define __except(__errno) \
337 __sebastian.leave (); \
347 class wait_signal_arrived
350 wait_signal_arrived (bool setit
, HANDLE
& h
) { _my_tls
.wait_signal_arrived (setit
, h
); }
351 wait_signal_arrived (HANDLE
& h
) { _my_tls
.wait_signal_arrived (true, h
); }
353 operator int () const {return _my_tls
.will_wait_for_signal
;}
354 /* Do not reset the signal_arrived event just because we leave the scope of
355 this wait_signal_arrived object. This may lead to all sorts of races.
356 The only method actually resetting the signal_arrived event is
357 _cygtls::call_signal_handler. */
358 ~wait_signal_arrived () { _my_tls
.unwait_signal_arrived (); }