Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ addons:
packages:
- autoconf
- automake
- clang
- gawk
- gcc-10
- lcov
- libtool
- llvm
- llvm-dev
- pkg-config
- python3-venv
- valgrind
Expand Down Expand Up @@ -84,6 +86,20 @@ matrix:
env:
- CONF="--enable-obsolete-api --enable-hashes=all"
- SANITIZER=1
- name: "Linux, GCC, all hashes, obsolete API, LTO, ASan+UBSan"
compiler: gcc
os: linux
env:
- CONF="--enable-obsolete-api --enable-hashes=all"
- LTO=1
- SANITIZER=1
- name: "Linux, Clang, all hashes, obsolete API, LTO, ASan+UBSan"
compiler: clang
os: linux
env:
- CONF="--enable-obsolete-api --enable-hashes=all"
- LTO=1
- SANITIZER=1
- name: "Linux, GCC, all hashes, static lib"
compiler: gcc
os: linux
Expand Down
23 changes: 23 additions & 0 deletions .travis_script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,29 @@ if [[ "$SANITIZER" == "1" ]]; then
export CXXFLAGS="$CXXFLAGS -fsanitize=undefined,address"
fi

if [[ "$LTO" == "1" ]]; then
if [[ "$CC" == "gcc" ]]; then
export CC="gcc-10"
export CPP="cpp-10"
export CXX="g++-10"
export AR="gcc-ar-10"
export NM="gcc-nm-10"
export RANLIB="gcc-ranlib-10"
export CFLAGS="$CFLAGS -flto=auto -ffat-lto-objects"
export CXXFLAGS="$CXXFLAGS -flto=auto -ffat-lto-objects"
fi
if [[ "$CC" == "clang" ]]; then
export CC="/usr/bin/clang"
export CPP="/usr/bin/clang-cpp-10"
export CXX="/usr/bin/clang++"
export AR="/usr/bin/llvm-ar"
export NM="/usr/bin/llvm-nm"
export RANLIB="/usr/bin/llvm-ranlib"
export CFLAGS="$CFLAGS -flto"
export CXXFLAGS="$CXXFLAGS -flto"
fi
fi

pushd build
log_time preparation

Expand Down
5 changes: 5 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ Version 4.4.17
newline '\n' character, since all parameters of the user data must
be on the same line within the Unix shadow file.

* Building with link-time optimization (-flto) enabled is now
possible with either GCC 10 or LLVM/Clang 10 (issue #24).
See the 'Portability Notes' section of the README.md file for
detailed instructions and possible caveats.

Version 4.4.16
* Add support for the e2k architecture.

Expand Down
30 changes: 23 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,29 @@ not always be able to retrieve cryptographically-sound random numbers
from the operating system; if you call these functions with a null
pointer for the “rbytes” argument, be prepared for them to fail.

As of mid-2018, GCC and LLVM don’t support link-time optimization of
libraries that use symbol versioning. If you build libxcrypt with
either of these compilers, do not use `-flto`. See [GCC bug 48200][1]
for specifics; the problem is very similar for LLVM. Because this is,
at its root, a set of missing compiler features, we expect link-time
optimization won’t work in other C compilers either, but we haven’t
tested it ourselves.
As of August 2020, link-time optimization (`-flto`) of libraries that use
symbol versioning is initially supported by GCC 10 and LLVM/Clang 10, if
their compiler specific toolchain is used during compilation.

For GCC the needed tools are called with:
```
./configure CC="gcc" AR="gcc-ar" NM="gcc-nm" RANLIB="gcc-ranlib" \
CFLAGS="-O2 -flto -g" ...
```
and for LLVM/Clang those tools are called with:
```
./configure CC="clang" AR="llvm-ar" NM="llvm-nm" RANLIB="llvm-ranlib" \
CFLAGS="-O2 -flto -g" ...
```

To build static libraries, that can be linked against non-LTO objects
one may also want to add `-ffat-lto-objects` to the CFLAGS.

If you build libxcrypt with earlier versions of these compilers, do not
use `-flto`. See [GCC bug 48200][1] for specifics; the problem is very
similar for LLVM. Because this is, at its root, a set of missing compiler
features, we expect link-time optimization won’t work in other C compilers
either, but we haven’t tested it ourselves.

[1]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48200

Expand Down
39 changes: 38 additions & 1 deletion lib/crypt-port.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,20 @@
#include <sys/param.h>
#endif

/* The prototype of the crypt() function possibly defined in <unistd.h>
needs to be renamed as it might be incompatible with our declaration.
Defining this macro *AFTER* the crypt-symbol-vers header, which also
defines the same macro for symbol-versioning purposes, was included,
would lead to a clashing redefinition of this macro, and thus cause
our symbol-versioning would not work properly. */
#ifdef HAVE_UNISTD_H
#define crypt unistd_crypt_is_incompatible
#define crypt_r unistd_crypt_r_is_incompatible
#include <unistd.h>
#undef crypt
#undef crypt_r
#endif

#ifndef HAVE_SYS_CDEFS_THROW
#define __THROW /* nothing */
#endif
Expand Down Expand Up @@ -179,11 +193,29 @@ _crypt_strcpy_or_abort (void *, const size_t, const void *);
# define _strong_alias(name, aliasname) \
extern __typeof (name) aliasname __THROW __attribute__ ((alias (#name)))

/* Starting with GCC 10, we can use the symver attribute, which also works
with link-time optimization enabled. */
# if __GNUC__ >= 10

/* Set the symbol version for EXTNAME, which uses INTNAME as its
implementation. */
# define symver_set(extstr, intname, version, mode) \
extern __typeof (intname) intname __THROW \
__attribute__((symver (extstr mode #version)))

/* Referencing specific _compatibility_ symbols still needs inline asm. */
# define _symver_ref(extstr, intname, version) \
__asm__ (".symver " #intname "," extstr "@" #version)

# else

/* Set the symbol version for EXTNAME, which uses INTNAME as its
implementation. */
# define symver_set(extstr, intname, version, mode) \
__asm__ (".symver " #intname "," extstr mode #version)

# endif

#else
# error "Don't know how to do symbol versioning with this compiler"
#endif
Expand Down Expand Up @@ -239,9 +271,14 @@ _crypt_strcpy_or_abort (void *, const size_t, const void *);

/* Tests may need to _refer_ to compatibility symbols, but should never need
to _define_ them. */

#define symver_ref(extstr, intname, version) \
_symver_ref(extstr, intname, version)

/* Generic way for referencing specific _compatibility_ symbols. */
#ifndef _symver_ref
#define _symver_ref(extstr, intname, version) \
symver_set(extstr, intname, version, "@")
#endif

/* Define configuration macros used during compile-time by the
GOST R 34.11-2012 "Streebog" hash function. */
Expand Down
3 changes: 0 additions & 3 deletions lib/randombytes.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

/* If we have O_CLOEXEC, we use it, but if we don't, we don't worry
about it. */
Expand Down
5 changes: 0 additions & 5 deletions libxcrypt.spec.rpkg
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,6 @@ fi \
%global _ld_strict_symbol_defs 1


# The library uses symbol versioning in way
# that is not compatible with LTO currently.
%undefine _lto_cflags


Name: {{{ git_name }}}
Version: {{{ git_real_version }}}
Release: 0.{{{ git_real_release }}}%{?dist}
Expand Down
2 changes: 0 additions & 2 deletions test/badsalt.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,10 @@
<http://www.gnu.org/licenses/>. */

#include "crypt-port.h"
#include <crypt.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>

static const char phrase[] = "values of β will give rise to dom!";

Expand Down
1 change: 0 additions & 1 deletion test/crypt-badargs.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include <string.h>
#include <signal.h>
#include <sys/mman.h>
#include <unistd.h>

/* The behavior tested below should be consistent for all hashing
methods. */
Expand Down
3 changes: 0 additions & 3 deletions test/getrandom-fallbacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

/* If arc4random_buf is available, all of the fallback logic is compiled
out and this test is unnecessary. If ld --wrap is not available this
Expand Down
1 change: 0 additions & 1 deletion test/getrandom-interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include <string.h>
#include <signal.h>
#include <sys/mman.h>
#include <unistd.h>

static bool error_occurred;

Expand Down
1 change: 0 additions & 1 deletion test/short-outbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
*/

#include "crypt-port.h"
#include <crypt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Expand Down