diff options
author | guenther <> | 2019-05-13 20:00:32 +0000 |
---|---|---|
committer | guenther <> | 2019-05-13 20:00:32 +0000 |
commit | 70b2a950f692eeeb801c24634d9740964ff30a50 (patch) | |
tree | 4458ec91afc3b14a32699aea4083dc9e86c4707b | |
parent | 87499aadbc125b924c025665e4b8ab2ef7f93eb4 (diff) | |
download | openbsd-70b2a950f692eeeb801c24634d9740964ff30a50.tar.gz openbsd-70b2a950f692eeeb801c24634d9740964ff30a50.tar.bz2 openbsd-70b2a950f692eeeb801c24634d9740964ff30a50.zip |
Move 'how this works' details from namespace.h to DETAILS
-rw-r--r-- | src/lib/libc/include/DETAILS | 133 | ||||
-rw-r--r-- | src/lib/libc/include/namespace.h | 115 |
2 files changed, 136 insertions, 112 deletions
diff --git a/src/lib/libc/include/DETAILS b/src/lib/libc/include/DETAILS new file mode 100644 index 0000000000..6382cc1c0d --- /dev/null +++ b/src/lib/libc/include/DETAILS | |||
@@ -0,0 +1,133 @@ | |||
1 | The goal: calls from inside libc to other libc functions should | ||
2 | * not be overridable (except for the malloc family), and | ||
3 | * not have pointless inefficiencies. | ||
4 | |||
5 | To achieve this, we arrange that all these internal call be via | ||
6 | identifiers that are of hidden visibility and--to avoid confusion | ||
7 | and work correctly in static executables--are in the reserved | ||
8 | namespace. | ||
9 | |||
10 | This document describes the details of the naming scheme and how | ||
11 | it is implemented. | ||
12 | |||
13 | I've chosen a prefix of underbar-libc-underbar ("_libc_") for this. | ||
14 | These are not declared directly; instead, the gcc "asm labels" | ||
15 | extension is used to rename the function. | ||
16 | |||
17 | We need many of the symbols to be weak in *static* builds, but they | ||
18 | can be strong in the dynamic library, as there's a natural precedence | ||
19 | from the search order there. When the descriptions below say a | ||
20 | name is "weak", that is only necessary for the static library and | ||
21 | not for the shared library. Note: use defined(PIC) to recognize | ||
22 | when compiling the shared objects: some archs define __PIC__ *all* | ||
23 | the time. | ||
24 | |||
25 | --------- | ||
26 | |||
27 | For syscalls which are not cancellation points, such as getpid(), | ||
28 | the identifiers are just: | ||
29 | _libc_getpid hidden alias, for use internal to libc only | ||
30 | _thread_sys_getpid global name, for use outside libc only | ||
31 | getpid weak alias, for use outside libc only | ||
32 | |||
33 | For syscalls which are cancellation points, such as wait4(), there | ||
34 | are identifiers that do not provide cancellation: | ||
35 | _libc_wait4 hidden alias, for use internal to libc only | ||
36 | _thread_sys_wait4 global name, for use outside libc only | ||
37 | ...and identifiers that do provide cancellation: | ||
38 | wait4 weak alias, for general use | ||
39 | _libc_wait4_cancel hidden name, for use internal to libc only | ||
40 | Inside libc, the bare name ("wait4") binds to the version *with* | ||
41 | cancellation. If it's necessary to use the syscall without doing | ||
42 | cancellation it can be obtained by calling HIDDEN(x) instead of | ||
43 | just x. | ||
44 | |||
45 | Some other calls need to be wrapped for reasons other than cancellation, | ||
46 | such as to provide functionality beyond the underlying syscall (e.g., | ||
47 | ptrace). For these, there are identifiers for the raw call, without | ||
48 | the wrapping: | ||
49 | _libc_ptrace hidden alias, for use internal to libc only | ||
50 | _thread_sys_ptrace global name, for use outside libc only | ||
51 | ...and identifiers that do provide the libc wrapping: | ||
52 | ptrace weak alias, for general use | ||
53 | _libc_ptrace_wrap hidden name, for use internal to libc only | ||
54 | Inside libc, the bare name ("ptrace") binds to the wrapper; if | ||
55 | the raw version is necessary it can be obtained by calling HIDDEN(x) | ||
56 | instead of just x. | ||
57 | |||
58 | For syscalls implemented in ASM, the aliases of the raw syscall stub | ||
59 | are provided by the ASM macros. Of the macros used by sys/Makefile.inc: | ||
60 | RSYSCALL(), PSEUDO(), and PSEUDO_NOERROR() generate all three names | ||
61 | (ala getpid() above), while RSYSCALL_HIDDEN() generates just the | ||
62 | _thread_sys_x and _libc_x names. | ||
63 | |||
64 | |||
65 | |||
66 | By using gcc's "asm label" extension, we can usually avoid having | ||
67 | to type those prefixes in the .h and .c files. However, for those | ||
68 | cases where a non-default binding is necessary we can use these macros | ||
69 | to get the desired identifier: | ||
70 | |||
71 | CANCEL(x) | ||
72 | This expands to the internal, hidden name of a cancellation | ||
73 | wrapper: _libc_x_cancel. ex: CANCEL(fsync)(fd) | ||
74 | |||
75 | WRAP(x) | ||
76 | This expands to the internal, hidden name of a non-cancellation | ||
77 | wrapper: _libc_x_wrap. ex: WRAP(sigprocmask)(set) | ||
78 | |||
79 | |||
80 | In order to actually set up the desired asm labels, we use these in | ||
81 | the internal .h files: | ||
82 | PROTO_NORMAL(x) Symbols used both internally and externally | ||
83 | This makes gcc convert use of x to use _libc_x instead | ||
84 | ex: PROTO_NORMAL(getpid) | ||
85 | |||
86 | PROTO_STD_DEPRECATED(x) Standard C symbols that we don't want to use | ||
87 | This just marks the symbol as deprecated, with no renaming. | ||
88 | ex: PROTO_STD_DEPRECATED(strcpy) | ||
89 | |||
90 | PROTO_DEPRECATED(x) Symbols not in ISO C that we don't want to use | ||
91 | This marks the symbol as both weak and deprecated, with no renaming | ||
92 | ex: PROTO_DEPRECATED(creat) | ||
93 | |||
94 | PROTO_CANCEL(x) Functions that have cancellation wrappers | ||
95 | Like PROTO_NORMAL(x), but also declares _libc_x_cancel | ||
96 | ex: PROTO_CANCEL(wait4) | ||
97 | |||
98 | PROTO_WRAP(x) Functions that have wrappers for other reasons | ||
99 | Like PROTO_NORMAL(x), but also declares _libc_x_wrap. Internal | ||
100 | calls that want the wrapper's processing should invoke WRAP(x)(...) | ||
101 | ex: PROTO_WRAP(sigaction) | ||
102 | |||
103 | |||
104 | Finally, to create the expected aliases, we use these in the .c files | ||
105 | where the definitions are: | ||
106 | DEF_STRONG(x) Symbols reserved to or specified by ISO C | ||
107 | This defines x as a strong alias for _libc_x; this must only | ||
108 | be used for symbols that are reserved by the C standard | ||
109 | (or reserved in the external identifier namespace). | ||
110 | Matches with PROTO_NORMAL() | ||
111 | ex: DEF_STRONG(fopen) | ||
112 | |||
113 | DEF_WEAK(x) Symbols used internally and not in ISO C | ||
114 | This defines x as a weak alias for _libc_x | ||
115 | Matches with PROTO_NORMAL() | ||
116 | ex: DEF_WEAK(lseek) | ||
117 | |||
118 | DEF_CANCEL(x) Symbols that have a cancellation wrapper | ||
119 | This defines x as a weak alias for _libc_x_cancel. | ||
120 | Matches with PROTO_CANCEL() | ||
121 | ex: DEF_CANCEL(read) | ||
122 | |||
123 | DEF_WRAP(x) | ||
124 | This defines x as a weak alias for _libc_x_wrap. | ||
125 | Matches with PROTO_WRAP() | ||
126 | ex: DEF_WRAP(ptrace) | ||
127 | |||
128 | MAKE_CLONE(dst, src) Symbols that are exact clones of other symbols | ||
129 | This declares _libc_dst as being the same type as dst, and makes | ||
130 | _libc_dst a strong, hidden alias for _libc_src. You still need to | ||
131 | DEF_STRONG(dst) or DEF_WEAK(dst) to alias dst itself | ||
132 | ex: MAKE_CLONE(SHA224Pad, SHA256Pad) | ||
133 | |||
diff --git a/src/lib/libc/include/namespace.h b/src/lib/libc/include/namespace.h index 60766afc0b..79692af0bc 100644 --- a/src/lib/libc/include/namespace.h +++ b/src/lib/libc/include/namespace.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: namespace.h,v 1.12 2018/01/18 08:23:44 guenther Exp $ */ | 1 | /* $OpenBSD: namespace.h,v 1.13 2019/05/13 20:00:32 guenther Exp $ */ |
2 | 2 | ||
3 | #ifndef _LIBC_NAMESPACE_H_ | 3 | #ifndef _LIBC_NAMESPACE_H_ |
4 | #define _LIBC_NAMESPACE_H_ | 4 | #define _LIBC_NAMESPACE_H_ |
@@ -20,117 +20,8 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | /* | 22 | /* |
23 | * The goal: calls from inside libc to other libc functions should be via | 23 | * For explanations of how to use these, see README |
24 | * identifiers that are of hidden visibility and--to avoid confusion--are | 24 | * For explanations of why we use them and how they work, see DETAILS |
25 | * in the reserved namespace. By doing this these calls are protected | ||
26 | * from overriding by applications and on many platforms can avoid creation | ||
27 | * or use of GOT or PLT entries. I've chosen a prefix of underbar-C-underbar | ||
28 | * ("_libc_") for this. These will not be declared directly; instead, the | ||
29 | * gcc "asm labels" extension will be used rename the function. | ||
30 | * | ||
31 | * For syscalls which are cancellation points, such as wait4(), there | ||
32 | * are identifiers that do not provide cancellation: | ||
33 | * _libc_wait4 hidden alias, for use internal to libc only | ||
34 | * _thread_sys_wait4 global name, for use outside libc only | ||
35 | * ...and identifiers that do provide cancellation: | ||
36 | * wait4 weak alias, for general use | ||
37 | * _libc_wait4_cancel hidden alias, for use internal to libc only | ||
38 | * Inside libc, the bare name ("wait4") binds to the version *without* | ||
39 | * cancellation; the few times where cancellation is desired it can be | ||
40 | * obtained by calling CANCEL(x) instead of just x. | ||
41 | * | ||
42 | * Some other calls need to be wrapped for reasons other than cancellation, | ||
43 | * such as to provide functionality beyond the underlying syscall (e.g., | ||
44 | * sigaction). For these, there are identifiers for the raw call, without | ||
45 | * the wrapping: | ||
46 | * _libc_sigaction hidden alias, for use internal to libc only | ||
47 | * _thread_sys_sigaction global name, for use outside libc only | ||
48 | * ...and identifiers that do provide the libc wrapping: | ||
49 | * sigaction weak alias, for general use | ||
50 | * _libc_sigaction_wrap hidden alias, for use internal to libc only | ||
51 | * Inside libc, the bare name ("sigaction") binds to the wrapper; when the | ||
52 | * raw version is necessary it can be obtained by calling HIDDEN(x) instead of | ||
53 | * just x. | ||
54 | * | ||
55 | * For syscalls which are not cancellation points, such as getpid(), | ||
56 | * the identifiers are just: | ||
57 | * _libc_getpid hidden alias, for use internal to libc only | ||
58 | * _thread_sys_getpid global name, for use outside libc only | ||
59 | * getpid weak alias, for use outside libc only | ||
60 | * | ||
61 | * By using gcc's "asm label" extension, we can usually avoid having | ||
62 | * to type those prefixes in the .h and .c files. However, for those | ||
63 | * cases where a non-default binding is necessary we can use these macros | ||
64 | * to get the desired identifier: | ||
65 | * | ||
66 | * CANCEL(x) | ||
67 | * This expands to the internal, hidden name of a cancellation | ||
68 | * wrapper: _libc_x_cancel. ex: CANCEL(fsync)(fd) | ||
69 | * | ||
70 | * WRAP(x) | ||
71 | * This expands to the internal, hidden name of a non-cancellation | ||
72 | * wrapper: _libc_x_wrap. ex: WRAP(sigprocmask)(set) | ||
73 | * | ||
74 | * | ||
75 | * In order to actually set up the desired asm labels, we use these in | ||
76 | * the internal .h files: | ||
77 | * PROTO_NORMAL(x) Symbols used both internally and externally | ||
78 | * This makes gcc convert use of x to use _libc_x instead | ||
79 | * ex: PROTO_NORMAL(getpid) | ||
80 | * | ||
81 | * PROTO_STD_DEPRECATED(x) Standard C symbols that we don't want to use | ||
82 | * This just marks the symbol as deprecated, with no renaming. | ||
83 | * ex: PROTO_STD_DEPRECATED(strcpy) | ||
84 | * | ||
85 | * PROTO_DEPRECATED(x) Symbols not in ISO C that we don't want to use | ||
86 | * This marks the symbol as both weak and deprecated, with no renaming | ||
87 | * ex: PROTO_DEPRECATED(creat) | ||
88 | * | ||
89 | * PROTO_CANCEL(x) Functions that have cancellation wrappers | ||
90 | * Like PROTO_NORMAL(x), but also declares _libc_x_cancel | ||
91 | * ex: PROTO_CANCEL(wait4) | ||
92 | * | ||
93 | * PROTO_WRAP(x) Functions that have wrappers for other reasons | ||
94 | * Like PROTO_NORMAL(x), but also declares _libc_x_wrap. Internal | ||
95 | * calls that want the wrapper's processing should invoke WRAP(x)(...) | ||
96 | * ex: PROTO_WRAP(sigaction) | ||
97 | * | ||
98 | * | ||
99 | * Finally, to create the expected aliases, we use these in the .c files | ||
100 | * where the definitions are: | ||
101 | * DEF_STRONG(x) Symbols reserved to or specified by ISO C | ||
102 | * This defines x as a strong alias for _libc_x; this must only | ||
103 | * be used for symbols that are reserved by the C standard | ||
104 | * (or reserved in the external identifier namespace). | ||
105 | * Matches with PROTO_NORMAL() | ||
106 | * ex: DEF_STRONG(fopen) | ||
107 | * | ||
108 | * DEF_WEAK(x) Symbols used internally and not in ISO C | ||
109 | * This defines x as a weak alias for _libc_x | ||
110 | * Matches with PROTO_NORMAL() | ||
111 | * ex: DEF_WEAK(lseek) | ||
112 | * | ||
113 | * DEF_CANCEL(x) Symbols that have a cancellation wrapper | ||
114 | * This defines x as a weak alias for _libc_x_cancel. | ||
115 | * Matches with PROTO_CANCEL() | ||
116 | * ex: DEF_CANCEL(read) | ||
117 | * | ||
118 | * DEF_WRAP(x) | ||
119 | * This defines x as a weak alias for _libc_x_wrap. | ||
120 | * Matches with PROTO_WRAP() | ||
121 | * ex: DEF_WRAP(sigaction) | ||
122 | * | ||
123 | * DEF_SYS(x) | ||
124 | * This defines _thread_sys_x as a strong alias for _libc_x. This should | ||
125 | * only be needed for syscalls that have C instead of asm stubs. | ||
126 | * Matches with PROTO_NORMAL(), PROTO_CANCEL(), or PROTO_WRAP() | ||
127 | * ex: DEF_SYS(pread) | ||
128 | * | ||
129 | * MAKE_CLONE(dst, src) Symbols that are exact clones of other symbols | ||
130 | * This declares _libc_dst as being the same type as dst, and makes | ||
131 | * _libc_dst a strong, hidden alias for _libc_src. You still need to | ||
132 | * DEF_STRONG(dst) or DEF_WEAK(dst) to alias dst itself | ||
133 | * ex: MAKE_CLONE(SHA224Pad, SHA256Pad) | ||
134 | */ | 25 | */ |
135 | 26 | ||
136 | #include <sys/cdefs.h> /* for __dso_hidden and __{weak,strong}_alias */ | 27 | #include <sys/cdefs.h> /* for __dso_hidden and __{weak,strong}_alias */ |