1adc7e4ecSguentherSo you want to add an interface to libc... 2adc7e4ecSguenther 3adc7e4ecSguentherCASE I: internal symbols 4adc7e4ecSguenther 5adc7e4ecSguenther A) used in a single file 6adc7e4ecSguenther Duh: use whatever name you want and make it static 7adc7e4ecSguenther 8adc7e4ecSguenther B) used in multiple files 9adc7e4ecSguenther Give it a name in the implementation namespace (leading underbar) 10adc7e4ecSguenther and declare it in a __{BEGIN,END}_HIDDEN_DECLS block in a .h 11adc7e4ecSguenther file inside libc. If it's used in just a single subdir of 12adc7e4ecSguenther libc *and* that subdir has an appropriate .h file in it, then 13adc7e4ecSguenther declare it there. 14adc7e4ecSguenther Example: stdio/local.h. 15adc7e4ecSguenther Otherwise, declare it in one of the hidden/* files. 16adc7e4ecSguenther Example: _mktemp() in hidden/stdio.h 17adc7e4ecSguenther 18adc7e4ecSguentherCASE II: external symbols 19adc7e4ecSguenther 20adc7e4ecSguenther First of all, add your symbol to Symbols.list. MD symbols go in 21adc7e4ecSguenther arch/*/Symbols.list (shock, I know) 22adc7e4ecSguenther 23adc7e4ecSguenther Declare your function in the appropriate header. It almost certainly 24adc7e4ecSguenther should be in a public header installed under /usr/include/. Exceptions 25adc7e4ecSguenther are symbols that are just shared between libc and libpthread/csu/ld.so 26adc7e4ecSguenther which are only declared in libc/include/* or just in each .c file. 27adc7e4ecSguenther 28adc7e4ecSguenther A) objects (variables) 29adc7e4ecSguenther That's it, you're done. 30adc7e4ecSguenther 31*8e2ed19fSguenther 32adc7e4ecSguenther B) plain C functions (not syscalls) 33adc7e4ecSguenther 1) functions that are *not* called from inside libc 34adc7e4ecSguenther 35adc7e4ecSguenther If this function is specified in the ISO C standard or its 36adc7e4ecSguenther name begins with an underbar, then in the hidden/* version 37adc7e4ecSguenther of the header where you declared the function, add this line: 38adc7e4ecSguenther PROTO_STD_DEPRECATED(your_function_name); 39adc7e4ecSguenther 40adc7e4ecSguenther Otherwise, this is *not* a function specified in the ISO C 41adc7e4ecSguenther standard and its name begins with a letter. In the hidden/* 42adc7e4ecSguenther version of the header where you declared the function, add 43adc7e4ecSguenther this line: 44adc7e4ecSguenther PROTO_DEPRECATED(your_function_name); 45adc7e4ecSguenther 46*8e2ed19fSguenther Note: the "DEPRECATED" suffix is about a detail of 47*8e2ed19fSguenther how the macros work and has nothing to do with whether the 48*8e2ed19fSguenther function itself is a Good Thing vs deprecated. 49*8e2ed19fSguenther 50adc7e4ecSguenther 2) functions that are called from inside libc 51adc7e4ecSguenther 52adc7e4ecSguenther In the hidden/* version of the header where you declared 53adc7e4ecSguenther the function, add this line: 54adc7e4ecSguenther PROTO_NORMAL(your_function_name); 55adc7e4ecSguenther 56adc7e4ecSguenther Then, in the .c file(s) where the function is defined: 57adc7e4ecSguenther - if the function is specified in the ISO C standard or 58adc7e4ecSguenther its name begins with an underbar, add 59adc7e4ecSguenther DEF_STRONG(your_function_name); 60adc7e4ecSguenther 61adc7e4ecSguenther - otherwise, add: 62adc7e4ecSguenther DEF_WEAK(your_function_name); 63adc7e4ecSguenther 64adc7e4ecSguenther 65*8e2ed19fSguenther C) syscalls that don't require any wrapping 66adc7e4ecSguenther 67adc7e4ecSguenther In the hidden/* version of the header where you declared the 68adc7e4ecSguenther function, add this line: 69adc7e4ecSguenther PROTO_NORMAL(your_function_name); 70adc7e4ecSguenther 71*8e2ed19fSguenther Generate the stub by adding it to the ASM variable in 72*8e2ed19fSguenther libc/sys/Makefile.inc 73*8e2ed19fSguenther 74*8e2ed19fSguenther 75*8e2ed19fSguenther D) syscalls that require cancellation or similar wrappers that don't 76*8e2ed19fSguenther change the function signature 77*8e2ed19fSguenther 78*8e2ed19fSguenther Generate the stub by adding it to the HIDDEN (*not* ASM!) 79*8e2ed19fSguenther variable in libc/sys/Makefile.inc 80*8e2ed19fSguenther 81*8e2ed19fSguenther In the hidden/* version of the header where you declared the 82*8e2ed19fSguenther function, add this line: 83*8e2ed19fSguenther PROTO_WRAP(your_function_name); 84*8e2ed19fSguenther 85*8e2ed19fSguenther The wrapper function should be defined in 86*8e2ed19fSguenther libc/sys/w_your_function_name.c 87*8e2ed19fSguenther which should define WRAP(your_function_name) and follow it 88*8e2ed19fSguenther with DEF_WRAP(your_function_name). Look at libc/sys/w_sigaction.c 89*8e2ed19fSguenther for an example. 90*8e2ed19fSguenther 91*8e2ed19fSguenther By default, libc code that calls your_function_name() will get 92*8e2ed19fSguenther the real syscall and *not* the wrapper. libc calls that need 93*8e2ed19fSguenther to go through the wrapper should invoke WRAP(your_function_name) 94*8e2ed19fSguenther 95*8e2ed19fSguenther 96*8e2ed19fSguenther E) syscalls that require libc wrappers for other reasons 97*8e2ed19fSguenther First of all, make sure this really is the Right Thing. Talk 98*8e2ed19fSguenther with kettenis, deraadt, millert, and guenther. 99*8e2ed19fSguenther 100*8e2ed19fSguenther If the actual syscall doesn't have the same calling convention 101*8e2ed19fSguenther as the C interface, then maybe it shouldn't be exported at all 102*8e2ed19fSguenther and you should just have an ASM stub, like SYS___tfork --> 103*8e2ed19fSguenther __tfork_thread() or SYS_break --> brk() and sbrk(). If it 104*8e2ed19fSguenther _could_ be called from C, then give the syscall a name different 105*8e2ed19fSguenther from the C API. Syscalls that fail this for historical reasons 106*8e2ed19fSguenther (e.g., exit == _exit(2)) are generated with PSEUDO/PSEUDO_NOERR 107*8e2ed19fSguenther in libc/sys/Makefile.inc, so the ASM stub has a leading underbar. 108*8e2ed19fSguenther Go read gen/getlogin.c rev 1.13 for an example of how to do 109*8e2ed19fSguenther this, but don't pick this option, really. 110*8e2ed19fSguenther 111