[klibc] [klibc:master] Add pread and pwrite 32bit syscall wrappers for parisc

klibc-bot for Helge Deller deller at gmx.de
Tue Jan 5 17:54:04 PST 2016


Commit-ID:  75895304280f597f46551deb8b87c27ac18a013c
Gitweb:     http://git.kernel.org/?p=libs/klibc/klibc.git;a=commit;h=75895304280f597f46551deb8b87c27ac18a013c
Author:     Helge Deller <deller at gmx.de>
AuthorDate: Wed, 6 Jan 2016 00:43:50 +0000
Committer:  H. Peter Anvin <hpa at linux.intel.com>
CommitDate: Tue, 5 Jan 2016 17:45:50 -0800

[klibc] Add pread and pwrite 32bit syscall wrappers for parisc

On the hppa arch (32bit userspace and 32 or 64bit kernel), the fstype
program fails to detect the filesystem.  The reason for this failure
is, that fstype calls the pread() syscall, which has on some
architectures with 32bit userspace a different calling syntax.  I
noticed this bug on hppa, but I assume s390 (32bit) and others might
run into similiar issues.

Signed-off-by: Helge Deller <deller at gmx.de>
Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
Signed-off-by: H. Peter Anvin <hpa at linux.intel.com>

---
 usr/include/endian.h   |  6 ++++++
 usr/klibc/Kbuild       |  1 +
 usr/klibc/SYSCALLS.def |  6 ++++--
 usr/klibc/pread.c      | 29 +++++++++++++++++++++++++++++
 usr/klibc/pwrite.c     | 29 +++++++++++++++++++++++++++++
 5 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/usr/include/endian.h b/usr/include/endian.h
index a6cd6d9..61cda3a 100644
--- a/usr/include/endian.h
+++ b/usr/include/endian.h
@@ -12,4 +12,10 @@
 #define PDP_ENDIAN	__PDP_ENDIAN
 #define BYTE_ORDER	__BYTE_ORDER
 
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# define __LONG_LONG_PAIR(HI, LO) LO, HI
+#elif __BYTE_ORDER == __BIG_ENDIAN
+# define __LONG_LONG_PAIR(HI, LO) HI, LO
+#endif
+
 #endif				/* _ENDIAN_H */
diff --git a/usr/klibc/Kbuild b/usr/klibc/Kbuild
index 40d43c7..d3e2b9f 100644
--- a/usr/klibc/Kbuild
+++ b/usr/klibc/Kbuild
@@ -35,6 +35,7 @@ klib-y += vsnprintf.o snprintf.o vsprintf.o sprintf.o \
 	  siglongjmp.o \
 	  sigaction.o sigpending.o sigprocmask.o sigsuspend.o \
 	  pselect.o ppoll.o \
+	  pread.o pwrite.o \
 	  brk.o sbrk.o malloc.o realloc.o zalloc.o calloc.o \
 	  mmap.o shm_open.o shm_unlink.o \
 	  memcpy.o memcmp.o memset.o memccpy.o memmem.o memswap.o \
diff --git a/usr/klibc/SYSCALLS.def b/usr/klibc/SYSCALLS.def
index 41cfa17..c56e8f9 100644
--- a/usr/klibc/SYSCALLS.def
+++ b/usr/klibc/SYSCALLS.def
@@ -189,8 +189,10 @@ int fdatasync,fsync::fdatasync(int);
 int readv(int, const struct iovec *, int);
 int writev(int, const struct iovec *, int);
 int ftruncate64,ftruncate::ftruncate(int, off_t);
-ssize_t pread64,pread::pread(int, void *, size_t, off_t);
-ssize_t pwrite64,pwrite::pwrite(int, void *, size_t, off_t);
+<parisc> ssize_t pread64,pread::__pread(int, void *, size_t, off_t);
+<parisc> ssize_t pwrite64,pwrite::__pwrite(int, void *, size_t, off_t);
+<!parisc> ssize_t pread64,pread::pread(int, void *, size_t, off_t);
+<!parisc> ssize_t pwrite64,pwrite::pwrite(int, void *, size_t, off_t);
 int sync_file_range,fdatasync,fsync::sync_file_range(int, off_t, off_t, unsigned int);
 <?> int splice(int, off_t *, int, off_t *, size_t, unsigned int);
 <?> int tee(int, int, size_t, unsigned int);
diff --git a/usr/klibc/pread.c b/usr/klibc/pread.c
new file mode 100644
index 0000000..0d8c3b1
--- /dev/null
+++ b/usr/klibc/pread.c
@@ -0,0 +1,29 @@
+/*
+ * pread.c
+ *
+ * Some architectures need to wrap the system call
+ */
+
+#include <endian.h>
+#include <sys/syscall.h>
+
+#if defined(__hppa__)
+
+#if _BITSIZE == 32
+extern size_t __pread(int, void *, size_t, unsigned int, unsigned int);
+#else
+extern size_t __pread(int, void *, size_t, off_t);
+#endif
+
+size_t pread(int fd, void *buf, size_t count, off_t offset)
+{
+#if _BITSIZE == 32
+	unsigned int hi = offset >> 32;
+	unsigned int lo = (unsigned int) offset;
+	return __pread(fd, buf, count, __LONG_LONG_PAIR(hi, lo));
+#else
+	return __pread(fd, buf, count, offset);
+#endif
+}
+
+#endif
diff --git a/usr/klibc/pwrite.c b/usr/klibc/pwrite.c
new file mode 100644
index 0000000..691d0e4
--- /dev/null
+++ b/usr/klibc/pwrite.c
@@ -0,0 +1,29 @@
+/*
+ * pwrite.c
+ *
+ * Some architectures need to wrap the system call
+ */
+
+#include <endian.h>
+#include <sys/syscall.h>
+
+#if defined(__hppa__)
+
+#if _BITSIZE == 32
+extern ssize_t __pwrite(int, const void *, size_t, unsigned int, unsigned int);
+#else
+extern ssize_t __pwrite(int, const void *, size_t, off_t);
+#endif
+
+size_t pwrite(int fd, void *buf, size_t count, off_t offset)
+{
+#if _BITSIZE == 32
+	unsigned int hi = offset >> 32;
+	unsigned int lo = (unsigned int) offset;
+	return __pwrite(fd, buf, count, __LONG_LONG_PAIR(hi, lo));
+#else
+	return __pwrite(fd, buf, count, offset);
+#endif
+}
+
+#endif


More information about the klibc mailing list