[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