[PATCH v4] lib/cobalt: Avoid making mmap offset argument unconditionally 64-bit

Jan Kiszka <[email protected]>
Newsgroups dev.linux.lists.xenomai
Message-ID <[email protected]>
From: Jan Kiszka <[email protected]>

When _FILE_OFFSET_BITS is 64, mmap is handled by the mmap64 symbol of
glibc. The original mmap continues to expect native off_t size, i.e.
32 bits on 32-bit archs.

While we require applications to be rebuilt with the same settings
Xenomai was built with as well (either both _TIME_BITS and
_FILE_OFFSET_BITS set to 64 or both left unset) which practically
shadows this issue, it remains wrong to change the wrapped mmap function
in a way that is incompatible with glibc.

To avoid running into conflicts between enabling and disabling
_TIME_BITS=64 and, thus, also _FILE_OFFSET_BITS=64, factor out the
affected mmap wrappers as well as their __real stubs into a separate
code module.

There is one catch: The cobalt-call to mmap in umm.c needs to be forced
to mmap64 to become agnostic to _FILE_OFFSET_BITS used by the cobalt
core internally.

Fixes: fb2bd6e647a9 ("y2038: build: Introduce new build parameter --disable-y2038")
Signed-off-by: Jan Kiszka <[email protected]>
---

Changes in v4:
 - renamed to libcobaltnativeoff in Makefile to align with nativetime
   patches

 lib/cobalt/Makefile.am | 15 ++++++++
 lib/cobalt/mmap.c      | 79 ++++++++++++++++++++++++++++++++++++++++++
 lib/cobalt/rtdm.c      | 38 --------------------
 lib/cobalt/umm.c       |  4 +--
 lib/cobalt/wrappers.c  | 17 ---------
 5 files changed, 96 insertions(+), 57 deletions(-)
 create mode 100644 lib/cobalt/mmap.c

diff --git a/lib/cobalt/Makefile.am b/lib/cobalt/Makefile.am
index 4318adf185..b5b184b555 100644
--- a/lib/cobalt/Makefile.am
+++ b/lib/cobalt/Makefile.am
@@ -7,9 +7,12 @@ noinst_HEADERS =	\
 
 lib_LTLIBRARIES = libcobalt.la libmodechk.la
 
+noinst_LTLIBRARIES = libcobaltnativeoff.la
+
 libcobalt_la_LDFLAGS = @XENO_LIB_LDFLAGS@ -version-info 2:0:0 -lpthread -lrt
 
 libcobalt_la_LIBADD = \
+	libcobaltnativeoff.la			\
 	arch/@XENO_TARGET_ARCH@/libarch.la	\
 	../boilerplate/libboilerplate.la
 
@@ -43,6 +46,18 @@ libcobalt_la_CPPFLAGS =			\
 	-I$(top_srcdir)/include/cobalt	\
 	-I$(top_srcdir)/include
 
+# source files that require native off_t size
+libcobaltnativeoff_la_SOURCES =	\
+	mmap.c
+
+libcobaltnativeoff_la_LDFLAGS = @XENO_LIB_LDFLAGS@
+
+libcobaltnativeoff_la_CPPFLAGS =	\
+	@XENO_COBALT_CFLAGS@		\
+	-I$(top_srcdir)/include/cobalt	\
+	-I$(top_srcdir)/include		\
+	-U_TIME_BITS -U_FILE_OFFSET_BITS
+
 libmodechk_la_LIBADD = libcobalt.la
 
 libmodechk_la_SOURCES =	\
diff --git a/lib/cobalt/mmap.c b/lib/cobalt/mmap.c
new file mode 100644
index 0000000000..069163a855
--- /dev/null
+++ b/lib/cobalt/mmap.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2005 Jan Kiszka <[email protected]>.
+ * Copyright (C) 2005 Heikki Lindholm <[email protected]>.
+ *
+ * This 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 of the License, or (at your option) any later version.
+ *
+ * This 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+  USA.
+ */
+
+#include <sys/mman.h>
+#include <rtdm/rtdm.h>
+#include <cobalt/uapi/syscall.h>
+#include <asm/xenomai/syscall.h>
+
+COBALT_IMPL(void *, mmap64, (void *addr, size_t length, int prot, int flags,
+			     int fd, off64_t offset))
+{
+	struct _rtdm_mmap_request rma;
+	int ret;
+
+	if (fd < 0) /* We don't do anonymous mappings. */
+		goto regular;
+
+	/* RTDM ignores the address hint, and rejects MAP_FIXED. */
+	rma.length = length;
+	rma.offset = offset;
+	rma.prot = prot;
+	rma.flags = flags;
+
+	ret = XENOMAI_SYSCALL3(sc_cobalt_mmap, fd, &rma, &addr);
+	if (ret != -EADV && ret != -ENOSYS) {
+		if (ret) {
+			errno = -ret;
+			return MAP_FAILED;
+		}
+
+		return addr;
+	}
+
+regular:
+#if mmap64 == mmap
+	return __STD(mmap(addr, length, prot, flags, fd, offset));
+#else
+	return __STD(mmap64(addr, length, prot, flags, fd, offset));
+#endif
+}
+
+COBALT_IMPL(void *, mmap, (void *addr, size_t length, int prot, int flags,
+			   int fd, off_t offset))
+{
+	return __COBALT(mmap64(addr, length, prot, flags, fd, offset));
+}
+
+__weak
+void *__real_mmap(void *addr, size_t length, int prot, int flags,
+		  int fd, off_t offset)
+{
+	return mmap(addr, length, prot, flags, fd, offset);
+}
+
+#if mmap64 != mmap
+__weak
+void *__real_mmap64(void *addr, size_t length, int prot, int flags,
+		  int fd, off64_t offset)
+{
+	return mmap64(addr, length, prot, flags, fd, offset);
+}
+#endif
diff --git a/lib/cobalt/rtdm.c b/lib/cobalt/rtdm.c
index 00c1aaf4b2..119ba3f83d 100644
--- a/lib/cobalt/rtdm.c
+++ b/lib/cobalt/rtdm.c
@@ -541,41 +541,3 @@ COBALT_IMPL(int, shutdown, (int fd, int how))
 
 	return __STD(shutdown(fd, how));
 }
-
-COBALT_IMPL(void *, mmap64, (void *addr, size_t length, int prot, int flags,
-			     int fd, off64_t offset))
-{
-	struct _rtdm_mmap_request rma;
-	int ret;
-
-	if (fd < 0) /* We don't do anonymous mappings. */
-		goto regular;
-
-	/* RTDM ignores the address hint, and rejects MAP_FIXED. */
-	rma.length = length;
-	rma.offset = offset;
-	rma.prot = prot;
-	rma.flags = flags;
-
-	ret = XENOMAI_SYSCALL3(sc_cobalt_mmap, fd, &rma, &addr);
-	if (ret != -EADV && ret != -ENOSYS) {
-		ret = set_errno(ret);
-		if (ret)
-			return MAP_FAILED;
-
-		return addr;
-	}
-
-regular:
-#if mmap64 == mmap
-	return __STD(mmap(addr, length, prot, flags, fd, offset));
-#else
-	return __STD(mmap64(addr, length, prot, flags, fd, offset));
-#endif
-}
-
-COBALT_IMPL(void *, mmap, (void *addr, size_t length, int prot, int flags,
-			   int fd, off_t offset))
-{
-	return __COBALT(mmap64(addr, length, prot, flags, fd, offset));
-}
diff --git a/lib/cobalt/umm.c b/lib/cobalt/umm.c
index c0d4489d34..6b4303b727 100644
--- a/lib/cobalt/umm.c
+++ b/lib/cobalt/umm.c
@@ -58,8 +58,8 @@ static void *__map_umm(const char *name, uint32_t *size_r)
 		return MAP_FAILED;
 	}
 
-	addr = __RT(mmap(NULL, statbuf.size, PROT_READ|PROT_WRITE,
-			 MAP_SHARED, fd, 0));
+	addr = __RT(mmap64(NULL, statbuf.size, PROT_READ|PROT_WRITE,
+			   MAP_SHARED, fd, 0));
 	__RT(close(fd));
 
 	*size_r = statbuf.size;
diff --git a/lib/cobalt/wrappers.c b/lib/cobalt/wrappers.c
index 18c237734f..3a0063f051 100644
--- a/lib/cobalt/wrappers.c
+++ b/lib/cobalt/wrappers.c
@@ -28,7 +28,6 @@
 #include <sys/select.h>
 #include <sys/socket.h>
 #include <sys/time.h>
-#include <sys/mman.h>
 #include <stdio.h>
 #include <stdarg.h>
 #include <stdlib.h>
@@ -384,22 +383,6 @@ int __real_select (int __nfds, fd_set *__restrict __readfds,
 	return select(__nfds, __readfds, __writefds, __exceptfds, __timeout);
 }
 
-__weak
-void *__real_mmap(void *addr, size_t length, int prot, int flags,
-		  int fd, off_t offset)
-{
-	return mmap(addr, length, prot, flags, fd, offset);
-}
-
-#if mmap64 != mmap
-__weak
-void *__real_mmap64(void *addr, size_t length, int prot, int flags,
-		  int fd, off64_t offset)
-{
-	return mmap64(addr, length, prot, flags, fd, offset);
-}
-#endif
-
 __weak
 int __real_vfprintf(FILE *stream, const char *fmt, va_list args)
 {
-- 
2.47.3
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.