This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
sysdeps/unix/sysv/linux/lseek.c on ILP32 question
- From: Steve Ellcey <sellcey at caviumnetworks dot com>
- To: libc-alpha <libc-alpha at sourceware dot org>
- Date: Tue, 21 Feb 2017 10:22:47 -0800
- Subject: sysdeps/unix/sysv/linux/lseek.c on ILP32 question
- Authentication-results: sourceware.org; auth=none
- Authentication-results: spf=none (sender IP is ) smtp.mailfrom=Steve dot Ellcey at cavium dot com;
- Spamdiagnosticmetadata: NSPM
- Spamdiagnosticoutput: 1:99
I am looking at a glibc bug in the ILP32 aarch implementation that I am
working on and have a question about lseek. The failure I am looking
at comes from the LTP testsuite and involves calling lseek with a
negative offset argument.
I am looking at sysdeps/unix/sysv/linux/lseek.c and the code for when
__NR__llseek is defined. It has:
int rc = INLINE_SYSCALL_CALL (_llseek, fd,
(long) (((uint64_t) (offset)) >> 32),
(long) offset, &res, whence);
And I am not sure the conversion from offset to the two llseek
arguments is correct for both LP64 and ILP32 modes when offset is
negative. For example if I run the following program on x86_64:
#include <stdio.h>
void foo(long long i)
{
printf("%ld %ld\n",
(long) (((unsigned long long) (i)) >> 32),
(long) i);
}
int main()
{
foo(3);
foo(-3);
}
I get this result when compiling in 64 bit mode:
0 3
4294967295 -3
And I get this result when compiling in 32 bit mode:
0 3
-1 -3
I have also attached the cutdown version of the original LTP test. On
my LP64 aarch64 system it prints:
fd = 3
val(1) = 0
val(2) = 40
val(3) = 0
val(4) = 40
val(5) = 0
When compiled in ILP32 mode on aarch64, it prints:
fd = 3
val(1) = 0
val(2) = 40
val(3) = 0
val(4) = 0
Gee, let's write something in the file!
41
val(5) = 0
Steve Ellcey
sellcey@cavium.com
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <limits.h>
char crmsg[] = "Gee, let's write something in the file!\n";
int main()
{
char fname[1024], buf[1024];
int x, fd, val;
strcpy(fname,"/tmp/foobar932");
fd = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0666);
printf("fd = %d\n", fd);
x = 0;
val = lseek(fd, x, 0);
printf("val(1) = %d\n", val);
val = write(fd, crmsg, sizeof(crmsg) - 1);
printf("val(2) = %d\n", val);
/* 1 == SEEK_CUR */
val = lseek(fd, -(sizeof(crmsg) - 1), 1);
printf("val(3) = %d\n", val);
val = read(fd, buf, sizeof(crmsg) - 1);
printf("val(4) = %d\n", val);
if (strncmp(crmsg, buf, sizeof(crmsg) - 1))
{
printf("%s\n", crmsg);
printf("%s\n", buf);
printf("%ld\n", sizeof(crmsg));
}
val = close(fd);
printf("val(5) = %d\n", val);
}