]>
Commit | Line | Data |
---|---|---|
33574c17 | 1 | /* Machine dependent pthreads code. Hurd/i386 version. |
04277e02 | 2 | Copyright (C) 2000-2019 Free Software Foundation, Inc. |
33574c17 ST |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
ad2b41bf ST |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
33574c17 ST |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
ad2b41bf | 13 | Lesser General Public License for more details. |
33574c17 | 14 | |
ad2b41bf ST |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, see | |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
33574c17 ST |
18 | |
19 | #include <errno.h> | |
20 | ||
21 | #include <mach.h> | |
22 | #include <mach/i386/thread_status.h> | |
23 | #include <mach/i386/mach_i386.h> | |
24 | #include <mach/mig_errors.h> | |
25 | #include <mach/thread_status.h> | |
26 | ||
27 | #define HURD_TLS_DESC_DECL(desc, tcb) \ | |
28 | struct descriptor desc = \ | |
29 | { /* low word: */ \ | |
30 | 0xffff /* limit 0..15 */ \ | |
31 | | (((unsigned int) (tcb)) << 16) /* base 0..15 */ \ | |
32 | , /* high word: */ \ | |
33 | ((((unsigned int) (tcb)) >> 16) & 0xff) /* base 16..23 */ \ | |
34 | | ((0x12 | 0x60 | 0x80) << 8) /* access = ACC_DATA_W|ACC_PL_U|ACC_P */ \ | |
35 | | (0xf << 16) /* limit 16..19 */ \ | |
36 | | ((4 | 8) << 20) /* granularity = SZ_32|SZ_G */ \ | |
37 | | (((unsigned int) (tcb)) & 0xff000000) /* base 24..31 */ \ | |
38 | } | |
39 | ||
40 | int | |
41 | __thread_set_pcsptp (thread_t thread, | |
42 | int set_ip, void *ip, | |
43 | int set_sp, void *sp, | |
44 | int set_tp, void *tp) | |
45 | { | |
46 | error_t err; | |
47 | struct i386_thread_state state; | |
48 | mach_msg_type_number_t state_count; | |
49 | ||
50 | state_count = i386_THREAD_STATE_COUNT; | |
51 | ||
52 | err = __thread_get_state (thread, i386_REGS_SEGS_STATE, | |
53 | (thread_state_t) &state, &state_count); | |
54 | if (err) | |
55 | return err; | |
56 | ||
57 | if (set_sp) | |
58 | state.uesp = (unsigned int) sp; | |
59 | if (set_ip) | |
60 | state.eip = (unsigned int) ip; | |
61 | if (set_tp) | |
62 | { | |
63 | HURD_TLS_DESC_DECL (desc, tp); | |
64 | int sel; | |
65 | ||
66 | asm ("mov %%gs, %w0": "=q" (sel):"0" (0)); | |
67 | if (__builtin_expect (sel, 0x48) & 4) /* LDT selector */ | |
68 | err = __i386_set_ldt (thread, sel, &desc, 1); | |
69 | else | |
70 | err = __i386_set_gdt (thread, &sel, desc); | |
71 | if (err) | |
72 | return err; | |
73 | state.gs = sel; | |
74 | } | |
75 | ||
76 | err = __thread_set_state (thread, i386_REGS_SEGS_STATE, | |
77 | (thread_state_t) &state, i386_THREAD_STATE_COUNT); | |
78 | if (err) | |
79 | return err; | |
80 | ||
81 | return 0; | |
82 | } |