diff options
Diffstat (limited to '')
| -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 */ |
