From 918c5fa0fc656e49b1ab9ce47183a23e3a36bc00 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 16 Jul 2019 21:05:24 -0400 Subject: [PATCH] fix broken lseek on mipsn32 with offsets larger than LONG_MAX mips n32 has 32-bit long, and generally uses long syscall arguments and return values, but provides only SYS_lseek, not SYS_llseek. we have some framework (syscall_arg_t, added for x32) to make syscall arguments 64-bit in such a setting, but it's not clear whether this could match the sign-extension semantics needed for 32-bit args to all the other syscalls, and we don't have any existing mechanism to allow the return value of syscalls to be something other than long. instead, just provide a custom mipsn32 version of the lseek function doing its own syscall asm with 64-bit arguments. as a result of commit 03919b26ed41c31876db41f7cee076ced4513fad, stdio will also get the new code, fixing fseeko/ftello too. --- src/unistd/mipsn32/lseek.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/unistd/mipsn32/lseek.c diff --git a/src/unistd/mipsn32/lseek.c b/src/unistd/mipsn32/lseek.c new file mode 100644 index 00000000..60e74a51 --- /dev/null +++ b/src/unistd/mipsn32/lseek.c @@ -0,0 +1,20 @@ +#include +#include "syscall.h" + +off_t __lseek(int fd, off_t offset, int whence) +{ + register long long r4 __asm__("$4") = fd; + register long long r5 __asm__("$5") = offset; + register long long r6 __asm__("$6") = whence; + register long long r7 __asm__("$7"); + register long long r2 __asm__("$2") = SYS_lseek; + __asm__ __volatile__ ( + "syscall" + : "+&r"(r2), "=r"(r7) + : "r"(r4), "r"(r5), "r"(r6) + : SYSCALL_CLOBBERLIST); + return r7 ? __syscall_ret(-r2) : r2; +} + +weak_alias(__lseek, lseek); +weak_alias(__lseek, lseek64);