summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libc/include/DETAILS133
-rw-r--r--lib/libc/include/namespace.h115
2 files changed, 136 insertions, 112 deletions
diff --git a/lib/libc/include/DETAILS b/lib/libc/include/DETAILS
new file mode 100644
index 00000000000..6382cc1c0d7
--- /dev/null
+++ b/lib/libc/include/DETAILS
@@ -0,0 +1,133 @@
+The goal: calls from inside libc to other libc functions should
+ * not be overridable (except for the malloc family), and
+ * not have pointless inefficiencies.
+
+To achieve this, we arrange that all these internal call be via
+identifiers that are of hidden visibility and--to avoid confusion
+and work correctly in static executables--are in the reserved
+namespace.
+
+This document describes the details of the naming scheme and how
+it is implemented.
+
+I've chosen a prefix of underbar-libc-underbar ("_libc_") for this.
+These are not declared directly; instead, the gcc "asm labels"
+extension is used to rename the function.
+
+We need many of the symbols to be weak in *static* builds, but they
+can be strong in the dynamic library, as there's a natural precedence
+from the search order there. When the descriptions below say a
+name is "weak", that is only necessary for the static library and
+not for the shared library. Note: use defined(PIC) to recognize
+when compiling the shared objects: some archs define __PIC__ *all*
+the time.
+
+---------
+
+For syscalls which are not cancellation points, such as getpid(),
+the identifiers are just:
+ _libc_getpid hidden alias, for use internal to libc only
+ _thread_sys_getpid global name, for use outside libc only
+ getpid weak alias, for use outside libc only
+
+For syscalls which are cancellation points, such as wait4(), there
+are identifiers that do not provide cancellation:
+ _libc_wait4 hidden alias, for use internal to libc only
+ _thread_sys_wait4 global name, for use outside libc only
+...and identifiers that do provide cancellation:
+ wait4 weak alias, for general use
+ _libc_wait4_cancel hidden name, for use internal to libc only
+Inside libc, the bare name ("wait4") binds to the version *with*
+cancellation. If it's necessary to use the syscall without doing
+cancellation it can be obtained by calling HIDDEN(x) instead of
+just x.
+
+Some other calls need to be wrapped for reasons other than cancellation,
+such as to provide functionality beyond the underlying syscall (e.g.,
+ptrace). For these, there are identifiers for the raw call, without
+the wrapping:
+ _libc_ptrace hidden alias, for use internal to libc only
+ _thread_sys_ptrace global name, for use outside libc only
+...and identifiers that do provide the libc wrapping:
+ ptrace weak alias, for general use
+ _libc_ptrace_wrap hidden name, for use internal to libc only
+Inside libc, the bare name ("ptrace") binds to the wrapper; if
+the raw version is necessary it can be obtained by calling HIDDEN(x)
+instead of just x.
+
+For syscalls implemented in ASM, the aliases of the raw syscall stub
+are provided by the ASM macros. Of the macros used by sys/Makefile.inc:
+RSYSCALL(), PSEUDO(), and PSEUDO_NOERROR() generate all three names
+(ala getpid() above), while RSYSCALL_HIDDEN() generates just the
+_thread_sys_x and _libc_x names.
+
+
+
+By using gcc's "asm label" extension, we can usually avoid having
+to type those prefixes in the .h and .c files. However, for those
+cases where a non-default binding is necessary we can use these macros
+to get the desired identifier:
+
+ CANCEL(x)
+ This expands to the internal, hidden name of a cancellation
+ wrapper: _libc_x_cancel. ex: CANCEL(fsync)(fd)
+
+ WRAP(x)
+ This expands to the internal, hidden name of a non-cancellation
+ wrapper: _libc_x_wrap. ex: WRAP(sigprocmask)(set)
+
+
+In order to actually set up the desired asm labels, we use these in
+the internal .h files:
+ PROTO_NORMAL(x) Symbols used both internally and externally
+ This makes gcc convert use of x to use _libc_x instead
+ ex: PROTO_NORMAL(getpid)
+
+ PROTO_STD_DEPRECATED(x) Standard C symbols that we don't want to use
+ This just marks the symbol as deprecated, with no renaming.
+ ex: PROTO_STD_DEPRECATED(strcpy)
+
+ PROTO_DEPRECATED(x) Symbols not in ISO C that we don't want to use
+ This marks the symbol as both weak and deprecated, with no renaming
+ ex: PROTO_DEPRECATED(creat)
+
+ PROTO_CANCEL(x) Functions that have cancellation wrappers
+ Like PROTO_NORMAL(x), but also declares _libc_x_cancel
+ ex: PROTO_CANCEL(wait4)
+
+ PROTO_WRAP(x) Functions that have wrappers for other reasons
+ Like PROTO_NORMAL(x), but also declares _libc_x_wrap. Internal
+ calls that want the wrapper's processing should invoke WRAP(x)(...)
+ ex: PROTO_WRAP(sigaction)
+
+
+Finally, to create the expected aliases, we use these in the .c files
+where the definitions are:
+ DEF_STRONG(x) Symbols reserved to or specified by ISO C
+ This defines x as a strong alias for _libc_x; this must only
+ be used for symbols that are reserved by the C standard
+ (or reserved in the external identifier namespace).
+ Matches with PROTO_NORMAL()
+ ex: DEF_STRONG(fopen)
+
+ DEF_WEAK(x) Symbols used internally and not in ISO C
+ This defines x as a weak alias for _libc_x
+ Matches with PROTO_NORMAL()
+ ex: DEF_WEAK(lseek)
+
+ DEF_CANCEL(x) Symbols that have a cancellation wrapper
+ This defines x as a weak alias for _libc_x_cancel.
+ Matches with PROTO_CANCEL()
+ ex: DEF_CANCEL(read)
+
+ DEF_WRAP(x)
+ This defines x as a weak alias for _libc_x_wrap.
+ Matches with PROTO_WRAP()
+ ex: DEF_WRAP(ptrace)
+
+ MAKE_CLONE(dst, src) Symbols that are exact clones of other symbols
+ This declares _libc_dst as being the same type as dst, and makes
+ _libc_dst a strong, hidden alias for _libc_src. You still need to
+ DEF_STRONG(dst) or DEF_WEAK(dst) to alias dst itself
+ ex: MAKE_CLONE(SHA224Pad, SHA256Pad)
+
diff --git a/lib/libc/include/namespace.h b/lib/libc/include/namespace.h
index 60766afc0b9..79692af0bca 100644
--- a/lib/libc/include/namespace.h
+++ b/lib/libc/include/namespace.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: namespace.h,v 1.12 2018/01/18 08:23:44 guenther Exp $ */
+/* $OpenBSD: namespace.h,v 1.13 2019/05/13 20:00:32 guenther Exp $ */
#ifndef _LIBC_NAMESPACE_H_
#define _LIBC_NAMESPACE_H_
@@ -20,117 +20,8 @@
*/
/*
- * The goal: calls from inside libc to other libc functions should be via
- * identifiers that are of hidden visibility and--to avoid confusion--are
- * in the reserved namespace. By doing this these calls are protected
- * from overriding by applications and on many platforms can avoid creation
- * or use of GOT or PLT entries. I've chosen a prefix of underbar-C-underbar
- * ("_libc_") for this. These will not be declared directly; instead, the
- * gcc "asm labels" extension will be used rename the function.
- *
- * For syscalls which are cancellation points, such as wait4(), there
- * are identifiers that do not provide cancellation:
- * _libc_wait4 hidden alias, for use internal to libc only
- * _thread_sys_wait4 global name, for use outside libc only
- * ...and identifiers that do provide cancellation:
- * wait4 weak alias, for general use
- * _libc_wait4_cancel hidden alias, for use internal to libc only
- * Inside libc, the bare name ("wait4") binds to the version *without*
- * cancellation; the few times where cancellation is desired it can be
- * obtained by calling CANCEL(x) instead of just x.
- *
- * Some other calls need to be wrapped for reasons other than cancellation,
- * such as to provide functionality beyond the underlying syscall (e.g.,
- * sigaction). For these, there are identifiers for the raw call, without
- * the wrapping:
- * _libc_sigaction hidden alias, for use internal to libc only
- * _thread_sys_sigaction global name, for use outside libc only
- * ...and identifiers that do provide the libc wrapping:
- * sigaction weak alias, for general use
- * _libc_sigaction_wrap hidden alias, for use internal to libc only
- * Inside libc, the bare name ("sigaction") binds to the wrapper; when the
- * raw version is necessary it can be obtained by calling HIDDEN(x) instead of
- * just x.
- *
- * For syscalls which are not cancellation points, such as getpid(),
- * the identifiers are just:
- * _libc_getpid hidden alias, for use internal to libc only
- * _thread_sys_getpid global name, for use outside libc only
- * getpid weak alias, for use outside libc only
- *
- * By using gcc's "asm label" extension, we can usually avoid having
- * to type those prefixes in the .h and .c files. However, for those
- * cases where a non-default binding is necessary we can use these macros
- * to get the desired identifier:
- *
- * CANCEL(x)
- * This expands to the internal, hidden name of a cancellation
- * wrapper: _libc_x_cancel. ex: CANCEL(fsync)(fd)
- *
- * WRAP(x)
- * This expands to the internal, hidden name of a non-cancellation
- * wrapper: _libc_x_wrap. ex: WRAP(sigprocmask)(set)
- *
- *
- * In order to actually set up the desired asm labels, we use these in
- * the internal .h files:
- * PROTO_NORMAL(x) Symbols used both internally and externally
- * This makes gcc convert use of x to use _libc_x instead
- * ex: PROTO_NORMAL(getpid)
- *
- * PROTO_STD_DEPRECATED(x) Standard C symbols that we don't want to use
- * This just marks the symbol as deprecated, with no renaming.
- * ex: PROTO_STD_DEPRECATED(strcpy)
- *
- * PROTO_DEPRECATED(x) Symbols not in ISO C that we don't want to use
- * This marks the symbol as both weak and deprecated, with no renaming
- * ex: PROTO_DEPRECATED(creat)
- *
- * PROTO_CANCEL(x) Functions that have cancellation wrappers
- * Like PROTO_NORMAL(x), but also declares _libc_x_cancel
- * ex: PROTO_CANCEL(wait4)
- *
- * PROTO_WRAP(x) Functions that have wrappers for other reasons
- * Like PROTO_NORMAL(x), but also declares _libc_x_wrap. Internal
- * calls that want the wrapper's processing should invoke WRAP(x)(...)
- * ex: PROTO_WRAP(sigaction)
- *
- *
- * Finally, to create the expected aliases, we use these in the .c files
- * where the definitions are:
- * DEF_STRONG(x) Symbols reserved to or specified by ISO C
- * This defines x as a strong alias for _libc_x; this must only
- * be used for symbols that are reserved by the C standard
- * (or reserved in the external identifier namespace).
- * Matches with PROTO_NORMAL()
- * ex: DEF_STRONG(fopen)
- *
- * DEF_WEAK(x) Symbols used internally and not in ISO C
- * This defines x as a weak alias for _libc_x
- * Matches with PROTO_NORMAL()
- * ex: DEF_WEAK(lseek)
- *
- * DEF_CANCEL(x) Symbols that have a cancellation wrapper
- * This defines x as a weak alias for _libc_x_cancel.
- * Matches with PROTO_CANCEL()
- * ex: DEF_CANCEL(read)
- *
- * DEF_WRAP(x)
- * This defines x as a weak alias for _libc_x_wrap.
- * Matches with PROTO_WRAP()
- * ex: DEF_WRAP(sigaction)
- *
- * DEF_SYS(x)
- * This defines _thread_sys_x as a strong alias for _libc_x. This should
- * only be needed for syscalls that have C instead of asm stubs.
- * Matches with PROTO_NORMAL(), PROTO_CANCEL(), or PROTO_WRAP()
- * ex: DEF_SYS(pread)
- *
- * MAKE_CLONE(dst, src) Symbols that are exact clones of other symbols
- * This declares _libc_dst as being the same type as dst, and makes
- * _libc_dst a strong, hidden alias for _libc_src. You still need to
- * DEF_STRONG(dst) or DEF_WEAK(dst) to alias dst itself
- * ex: MAKE_CLONE(SHA224Pad, SHA256Pad)
+ * For explanations of how to use these, see README
+ * For explanations of why we use them and how they work, see DETAILS
*/
#include <sys/cdefs.h> /* for __dso_hidden and __{weak,strong}_alias */