summaryrefslogtreecommitdiff
path: root/lib/libc/include
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2015-11-14 07:11:29 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2015-11-14 07:11:29 +0000
commit20231f779df38e1bb04133af8443db2ad1d8d17f (patch)
tree7944fc9042ccd6da79ab71c80b7bf5232bcc8104 /lib/libc/include
parent1ec84b09e9a6b35048e8c514f34afe1eaaf152ff (diff)
Give clear directions on how to declare, PROTO_*() and DEF_*() new symbols
prodded by deraadt@
Diffstat (limited to 'lib/libc/include')
-rw-r--r--lib/libc/include/README97
1 files changed, 97 insertions, 0 deletions
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);
+