Split fcntl() into __fcntl() and fcntl() (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 21 Jul 2015 20:15:55 +0000 (16:15 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 24 Jul 2015 07:17:57 +0000 (03:17 -0400)
commitd2d005125153f909016c27a5648094ff10fcfb89
tree89accdc8489925bcfc9d66a3dd30340df260c6d4
parente49fb234d6454f27379064c144df9857551c81eb
Split fcntl() into __fcntl() and fcntl() (XCC)

Upcoming changes to fcntl() will require the Plan 9 sockets.  Building
fcntl with dependencies on e.g. plan9_socket.c will bring in snprintf,
which ultimately triggers the dreaded multiple libcs error.  E.g.

     x86_64-ucb-akaros-gcc   -nostdlib -nostartfiles -r -o
/home/brho/akaros/ros-kernel/tools/compilers/gcc-glibc/x86_64-ucb-akaros-glibc-stage2-builddir/elf/librtld.map.o
'-Wl,-('
/home/brho/akaros/ros-kernel/tools/compilers/gcc-glibc/x86_64-ucb-akaros-glibc-stage2-builddir/elf/dl-allobjs.os
/home/brho/akaros/ros-kernel/tools/compilers/gcc-glibc/x86_64-ucb-akaros-glibc-stage2-builddir/libc_pic.a
-lgcc '-Wl,-)'
-Wl,-Map,/home/brho/akaros/ros-kernel/tools/compilers/gcc-glibc/x86_64-ucb-akaros-glibc-stage2-builddir/elf/librtld.mapT
     /home/brho/akaros/ros-kernel/tools/compilers/gcc-glibc/x86_64-ucb-akaros-glibc-stage2-builddir/libc_pic.a(init-first.os):(.data+0x0):
multiple definition of `__libc_multiple_libcs'
     /home/brho/akaros/ros-kernel/tools/compilers/gcc-glibc/x86_64-ucb-akaros-glibc-stage2-builddir/elf/dl-allobjs.os:/home/brho/akaros/ros-kernel/tools/compilers/gcc-glibc/glibc-2.19/elf/rtld.c:874:
first defined here

What's going on is that rtld can't stand to have certain parts of glibc
brought in.  This has happened previously with werrstr.  If you look at
the librtld.mapT file, you'll see bits about snprintf in there - that's
what I think pulls in an extra "__libc_multiple_libc".

The fix, according to
https://sourceware.org/ml/libc-help/2012-04/msg00043.html, is to look
into the map file and try and figure out what is pulling in what.

Ultimately, fcntl is used by rtld, so we can't have anything in fcntl.c,
even if only __fcntl is being called, that depends on things like
snprintf (as does all of the 9ns sockets stuff).

The solution is to have a separate C file for the external fcntl file
that will appear in the final libc.so, but not used internally.  I put
it in the sockets sysdep, since that subdir already includes the Plan 9
sockets stuff, and that is what is causing the incompatibility with
rtld.  Might as well keep everything "tainted" in that manner in one
place.

Rebuild glibc, etc.
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/Makefile
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/fcntl-ext.c [new file with mode: 0644]
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/fcntl.c