1The 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 5To achieve this, we arrange that all these internal call be via 6identifiers that are of hidden visibility and--to avoid confusion 7and work correctly in static executables--are in the reserved 8namespace. 9 10This document describes the details of the naming scheme and how 11it is implemented. 12 13I've chosen a prefix of underbar-libc-underbar ("_libc_") for this. 14These are not declared directly; instead, the gcc "asm labels" 15extension is used to rename the function. 16 17We need many of the symbols to be weak in *static* builds, but they 18can be strong in the dynamic library, as there's a natural precedence 19from the search order there. When the descriptions below say a 20name is "weak", that is only necessary for the static library and 21not for the shared library. Note: use defined(PIC) to recognize 22when compiling the shared objects: some archs define __PIC__ *all* 23the time. 24 25--------- 26 27For syscalls which are not cancellation points, such as getpid(), 28the 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 33For syscalls which are cancellation points, such as wait4(), there 34are 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 40Inside libc, the bare name ("wait4") binds to the version *with* 41cancellation. If it's necessary to use the syscall without doing 42cancellation it can be obtained by calling HIDDEN(x) instead of 43just x. 44 45Some other calls need to be wrapped for reasons other than cancellation, 46such as to provide functionality beyond the underlying syscall (e.g., 47ptrace). For these, there are identifiers for the raw call, without 48the 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 54Inside libc, the bare name ("ptrace") binds to the wrapper; if 55the raw version is necessary it can be obtained by calling HIDDEN(x) 56instead of just x. 57 58For syscalls implemented in ASM, the aliases of the raw syscall stub 59are provided by the ASM macros. Of the macros used by sys/Makefile.inc: 60RSYSCALL(), 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 66By using gcc's "asm label" extension, we can usually avoid having 67to type those prefixes in the .h and .c files. However, for those 68cases where a non-default binding is necessary we can use these macros 69to 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 80In order to actually set up the desired asm labels, we use these in 81the 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 104Finally, to create the expected aliases, we use these in the .c files 105where 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 134