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)
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

index b3608db..42dcd25 100644 (file)
@@ -15,6 +15,7 @@ CFLAGS-funlockfile.c = $(libio-mtsafe)
 # need to be careful to only include some of them for specific subdirs.
 ifeq ($(subdir),socket)
 sysdep_routines += sa_len plan9_sockets
+sysdep_routines += fcntl-ext
 endif
 sysdep_headers += sys/syscall.h sys/tls.h
 
diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/fcntl-ext.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/fcntl-ext.c
new file mode 100644 (file)
index 0000000..0cb87b1
--- /dev/null
@@ -0,0 +1,22 @@
+/* Copyright (c) 2015 Google, Inc.
+ * Barret Rhoden <brho@cs.berkeley.edu>
+ * See LICENSE for details. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <ros/syscall.h>
+
+/* in sysdeps/akaros/fcntl.c */
+extern int __vfcntl(int fd, int cmd, va_list vl);
+
+int fcntl(int fd, int cmd, ...)
+{
+       int ret;
+       va_list vl;
+       va_start(vl, cmd);
+       ret = __vfcntl(fd, cmd, vl);
+       va_end(vl);
+       return ret;
+}
index ea6df98..8577c02 100644 (file)
@@ -1,20 +1,6 @@
-/* Copyright (C) 1991, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+/* Copyright (c) 2015 Google, Inc.
+ * Barret Rhoden <brho@cs.berkeley.edu>
+ * See LICENSE for details. */
 
 #include <errno.h>
 #include <fcntl.h>
 #include <stdlib.h>
 #include <ros/syscall.h>
 
-/* Perform file control operations on FD.  */
-int
-__fcntl(int fd, int cmd, ...)
+int __vfcntl(int fd, int cmd, va_list vl)
 {
        int ret, arg, advise;
        __off64_t offset, len;
-       va_list vl;
-       va_start(vl, cmd);
        switch (cmd) {
                case F_GETFD:
                case F_SYNC:
@@ -52,9 +34,16 @@ __fcntl(int fd, int cmd, ...)
                        errno = ENOSYS;
                        ret = -1;
        }
-       va_end(vl);
        return ret;
 }
 
-libc_hidden_def (__fcntl)
-weak_alias (__fcntl, fcntl)
+int __fcntl(int fd, int cmd, ...)
+{
+       int ret;
+       va_list vl;
+       va_start(vl, cmd);
+       ret = __vfcntl(fd, cmd, vl);
+       va_end(vl);
+       return ret;
+}
+libc_hidden_def(__fcntl)