From: SUGIOKA T. <su...@it...> - 2002-10-31 15:38:53
|
Hi, all. Currently, pread/pwrite system call do not work on SH-4. This is caused by mismatch of calling convention. (see glibc-2.2.5/sysdeps/unix/sysv/linux/pread.c) glibc invokes pread system call with 5 long arguments, but sys_pread takes 3 longs and 1 long long. These are different on SH-4. (otherwise same on SH-3) I have attached the patch which I'll commit if no one has any objections. Index: arch/sh/kernel/entry.S =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/entry.S,v retrieving revision 1.1.1.1.2.11 diff -u -r1.1.1.1.2.11 entry.S --- arch/sh/kernel/entry.S 1 Oct 2002 00:43:32 -0000 1.1.1.1.2.11 +++ arch/sh/kernel/entry.S 31 Oct 2002 15:14:18 -0000 @@ -1147,8 +1147,13 @@ .long SYMBOL_NAME(sys_rt_sigtimedwait) .long SYMBOL_NAME(sys_rt_sigqueueinfo) .long SYMBOL_NAME(sys_rt_sigsuspend) +#ifdef __SH4__ + .long SYMBOL_NAME(sh4_sys_pread) /* 180 */ + .long SYMBOL_NAME(sh4_sys_pwrite) +#else .long SYMBOL_NAME(sys_pread) /* 180 */ .long SYMBOL_NAME(sys_pwrite) +#endif .long SYMBOL_NAME(sys_chown16) .long SYMBOL_NAME(sys_getcwd) .long SYMBOL_NAME(sys_capget) Index: arch/sh/kernel/sys_sh.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/sys_sh.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 sys_sh.c --- arch/sh/kernel/sys_sh.c 15 Oct 2001 20:44:53 -0000 1.1.1.1 +++ arch/sh/kernel/sys_sh.c 31 Oct 2002 15:14:18 -0000 @@ -84,6 +84,30 @@ addr = COLOUR_ALIGN(addr); } } + +asmlinkage ssize_t sh4_sys_pread(unsigned int fd, char * buf, + size_t count, unsigned long pos0, unsigned long pos1) +{ +extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf, + size_t count, loff_t pos); +#ifdef __LITTLE_ENDIAN__ + return sys_pread(fd, buf, count, (loff_t)pos0 | ((loff_t)pos1 << 32)); +#else + return sys_pread(fd, buf, count, (loff_t)pos1 | ((loff_t)pos0 << 32)); +#endif +} + +asmlinkage ssize_t sh4_sys_pwrite(unsigned int fd, const char * buf, + size_t count, unsigned long pos0, unsigned long pos1) +{ +extern asmlinkage ssize_t sys_pwrite(unsigned int fd, char * buf, + size_t count, loff_t pos); +#ifdef __LITTLE_ENDIAN__ + return sys_pwrite(fd, buf, count, (loff_t)pos0 | ((loff_t)pos1 << 32)); +#else + return sys_pwrite(fd, buf, count, (loff_t)pos1 | ((loff_t)pos0 << 32)); +#endif +} #endif static inline long ---- SUGIOKA Toshinobu |