Hello,
Thank for a wonderful system library !
Revision f61be1f875a2758509d6e9e2cf6f1d9603b28b65
has led to regression with system calls of family *stat on MIPS with
big endian byte order.
Upon successful completion, the system call returns the number from
stat structure instead of 0.
Information:
Binutils 2.23.2/2.24
GCC 4.8.3/4.9.2
musl 1.1.5/1.1.8/HEAD
Code to reproduce problem:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int fd, res = EXIT_FAILURE, ret;
struct stat st;
fd = open("/dev/urandom", O_RDONLY);
if (fd < 0) {
perror("open");
goto out;
}
ret = fstat(fd, &st);
if (ret < 0) {
perror("fstat");
goto out_close;
} else {
printf("ret = %d\n", ret);
}
res = EXIT_SUCCESS;
out_close:
close(fd);
out:
return res;
}
Output:
# test_fstat
ret = 265
# strace -s 1024 test_fstat
execve("/bin/test_fstat", ["test_fstat"], [/* 7 vars */]) = 0
set_thread_area(0x2ae00764) = 0
set_tid_address(0x2adf96b4) = 150
open("/dev/urandom", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFCHR|0600, st_rdev=makedev(1, 9), ...}) = 0
ioctl(1, TIOCNXCL, {B9600 opost isig icanon echo ...}) = 0
writev(1, [{"ret = 265", 9}, {"\n", 1}], 2ret = 265
) = 10
close(3) = 0
exit_group(0) = ?
+++ exited with 0 +++
The reason of the problem is that the function __stat_fix rewrites
register $v0, which is not stored in the parent function.
Disassembled code of fstat64 is attached.
Patch is attached also.
Sorry for my english.