Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 20 May 2019 19:12:29 +0000 (UTC)
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r348003 - head/share/man/man9
Message-ID:  <201905201912.x4KJCTUT012079@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: markj
Date: Mon May 20 19:12:29 2019
New Revision: 348003
URL: https://svnweb.freebsd.org/changeset/base/348003

Log:
  Add a man page for DEFINE_IFUNC.
  
  Reviewed by:	kib
  Discussed with:	emaste
  MFC after:	2 weeks
  Event:		Waterloo Hackathon 2019
  Differential Revision:	https://reviews.freebsd.org/D20310

Added:
  head/share/man/man9/DEFINE_IFUNC.9   (contents, props changed)

Added: head/share/man/man9/DEFINE_IFUNC.9
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/share/man/man9/DEFINE_IFUNC.9	Mon May 20 19:12:29 2019	(r348003)
@@ -0,0 +1,143 @@
+.\" Copyright (c) 2019 The FreeBSD Foundation
+.\"
+.\" This documentation was written by Mark Johnston <markj@FreeBSD.org>
+.\" under sponsorship from the FreeBSD Foundation.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 18, 2019
+.Dt DEFINE_IFUNC 9
+.Os
+.Sh NAME
+.Nm DEFINE_IFUNC
+.Nd define a kernel function with an implementation selected at run-time
+.Sh SYNOPSIS
+.In machine/ifunc.h
+.Fn DEFINE_IFUNC qual ret_type name args
+.Sh DESCRIPTION
+ifuncs are a linker feature which allows the programmer to define functions
+whose implementation is selected at boot-time or module load-time.
+The
+.Nm
+macro can be used to define an ifunc.
+The selection is performed by a resolver function, which returns a pointer
+to the selected function.
+ifunc resolvers are invoked very early during the machine-dependent
+initialization routine, or at load time for dynamically loaded modules.
+Resolution must occur before the first call to an ifunc.
+ifunc resolution is performed after CPU features are enumerated and after the
+kernel's environment is initialized.
+The typical use-case for an ifunc is a routine whose behavior depends on
+optional CPU features.
+For example, newer generations of a given CPU architecture may provide an
+instruction to optimize a common operation.
+To avoid the overhead of testing for the CPU feature each time the operation
+is performed, an ifunc can be used to provide two implementations for the
+operation: one targeting platforms with the extra instruction, and one
+for older platforms.
+.Pp
+Because
+.Nm
+is a macro that defines a dynamically typed function, its usage looks somewhat
+unusual.
+The
+.Ar qual
+parameter is a list of zero or more C function qualifiers to be applied to the
+ifunc.
+This parameter is typically empty or the
+.Dv static
+qualifier.
+.Ar ret_type
+is the return type of the ifunc.
+.Ar name
+is the name of the ifunc.
+.Ar args
+is a parenthesized, comma-separated list of the parameter types of the function,
+as they would appear in a C function declaration.
+.Pp
+The
+.Nm
+usage must be followed by the resolver function body.
+The resolver must return a function with return type
+.Ar ret_type
+and parameter types
+.Ar args .
+The resolver function is defined with the
+.Ql resolver
+gcc-style function attribute, causing the corresponding
+.Xr elf 5
+function symbol to be of type
+.Dv STT_GNU_IFUNC
+instead of
+.Dv STT_FUNC .
+The kernel linker invokes the resolver to process relocations targeting ifunc
+calls and PLT entries referencing such symbols.
+.Sh EXAMPLES
+ifunc resolvers are executed early during boot, before most kernel facilities
+are available.
+They are effectively limited to checking CPU feature flags and tunables.
+.Bd -literal
+static size_t
+fast_strlen(const char *s __unused)
+{
+	size_t len;
+
+	/* Fast, but may not be correct in all cases. */
+	__asm("movq $42,%0\\n" : "=r" (len));
+	return (len);
+}
+
+static size_t
+slow_strlen(const char *s)
+{
+	const char *t;
+
+	for (t = s; *t != '\\0'; t++);
+	return (t - s);
+}
+
+DEFINE_IFUNC(, size_t, strlen, (const char *))
+{
+	int enabled;
+
+	enabled = 1;
+	TUNABLE_INT_FETCH("debug.use_fast_strlen", &enabled);
+	if (enabled && (cpu_features & CPUID_FAST_STRLEN) != 0)
+		return (fast_strlen);
+	else
+		return (slow_strlen);
+}
+.Ed
+.Pp
+This defines a
+.Fn strlen
+function with an optimized implementation for CPUs that advertise support.
+.Sh SEE ALSO
+.Xr elf 5
+.Sh NOTES
+ifuncs are not supported on all architectures.
+They require both toolchain support, to emit function symbols of type
+.Dv STT_GNU_IFUNC ,
+and kernel linker support to invoke ifunc resolvers during boot or
+during module load.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201905201912.x4KJCTUT012079>