1*cfc1d11dSguentherThe goal: calls from inside libc to other libc functions should 2*cfc1d11dSguenther * not be overridable (except for the malloc family), and 3*cfc1d11dSguenther * not have pointless inefficiencies. 4*cfc1d11dSguenther 5*cfc1d11dSguentherTo achieve this, we arrange that all these internal call be via 6*cfc1d11dSguentheridentifiers that are of hidden visibility and--to avoid confusion 7*cfc1d11dSguentherand work correctly in static executables--are in the reserved 8*cfc1d11dSguenthernamespace. 9*cfc1d11dSguenther 10*cfc1d11dSguentherThis document describes the details of the naming scheme and how 11*cfc1d11dSguentherit is implemented. 12*cfc1d11dSguenther 13*cfc1d11dSguentherI've chosen a prefix of underbar-libc-underbar ("_libc_") for this. 14*cfc1d11dSguentherThese are not declared directly; instead, the gcc "asm labels" 15*cfc1d11dSguentherextension is used to rename the function. 16*cfc1d11dSguenther 17*cfc1d11dSguentherWe need many of the symbols to be weak in *static* builds, but they 18*cfc1d11dSguenthercan be strong in the dynamic library, as there's a natural precedence 19*cfc1d11dSguentherfrom the search order there. When the descriptions below say a 20*cfc1d11dSguenthername is "weak", that is only necessary for the static library and 21*cfc1d11dSguenthernot for the shared library. Note: use defined(PIC) to recognize 22*cfc1d11dSguentherwhen compiling the shared objects: some archs define __PIC__ *all* 23*cfc1d11dSguentherthe time. 24*cfc1d11dSguenther 25*cfc1d11dSguenther--------- 26*cfc1d11dSguenther 27*cfc1d11dSguentherFor syscalls which are not cancellation points, such as getpid(), 28*cfc1d11dSguentherthe identifiers are just: 29*cfc1d11dSguenther _libc_getpid hidden alias, for use internal to libc only 30*cfc1d11dSguenther _thread_sys_getpid global name, for use outside libc only 31*cfc1d11dSguenther getpid weak alias, for use outside libc only 32*cfc1d11dSguenther 33*cfc1d11dSguentherFor syscalls which are cancellation points, such as wait4(), there 34*cfc1d11dSguentherare identifiers that do not provide cancellation: 35*cfc1d11dSguenther _libc_wait4 hidden alias, for use internal to libc only 36*cfc1d11dSguenther _thread_sys_wait4 global name, for use outside libc only 37*cfc1d11dSguenther...and identifiers that do provide cancellation: 38*cfc1d11dSguenther wait4 weak alias, for general use 39*cfc1d11dSguenther _libc_wait4_cancel hidden name, for use internal to libc only 40*cfc1d11dSguentherInside libc, the bare name ("wait4") binds to the version *with* 41*cfc1d11dSguenthercancellation. If it's necessary to use the syscall without doing 42*cfc1d11dSguenthercancellation it can be obtained by calling HIDDEN(x) instead of 43*cfc1d11dSguentherjust x. 44*cfc1d11dSguenther 45*cfc1d11dSguentherSome other calls need to be wrapped for reasons other than cancellation, 46*cfc1d11dSguenthersuch as to provide functionality beyond the underlying syscall (e.g., 47*cfc1d11dSguentherptrace). For these, there are identifiers for the raw call, without 48*cfc1d11dSguentherthe wrapping: 49*cfc1d11dSguenther _libc_ptrace hidden alias, for use internal to libc only 50*cfc1d11dSguenther _thread_sys_ptrace global name, for use outside libc only 51*cfc1d11dSguenther...and identifiers that do provide the libc wrapping: 52*cfc1d11dSguenther ptrace weak alias, for general use 53*cfc1d11dSguenther _libc_ptrace_wrap hidden name, for use internal to libc only 54*cfc1d11dSguentherInside libc, the bare name ("ptrace") binds to the wrapper; if 55*cfc1d11dSguentherthe raw version is necessary it can be obtained by calling HIDDEN(x) 56*cfc1d11dSguentherinstead of just x. 57*cfc1d11dSguenther 58*cfc1d11dSguentherFor syscalls implemented in ASM, the aliases of the raw syscall stub 59*cfc1d11dSguentherare provided by the ASM macros. Of the macros used by sys/Makefile.inc: 60*cfc1d11dSguentherRSYSCALL(), PSEUDO(), and PSEUDO_NOERROR() generate all three names 61*cfc1d11dSguenther(ala getpid() above), while RSYSCALL_HIDDEN() generates just the 62*cfc1d11dSguenther_thread_sys_x and _libc_x names. 63*cfc1d11dSguenther 64*cfc1d11dSguenther 65*cfc1d11dSguenther 66*cfc1d11dSguentherBy using gcc's "asm label" extension, we can usually avoid having 67*cfc1d11dSguentherto type those prefixes in the .h and .c files. However, for those 68*cfc1d11dSguenthercases where a non-default binding is necessary we can use these macros 69*cfc1d11dSguentherto get the desired identifier: 70*cfc1d11dSguenther 71*cfc1d11dSguenther CANCEL(x) 72*cfc1d11dSguenther This expands to the internal, hidden name of a cancellation 73*cfc1d11dSguenther wrapper: _libc_x_cancel. ex: CANCEL(fsync)(fd) 74*cfc1d11dSguenther 75*cfc1d11dSguenther WRAP(x) 76*cfc1d11dSguenther This expands to the internal, hidden name of a non-cancellation 77*cfc1d11dSguenther wrapper: _libc_x_wrap. ex: WRAP(sigprocmask)(set) 78*cfc1d11dSguenther 79*cfc1d11dSguenther 80*cfc1d11dSguentherIn order to actually set up the desired asm labels, we use these in 81*cfc1d11dSguentherthe internal .h files: 82*cfc1d11dSguenther PROTO_NORMAL(x) Symbols used both internally and externally 83*cfc1d11dSguenther This makes gcc convert use of x to use _libc_x instead 84*cfc1d11dSguenther ex: PROTO_NORMAL(getpid) 85*cfc1d11dSguenther 86*cfc1d11dSguenther PROTO_STD_DEPRECATED(x) Standard C symbols that we don't want to use 87*cfc1d11dSguenther This just marks the symbol as deprecated, with no renaming. 88*cfc1d11dSguenther ex: PROTO_STD_DEPRECATED(strcpy) 89*cfc1d11dSguenther 90*cfc1d11dSguenther PROTO_DEPRECATED(x) Symbols not in ISO C that we don't want to use 91*cfc1d11dSguenther This marks the symbol as both weak and deprecated, with no renaming 92*cfc1d11dSguenther ex: PROTO_DEPRECATED(creat) 93*cfc1d11dSguenther 94*cfc1d11dSguenther PROTO_CANCEL(x) Functions that have cancellation wrappers 95*cfc1d11dSguenther Like PROTO_NORMAL(x), but also declares _libc_x_cancel 96*cfc1d11dSguenther ex: PROTO_CANCEL(wait4) 97*cfc1d11dSguenther 98*cfc1d11dSguenther PROTO_WRAP(x) Functions that have wrappers for other reasons 99*cfc1d11dSguenther Like PROTO_NORMAL(x), but also declares _libc_x_wrap. Internal 100*cfc1d11dSguenther calls that want the wrapper's processing should invoke WRAP(x)(...) 101*cfc1d11dSguenther ex: PROTO_WRAP(sigaction) 102*cfc1d11dSguenther 103*cfc1d11dSguenther 104*cfc1d11dSguentherFinally, to create the expected aliases, we use these in the .c files 105*cfc1d11dSguentherwhere the definitions are: 106*cfc1d11dSguenther DEF_STRONG(x) Symbols reserved to or specified by ISO C 107*cfc1d11dSguenther This defines x as a strong alias for _libc_x; this must only 108*cfc1d11dSguenther be used for symbols that are reserved by the C standard 109*cfc1d11dSguenther (or reserved in the external identifier namespace). 110*cfc1d11dSguenther Matches with PROTO_NORMAL() 111*cfc1d11dSguenther ex: DEF_STRONG(fopen) 112*cfc1d11dSguenther 113*cfc1d11dSguenther DEF_WEAK(x) Symbols used internally and not in ISO C 114*cfc1d11dSguenther This defines x as a weak alias for _libc_x 115*cfc1d11dSguenther Matches with PROTO_NORMAL() 116*cfc1d11dSguenther ex: DEF_WEAK(lseek) 117*cfc1d11dSguenther 118*cfc1d11dSguenther DEF_CANCEL(x) Symbols that have a cancellation wrapper 119*cfc1d11dSguenther This defines x as a weak alias for _libc_x_cancel. 120*cfc1d11dSguenther Matches with PROTO_CANCEL() 121*cfc1d11dSguenther ex: DEF_CANCEL(read) 122*cfc1d11dSguenther 123*cfc1d11dSguenther DEF_WRAP(x) 124*cfc1d11dSguenther This defines x as a weak alias for _libc_x_wrap. 125*cfc1d11dSguenther Matches with PROTO_WRAP() 126*cfc1d11dSguenther ex: DEF_WRAP(ptrace) 127*cfc1d11dSguenther 128*cfc1d11dSguenther MAKE_CLONE(dst, src) Symbols that are exact clones of other symbols 129*cfc1d11dSguenther This declares _libc_dst as being the same type as dst, and makes 130*cfc1d11dSguenther _libc_dst a strong, hidden alias for _libc_src. You still need to 131*cfc1d11dSguenther DEF_STRONG(dst) or DEF_WEAK(dst) to alias dst itself 132*cfc1d11dSguenther ex: MAKE_CLONE(SHA224Pad, SHA256Pad) 133*cfc1d11dSguenther 134