Bug 20723

Summary: Static linking fails on Haswell and Sandy Bridge when certain math functions are used
Product: glibc Reporter: rlcamp.pdx
Component: mathAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED DUPLICATE    
Severity: normal Flags: fweimer: security-
Priority: P2    
Version: 2.24   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:

Description rlcamp.pdx 2016-10-20 11:06:15 UTC
The math library in the newest glibc in both Ubuntu 16.10 (2.24-3ubuntu1) and Debian-testing (2.24-3) cannot be statically linked successfully on Haswell or Sandy Bridge (when compiling with -static and -march=native, -march=haswell, or -march-sandybridge). The specific errors are "undefined reference to _ZGVcN4v_cos" and similar at link time. The problem does not occur when not statically linking, and does not occur when using -march=nehalem or some other pre-AVX instruction set. The problem does not occur when using musl-libc rather than glibc.

cc -static -Ofast  -I/usr/local/include -std=gnu99 -Wall -Werror -Wextra -Wvla -Wpointer-arith -Wshadow -Wuninitialized -Wno-unused-result -Wno-unused-parameter -march=native -o [binary name omitted] [.o filenames omitted] -lpthread -lm
[filename omitted].o: In function `[function name omitted]':
[filename omitted].c:(.text+0x2256): undefined reference to `_ZGVcN4v_cos'
[filename omitted].c:(.text+0x2268): undefined reference to `_ZGVcN4v_cos'
[filename omitted].c:(.text+0x2282): undefined reference to `_ZGVcN4v_sin'
[filename omitted].c:(.text+0x22a0): undefined reference to `_ZGVcN4v_sin'
[filename omitted].o: In function `[function name omitted]':
[filename omitted].c:(.text+0x5ff): undefined reference to `_ZGVcN4v_cos'
[filename omitted].c:(.text+0x60e): undefined reference to `_ZGVcN4v_cos'
[filename omitted].c:(.text+0x625): undefined reference to `_ZGVcN4v_sin'
[filename omitted].c:(.text+0x640): undefined reference to `_ZGVcN4v_sin'
collect2: error: ld returned 1 exit status
Makefile:79: recipe for target '[binary name omitted]' failed
make: *** [[binary name omitted]] Error 1
Comment 1 rlcamp.pdx 2016-10-20 12:53:35 UTC
The following code example and compile line triggers the error. Code is taken verbatim from the glibc wiki:

#include <math.h>

int N = 3200;
double b[3200];
double a[3200];

int main (void)
{
  int i;

  for (i = 0; i < N; i += 1)
  {
    b[i] = sin (a[i]);
  }

  return (0);
}

cc -static -Ofast -march=haswell -o test test.c -lm
/tmp/ccIWFVL3.o: In function `main':
test.c:(.text.startup+0x14a): undefined reference to `_ZGVdN4v_sin'
collect2: error: ld returned 1 exit status
Comment 2 rlcamp.pdx 2016-10-20 13:03:01 UTC
Explicitly adding -lmvec to the end of the compile line fixes the issue. However, the wiki page (https://sourceware.org/glibc/wiki/libmvec) indicates that this should not be required, and since no explicitly stated desire to use vectorized math functions is necessary to trigger this error, the user may not realize the nature of the problem, and will have a hard time determining the fix.
Comment 3 Joseph Myers 2016-10-20 15:36:22 UTC
That wiki page explicitly says "For static builds with gcc needed to add both options with the following order: -lmvec -lm.", but there's the question of whether we should make libm.a into a linker script like libm.so (we don't have any precedent for making .a files into linker scripts, however).

*** This bug has been marked as a duplicate of bug 20539 ***