Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Dmitry Baryshkov
nettle
Commits
323a2c0d
Commit
323a2c0d
authored
Jan 19, 2015
by
Niels Möller
Browse files
Moved fat declarations and macros to fat-setup.h.
parent
48d320c0
Changes
4
Hide whitespace changes
Inline
Side-by-side
ChangeLog
View file @
323a2c0d
2015-01-19 Niels Möller <nisse@lysator.liu.se>
* Makefile.in (DISTFILES): Added fat-setup.h.
* fat-setup.h: New file, declarations moved from...
* fat-x86_64.c: ... old location
2015-01-17 Niels Möller <nisse@lysator.liu.se>
* fat-x86_64.c (DECLARE_FAT_FUNC, DEFINE_FAT_FUNC)
...
...
Makefile.in
View file @
323a2c0d
...
...
@@ -219,7 +219,7 @@ DISTFILES = $(SOURCES) $(HEADERS) getopt.h getopt_int.h \
aes-internal.h camellia-internal.h serpent-internal.h
\
cast128_sboxes.h desinfo.h desCode.h
\
memxor-internal.h nettle-internal.h nettle-write.h
\
gmp-glue.h ecc-internal.h
\
gmp-glue.h ecc-internal.h
fat-setup.h
\
mini-gmp.h mini-gmp.c asm.m4
\
nettle.texinfo nettle.info nettle.html nettle.pdf sha-example.c
...
...
fat-setup.h
0 → 100644
View file @
323a2c0d
/* fat-setup.h
Copyright (C) 2015 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
/* Fat library initialization works as follows. The main function is
fat_init. It tries to do initialization only once, but since it is
idempotent and pointer updates are atomic on x86_64, there's no
harm if it is in some cases called multiple times from several
threads.
The fat_init function checks the cpuid flags, and sets function
pointers, e.g, _nettle_aes_encrypt_vec, to point to the appropriate
implementation.
To get everything hooked in, we use a belt-and-suspenders approach.
We try to register fat_init as a constructor function to be called
at load time. If this is unavailable or non-working, we instead
arrange fat_init to be called lazily.
For the actual indirection, there are two cases.
If ifunc support is available, function pointers are statically
initialized to NULL, and we register resolver functions, e.g.,
_nettle_aes_encrypt_resolve, which call fat_init, and then return
the function pointer, e.g., the value of _nettle_aes_encrypt_vec.
If ifunc is not available, we have to define a wrapper function to
jump via the function pointer. (FIXME: For internal calls, we could
do this as a macro). We statically initialize each function pointer
to point to a special initialization function, e.g.,
_nettle_aes_encrypt_init, which calls fat_init, and then invokes
the right function. This way, all pointers are setup correctly at
the first call to any fat function.
*/
#if HAVE_GCC_ATTRIBUTE
# define CONSTRUCTOR __attribute__ ((constructor))
#else
# define CONSTRUCTOR
# if defined (__sun)
# pragma init(fat_init)
# endif
#endif
#define ENV_VERBOSE "NETTLE_FAT_VERBOSE"
/* DECLARE_FAT_FUNC(name, ftype)
*
* name is the public function, e.g., _nettle_aes_encrypt.
* ftype is its type, e.g., aes_crypt_internal_func.
*
* DECLARE_FAT_VAR(name, type, var)
*
* name is name without _nettle prefix.
* type is its type.
* var is the variant, used as a suffix on the symbol name.
*
* DEFINE_FAT_FUNC(name, rtype, prototype, args)
*
* name is the public function.
* rtype its return type.
* prototype is the list of formal arguments, with types.
* args contain the argument list without any types.
*/
#if HAVE_LINK_IFUNC
#define IFUNC(resolve) __attribute__ ((ifunc (resolve)))
#define DECLARE_FAT_FUNC(name, ftype) \
ftype name IFUNC(#name"_resolve"); \
static ftype *name##_vec = NULL;
#define DEFINE_FAT_FUNC(name, rtype, prototype, args) \
static void_func * name##_resolve(void) \
{ \
if (getenv (ENV_VERBOSE)) \
fprintf (stderr, "libnettle: "#name"_resolve\n"); \
fat_init(); \
return (void_func *) name##_vec; \
}
#else
/* !HAVE_LINK_IFUNC */
#define DECLARE_FAT_FUNC(name, ftype) \
ftype name; \
static ftype name##_init; \
static ftype *name##_vec = name##_init;
#define DEFINE_FAT_FUNC(name, rtype, prototype, args) \
rtype name prototype \
{ \
return name##_vec args; \
} \
static rtype name##_init prototype { \
if (getenv (ENV_VERBOSE)) \
fprintf (stderr, "libnettle: "#name"_init\n"); \
fat_init(); \
assert (name##_vec != name##_init); \
return name##_vec args; \
}
#endif
/* !HAVE_LINK_IFUNC */
#define DECLARE_FAT_FUNC_VAR(name, type, var) \
type _nettle_##name##_##var;
typedef
void
void_func
(
void
);
typedef
void
aes_crypt_internal_func
(
unsigned
rounds
,
const
uint32_t
*
keys
,
const
struct
aes_table
*
T
,
size_t
length
,
uint8_t
*
dst
,
const
uint8_t
*
src
);
typedef
void
*
(
memxor_func
)(
void
*
dst
,
const
void
*
src
,
size_t
n
);
fat-x86_64.c
View file @
323a2c0d
...
...
@@ -41,121 +41,11 @@
#include
"nettle-types.h"
#include
"aes-internal.h"
/* Fat library initialization works as follows. The main function is
fat_init. It tries to do initialization only once, but since it is
idempotent and pointer updates are atomic on x86_64, there's no
harm if it is in some cases called multiple times from several
threads.
The fat_init function checks the cpuid flags, and sets function
pointers, e.g, _nettle_aes_encrypt_vec, to point to the appropriate
implementation.
To get everything hooked in, we use a belt-and-suspenders approach.
We try to register fat_init as a constructor function to be called
at load time. If this is unavailable or non-working, we instead
arrange fat_init to be called lazily.
For the actual indirection, there are two cases.
If ifunc support is available, function pointers are statically
initialized to NULL, and we register resolver functions, e.g.,
_nettle_aes_encrypt_resolve, which call fat_init, and then return
the function pointer, e.g., the value of _nettle_aes_encrypt_vec.
If ifunc is not available, we have to define a wrapper function to
jump via the function pointer. (FIXME: For internal calls, we could
do this as a macro). We statically initialize each function pointer
to point to a special initialization function, e.g.,
_nettle_aes_encrypt_init, which calls fat_init, and then invokes
the right function. This way, all pointers are setup correctly at
the first call to any fat function.
*/
#if HAVE_LINK_IFUNC
# define IFUNC(resolve) __attribute__ ((ifunc (resolve)))
# define vec_init(f) NULL
# define FAT_BOILERPLATE()
#else
# define IFUNC(resolve)
# define vec_init(f) f##_init
#endif
#if HAVE_GCC_ATTRIBUTE
# define CONSTRUCTOR __attribute__ ((constructor))
#else
# define CONSTRUCTOR
# if defined (__sun)
# pragma init(fat_init)
# endif
#endif
/* DECLARE_FAT_FUNC(name, ftype)
*
* name is the public function, e.g., _nettle_aes_encrypt.
* ftype is its type, e.g., aes_crypt_internal_func.
*
* DECLARE_FAT_VAR(name, type, var)
*
* name is name without _nettle prefix.
* type is its type.
* var is the variant, used as a suffix on the symbol name.
*
* DEFINE_FAT_FUNC(name, rtype, prototype, args)
*
* name is the public function.
* rtype its return type.
* prototype is the list of formal arguments, with types.
* args contain the argument list without any types.
*/
#if HAVE_LINK_IFUNC
#define DECLARE_FAT_FUNC(name, ftype) \
ftype name IFUNC(#name"_resolve"); \
static ftype *name##_vec = NULL;
#define DEFINE_FAT_FUNC(name, rtype, prototype, args) \
static void_func * name##_resolve(void) \
{ \
if (getenv ("NETTLE_FAT_VERBOSE")) \
fprintf (stderr, "libnettle: "#name"_resolve\n"); \
fat_init(); \
return (void_func *) name##_vec; \
}
#else
/* !HAVE_LINK_IFUNC */
#define DECLARE_FAT_FUNC(name, ftype) \
ftype name; \
static ftype name##_init; \
static ftype *name##_vec = name##_init;
#define DEFINE_FAT_FUNC(name, rtype, prototype, args) \
rtype name prototype \
{ \
return name##_vec args; \
} \
static rtype name##_init prototype { \
if (getenv ("NETTLE_FAT_VERBOSE")) \
fprintf (stderr, "libnettle: "#name"_init\n"); \
fat_init(); \
assert (name##_vec != name##_init); \
return name##_vec args; \
}
#endif
/* !HAVE_LINK_IFUNC */
#define DECLARE_FAT_FUNC_VAR(name, type, var) \
type _nettle_##name##_##var;
#include
"memxor.h"
#include
"fat-setup.h"
void
_nettle_cpuid
(
uint32_t
input
,
uint32_t
regs
[
4
]);
typedef
void
void_func
(
void
);
typedef
void
aes_crypt_internal_func
(
unsigned
rounds
,
const
uint32_t
*
keys
,
const
struct
aes_table
*
T
,
size_t
length
,
uint8_t
*
dst
,
const
uint8_t
*
src
);
DECLARE_FAT_FUNC
(
_nettle_aes_encrypt
,
aes_crypt_internal_func
)
DECLARE_FAT_FUNC_VAR
(
aes_encrypt
,
aes_crypt_internal_func
,
x86_64
)
DECLARE_FAT_FUNC_VAR
(
aes_encrypt
,
aes_crypt_internal_func
,
aesni
)
...
...
@@ -164,8 +54,6 @@ DECLARE_FAT_FUNC(_nettle_aes_decrypt, aes_crypt_internal_func)
DECLARE_FAT_FUNC_VAR
(
aes_decrypt
,
aes_crypt_internal_func
,
x86_64
)
DECLARE_FAT_FUNC_VAR
(
aes_decrypt
,
aes_crypt_internal_func
,
aesni
)
typedef
void
*
(
memxor_func
)(
void
*
dst
,
const
void
*
src
,
size_t
n
);
DECLARE_FAT_FUNC
(
nettle_memxor
,
memxor_func
)
DECLARE_FAT_FUNC_VAR
(
memxor
,
memxor_func
,
x86_64
)
DECLARE_FAT_FUNC_VAR
(
memxor
,
memxor_func
,
sse2
)
...
...
@@ -184,7 +72,7 @@ fat_init (void)
return
;
/* FIXME: Replace all getenv calls by getenv_secure? */
verbose
=
getenv
(
"NETTLE_FAT
_VERBOSE
"
)
!=
NULL
;
verbose
=
getenv
(
ENV
_VERBOSE
)
!=
NULL
;
if
(
verbose
)
fprintf
(
stderr
,
"libnettle: fat library initialization.
\n
"
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment