libtom/libtommath

Dependency on dead code elimination

mabuchner opened this issue · 4 comments

I'm trying to compile libtommath (v1.2.0) on MacOS with my own CMake configuration.

However, when linking the test application, if received the following linker error

Linking C executable tommath-test
FAILED: tommath-test
: && /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk -mmacosx-version-min=10.12 -Wl,-search_paths_first -Wl,-headerpad_max_install_names  CMakeFiles/tommath-test.dir/demo/shared.c.o CMakeFiles/tommath-test.dir/demo/test.c.o -o tommath-test  libtommath.a && :
Undefined symbols for architecture x86_64:
  "_s_read_arc4random", referenced from:
      _s_mp_rand_platform in libtommath.a(bn_s_mp_rand_platform.c.o)
  "_s_read_getrandom", referenced from:
      _s_mp_rand_platform in libtommath.a(bn_s_mp_rand_platform.c.o)
  "_s_read_ltm_rng", referenced from:
      _s_mp_rand_platform in libtommath.a(bn_s_mp_rand_platform.c.o)
  "_s_read_wincsp", referenced from:
      _s_mp_rand_platform in libtommath.a(bn_s_mp_rand_platform.c.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

While looking for a cause in the source code, I found the following comment

* Note: libtommath relies on dead code elimination

which makes it sound like this is intended behaviour???

I need to compile libtommath for a bunch of platforms and I really don't want to patch this file for each one of them.

I'm wondering why the code doesn't simply use the preprocessor defines, which are defined in the code above.

mp_err s_mp_rand_platform(void *p, size_t n)
{
   mp_err err = MP_ERR;
#ifdef BN_S_READ_ARC4RANDOM_C
   if (err != MP_OKAY) err = s_read_arc4random(p, n);
#endif
#ifdef BN_S_READ_WINCSP_C
   if (err != MP_OKAY) err = s_read_wincsp(p, n);
#endif
#ifdef BN_S_READ_GETRANDOM_C
   if (err != MP_OKAY) err = s_read_getrandom(p, n);
#endif
#ifdef BN_S_READ_URANDOM_C
   if (err != MP_OKAY) err = s_read_urandom(p, n);
#endif
#ifdef BN_S_READ_LTM_RNG
   if (err != MP_OKAY) err = s_read_ltm_rng(p, n);
#endif
   return err;
}

Wouldn't this achieve the same effect without having to rely on dead code elimination?

* We intentionally don't fix this issue in order
* to have a single point of failure for misconfigured compilers.

Are there places where libtommath silently depends on dead code elimination? Or why do you need a single point of failure?

$ ack -l --cc --no-hh --sort-files MP_HAS
demo/test.c
etc/tune.c
mp_div.c
mp_div_d.c
mp_exptmod.c
mp_invmod.c
mp_log_n.c
mp_mul.c
mp_mul_d.c
mp_radix_size_overestimate.c
mp_reduce.c
mp_set_double.c
s_mp_exptmod_fast.c
s_mp_mul_high.c
s_mp_radix_size_overestimate.c
s_mp_rand_platform.c

Guarding invalid code (for the current target platform) behind an if-condition, feels not correct.

Seems like the MP_HAS macro was introduced with #262. I will try to work with an older version.