]>
Commit | Line | Data |
---|---|---|
d6cc1829 L |
1 | /* ABI compatibility for 'longjmp' and 'siglongjmp' symbols in libpthread ABI. |
2 | X86 version. | |
04277e02 | 3 | Copyright (C) 1918-2019 Free Software Foundation, Inc. |
d6cc1829 L |
4 | This file is part of the GNU C Library. |
5 | ||
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. | |
10 | ||
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. | |
15 | ||
16 | You should have received a copy of the GNU Lesser General Public | |
17 | License along with the GNU C Library; if not, see | |
18 | <http://www.gnu.org/licenses/>. */ | |
19 | ||
20 | #include <pthreadP.h> | |
21 | #include <jmp_buf-ssp.h> | |
22 | ||
23 | #ifdef __x86_64__ | |
24 | # define SHADOW_STACK_POINTER_SIZE 8 | |
25 | #else | |
26 | # define SHADOW_STACK_POINTER_SIZE 4 | |
27 | #endif | |
28 | ||
29 | /* Assert that the priv field in struct pthread_unwind_buf has space | |
30 | to store shadow stack pointer. */ | |
31 | _Static_assert ((offsetof (struct pthread_unwind_buf, priv) | |
32 | <= SHADOW_STACK_POINTER_OFFSET) | |
33 | && ((offsetof (struct pthread_unwind_buf, priv) | |
34 | + sizeof (((struct pthread_unwind_buf *) 0)->priv)) | |
35 | >= (SHADOW_STACK_POINTER_OFFSET | |
36 | + SHADOW_STACK_POINTER_SIZE)), | |
37 | "Shadow stack pointer is not within private storage " | |
38 | "of pthread_unwind_buf."); | |
39 | ||
40 | #include <shlib-compat.h> | |
41 | ||
42 | /* libpthread once had its own longjmp (and siglongjmp alias), though there | |
43 | was no apparent reason for it. There is no use in having a separate | |
44 | symbol in libpthread, but the historical ABI requires it. For static | |
45 | linking, there is no need to provide anything here--the libc version | |
46 | will be linked in. For shared library ABI compatibility, there must be | |
47 | longjmp and siglongjmp symbols in libpthread.so. | |
48 | ||
49 | With an IFUNC resolver, it would be possible to avoid the indirection, | |
50 | but the IFUNC resolver might run before the __libc_longjmp symbol has | |
51 | been relocated, in which case the IFUNC resolver would not be able to | |
52 | provide the correct address. */ | |
53 | ||
54 | #if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_22) | |
55 | ||
56 | static void __attribute__ ((noreturn, used)) | |
57 | longjmp_compat (jmp_buf env, int val) | |
58 | { | |
59 | /* NB: We call __libc_siglongjmp, instead of __libc_longjmp, since | |
60 | __libc_longjmp is a private interface for cancellation which | |
61 | doesn't restore shadow stack register. */ | |
62 | __libc_siglongjmp (env, val); | |
63 | } | |
64 | ||
65 | strong_alias (longjmp_compat, longjmp_alias) | |
66 | compat_symbol (libpthread, longjmp_alias, longjmp, GLIBC_2_0); | |
67 | ||
68 | strong_alias (longjmp_alias, siglongjmp_alias) | |
69 | compat_symbol (libpthread, siglongjmp_alias, siglongjmp, GLIBC_2_0); | |
70 | ||
71 | #endif |