From 20231f779df38e1bb04133af8443db2ad1d8d17f Mon Sep 17 00:00:00 2001 From: Philip Guenther Date: Sat, 14 Nov 2015 07:11:29 +0000 Subject: Give clear directions on how to declare, PROTO_*() and DEF_*() new symbols prodded by deraadt@ --- lib/libc/include/README | 97 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 lib/libc/include/README (limited to 'lib/libc/include') diff --git a/lib/libc/include/README b/lib/libc/include/README new file mode 100644 index 00000000000..6410072c963 --- /dev/null +++ b/lib/libc/include/README @@ -0,0 +1,97 @@ +So you want to add an interface to libc... + +CASE I: internal symbols + + A) used in a single file + Duh: use whatever name you want and make it static + + B) used in multiple files + Give it a name in the implementation namespace (leading underbar) + and declare it in a __{BEGIN,END}_HIDDEN_DECLS block in a .h + file inside libc. If it's used in just a single subdir of + libc *and* that subdir has an appropriate .h file in it, then + declare it there. + Example: stdio/local.h. + Otherwise, declare it in one of the hidden/* files. + Example: _mktemp() in hidden/stdio.h + +CASE II: external symbols + + First of all, add your symbol to Symbols.list. MD symbols go in + arch/*/Symbols.list (shock, I know) + + Declare your function in the appropriate header. It almost certainly + should be in a public header installed under /usr/include/. Exceptions + are symbols that are just shared between libc and libpthread/csu/ld.so + which are only declared in libc/include/* or just in each .c file. + + A) objects (variables) + That's it, you're done. + + B) plain C functions (not syscalls) + 1) functions that are *not* called from inside libc + + If this function is specified in the ISO C standard or its + name begins with an underbar, then in the hidden/* version + of the header where you declared the function, add this line: + PROTO_STD_DEPRECATED(your_function_name); + + Otherwise, this is *not* a function specified in the ISO C + standard and its name begins with a letter. In the hidden/* + version of the header where you declared the function, add + this line: + PROTO_DEPRECATED(your_function_name); + + 2) functions that are called from inside libc + + In the hidden/* version of the header where you declared + the function, add this line: + PROTO_NORMAL(your_function_name); + + Then, in the .c file(s) where the function is defined: + - if the function is specified in the ISO C standard or + its name begins with an underbar, add + DEF_STRONG(your_function_name); + + - otherwise, add: + DEF_WEAK(your_function_name); + + C) syscalls that require cancellation or other libpthread wrappers + You're done in libc, but go to libpthread and add the wrapper there. + + D) syscalls that require libc wrappers for other reasons + First of all, make sure this really is the Right Thing. Talk + with kettenis, deraadt, miod, and guenther. + + 1) If the actual syscall doesn't have the same calling convention + as the C interface, then maybe it shouldn't be exported at + all and you should just have an ASM stub, like SYS___tfork + --> __tfork_thread() or SYS_break --> brk() and sbrk(). If + it _could_ be called from C, then give the syscall a name + different from the C API. Syscalls that fail this for + historical reasons (e.g., getlogin) are generated with + PSEUDO in libc/sys/Makefile.inc, so the ASM stub has a + leading underbar. Go read gen/getlogin.c for an example + of how to do this. + + 2) Otherwise, you're sane and have a syscall like sigaction() + which requires a wrapper but whose syscall API is the same + as the C API. Then: + - generate the ASM stub with HIDDEN in libc/sys/Makefile.inc + - in the proper hidden/*.h file add + PROTO_WRAP(your_function_name) + - the wrapper function should be defined in + libc/sys/w_your_function_name.c + which should define WRAP(your_function_name) and + follow it with DEF_WRAP(your_function_name). Look at + libc/sys/w_sigaction.c for an example. + - by default, libc code that calls your_function_name() + will get the real syscall and *not* the wrapper. libc + calls that needd to go through the wrapper should invoke + WRAP(your_function_name) + + E) syscalls that don't require any wrapping + In the hidden/* version of the header where you declared the + function, add this line: + PROTO_NORMAL(your_function_name); + -- cgit v1.2.3