|
Date: Tue, 10 Mar 2020 22:10:15 +0100 From: Andreas Dröscher <musl@...free.ch> To: musl@...ts.openwall.com Subject: mips32 little endian -ENOSYS is not -(-ENOSYS) Hi I'm building a new toolchain for a very old hardware with a very old Linux Kernel (2.6.20). The CPU is a Alchemy (now AMD) AU1100 (production was discontinued). Obviously the Kernel lacks a lot of the modern system calls. I however expect the general system call interface to be consistent. Moreover, musl has fallbacks for many system-calls in place, kudos! However, the fallback is never triggered. I will present the issue on one example (epoll): excerpt from src/linux/epoll.c: int epoll_create1(int flags) { int r = __syscall(SYS_epoll_create1, flags); #ifdef SYS_epoll_create if (r==-ENOSYS && !flags) r = __syscall(SYS_epoll_create, 1); #endif return __syscall_ret(r); } If r is -89 (negative ENOSYS) the fallback is triggered else the result is returned as it is. However, in my case __syscall returnes 89 (positive ENOSYS). I've tracked the return into the kernel and there the negative value is returned. The Kernel additionally sets r7 to 1. excerpt from arch/mips/syscall_arch.h: static inline long __syscall1(long n, long a) { register long r4 __asm__("$4") = a; register long r7 __asm__("$7"); register long r2 __asm__("$2") = n; __asm__ __volatile__ ( "syscall" : "+r"(r2), "=r"(r7) : "r"(r4) : SYSCALL_CLOBBERLIST, "$8", "$9", "$10"); return r7 ? -r2 : r2; } I assume the "bug" is triggered by __syscall1 If r7 is set it will change the sign of r2. I can patch that by replacing: return r7 ? -r2 : r2; with return (r7 && r2 > 0) ? -r2 : r2; However I've no idea if I'm triggering any side effects or if I selected the wrong implementation for my architecture. Any suggestions are appreciated. ~Andreas
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.