El mié., 23 oct. 2019 a las 6:50, Laurent Bercot escribió: > > >/usr/bin/ld: src/librandom/random_string.lo: in function `random_string': > >./src/librandom/random_string.c:26: warning: getrandom is not > >implemented and will always fail > [...] > >ld returns zero, even it knows "xxx is not implemented and will always fail". > > That, on the other hand, is completely insane. Why the heck isn't it > an error? It's *precisely* the kind of thing I want ld to error out on! > [...] > > >I only observe such case on GNU Hurd/K*BSD actually. I'm thinking if > >only these non-linux systems have such confused behaviour(why it links > >successfully at all...) > > That would be interesting to explore, yes.
I also think that this is a GNU libc thing. As far as I can tell, it contains a 'stub' getrandom() that does nothing, returns -1, and sets errno to ENOSYS, unless it is built for an OS that can provide a 'real' getrandom(): * https://sourceware.org/git/?p=glibc.git;a=blob;f=stdlib/getrandom.c;h=9fe6dda34d3f7fe99aaa66fc3a8ad4e540494c4a;hb=56c86f5dd516284558e106d04b92875d5b623b7a In the upstream libc package, this seems to happen only for Linux, where it is just a wrapper around the corresponding system call: * https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/getrandom.c;h=9d3d919c748d10c7debb6836575c3c44afa0d707;hb=56c86f5dd516284558e106d04b92875d5b623b7a I would think that for 'pure' GNU (Hurd) and GNU/k*BSD there is no 'real' getrandom() implementation, so the libc gets the 'stub' one, although the kernel of FreeBSD 12.0, has a getrandom() system call that the libc could use. * https://svnweb.freebsd.org/base/stable/12/sys/sys/syscall.h?revision=351565&view=markup That "stub_warning()" macro turns out to be a GCC trick to display the "is not implemented and will always fail" message: if an ELF object file contains .gnu.warning.<symbol> section, GNU ld knows what it means, shows a warning, removes the section in the resulting file, and returns 0, because an excecutable is still produced, although with an implementation of getrandom() that is not useful for skalibs :P Here's an example of the trick: $ cat libtest.c #include <errno.h> #include <stdio.h> int test_function() { fprintf (stderr, "test_function(): I told you! I don't work!\n"); return errno = ENOSYS, -1; } //Magic, create a .gnu.warning.test_function ELF section static char message[] __attribute__ ((used, section(".gnu.warning.test_function\n\t#"))) = "libtest: I provide a \"test_function\" symbol, but I don't actually implement the function"; $ gcc -shared -Wl,-soname=libtest.so -o libtest.so -fPIC -DPIC libtest.c $ objdump -h libtest.so | grep .gnu.warning 23 .gnu.warning.test_function 00000059 0000000000000000 0000000000000000 00003060 2**5 $ cat test-program.c #include <errno.h> #include <stdio.h> #include <string.h> int test_function(); int main() { if (test_function()) fprintf (stderr, "test-program: ERROR: %s\n", strerror(errno)); } $ gcc -o test-program -Wl,-rpath=/home/guillermo -L. test-program.c -ltest /usr/bin/ld: /tmp/ccu3uP4m.o: in function `main': test-program.c:(.text+0xa): warning: libtest: I provide a "test_function" symbol, but I don't actually implement the function $ objdump -h test-program | grep .gnu.warning $ ./test-program test_function(): I told you! I don't work! test-program: ERROR: Function not implemented So, it seems that,:for the purposes of detecting whether there is a usable getrandom(),for skallibs: * If GNU libc is used, a 'choose cl' test is unreliable. * GNU/Hurd and GNU/k*BSD would be 'getrandom: no' OSes, at least until the libc is updated to make a system call on GNU/kFreeBSD [1] * A 'choose clr' test would be reliable. * Any other alternative (passing an LDFLAGS that produces a build failure, overriding the result of tests, or whatever) kind of implies knowledge about what the outcome of the detection is going to be, anyway, doesn't it? It's not really a detection. [1] Is Debian the upstream of the libc port to GNU/kFreeBSD? G.
