New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix compatibility with AARCH64 #101

Merged
merged 3 commits into from May 11, 2017

Conversation

Projects
None yet
3 participants
@etehtsea
Contributor

etehtsea commented May 10, 2017

I added/,odified Linux stat64 struct layouts according to pahole output:

xtest.c

#define _LARGEFILE_SOURCE 1

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <sys/stat.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
        struct stat sb;

        if (argc < 2)
        {
                fprintf(stderr, "Usage: %s: file ...\n", argv[0]);
                exit(EXIT_FAILURE);
        }

        for (int i = 1; i < argc; i++)
        {
                if (-1 == __xstat64(0, argv[i], &sb))
                {
                        perror("stat()");
                        exit(EXIT_FAILURE);
                }

                printf("%s:\n", argv[i]);
                printf("\tdev: %u\n", sb.st_dev);
                printf("\tinode: %u\n", sb.st_ino);
                printf("\tmode: %o\n", sb.st_mode);
                printf("\tlinks: %d\n", sb.st_nlink);
                printf("\towner: %u\n", sb.st_uid);
                printf("\tgroup: %u\n", sb.st_gid);
                printf("\trdev: %u\n", sb.st_rdev);
                printf("\tsize: %ld\n", sb.st_size);
                printf("\tblksize: %d\n", sb.st_blksize);
                printf("\tblkcnt: %ld\n", sb.st_blocks);
                printf("\tatime: %s", ctime(&sb.st_atim.tv_sec));
                printf("\tmtime: %s", ctime(&sb.st_mtim.tv_sec));
                printf("\tctime: %s", ctime(&sb.st_ctim.tv_sec));
                printf("\n");
        }

        return 0;
}

On AARCH64:

struct stat {
        __dev_t                    st_dev;               /*     0     8 */
        __ino_t                    st_ino;               /*     8     8 */
        __mode_t                   st_mode;              /*    16     4 */
        __nlink_t                  st_nlink;             /*    20     4 */
        __uid_t                    st_uid;               /*    24     4 */
        __gid_t                    st_gid;               /*    28     4 */
        __dev_t                    st_rdev;              /*    32     8 */
        __dev_t                    __pad1;               /*    40     8 */
        __off_t                    st_size;              /*    48     8 */
        __blksize_t                st_blksize;           /*    56     4 */
        int                        __pad2;               /*    60     4 */
        /* --- cacheline 1 boundary (64 bytes) --- */
        __blkcnt_t                 st_blocks;            /*    64     8 */
        struct timespec            st_atim;              /*    72    16 */
        struct timespec            st_mtim;              /*    88    16 */
        struct timespec            st_ctim;              /*   104    16 */
        int                        __glibc_reserved[2];  /*   120     8 */
        /* --- cacheline 2 boundary (128 bytes) --- */

        /* size: 128, cachelines: 2, members: 16 */
};

On X86_64:

struct stat {
	__dev_t                    st_dev;               /*     0     8 */
	__ino_t                    st_ino;               /*     8     8 */
	__nlink_t                  st_nlink;             /*    16     8 */
	__mode_t                   st_mode;              /*    24     4 */
	__uid_t                    st_uid;               /*    28     4 */
	__gid_t                    st_gid;               /*    32     4 */
	int                        __pad0;               /*    36     4 */
	__dev_t                    st_rdev;              /*    40     8 */
	__off_t                    st_size;              /*    48     8 */
	__blksize_t                st_blksize;           /*    56     8 */
	/* --- cacheline 1 boundary (64 bytes) --- */
	__blkcnt_t                 st_blocks;            /*    64     8 */
	struct timespec            st_atim;              /*    72    16 */
	struct timespec            st_mtim;              /*    88    16 */
	struct timespec            st_ctim;              /*   104    16 */
	__syscall_slong_t          __glibc_reserved[3];  /*   120    24 */
	/* --- cacheline 2 boundary (128 bytes) was 16 bytes ago --- */

	/* size: 144, cachelines: 3, members: 15 */
	/* last cacheline: 16 bytes */
};

This PR fixes jruby/jruby#4600

Show outdated Hide outdated src/main/java/jnr/posix/LinuxFileStat64.java
public final Unsigned32 st_mode = new Unsigned32();
public final Unsigned32 st_uid = new Unsigned32();
public final Unsigned32 st_gid = new Unsigned32();
public final Signed32 __pad0 = new Signed32();

This comment has been minimized.

@enebo

enebo May 10, 2017

Member

@etehtsea Is __pad0 missing from all 64 bit Linux systems? This seems like everything would be way off here if this were the case. Assuming it was ever tested against any other 64 bit linux.

@enebo

enebo May 10, 2017

Member

@etehtsea Is __pad0 missing from all 64 bit Linux systems? This seems like everything would be way off here if this were the case. Assuming it was ever tested against any other 64 bit linux.

This comment has been minimized.

@etehtsea

etehtsea May 11, 2017

Contributor

Originally I tried on Debian 8.8 / cc (Debian 4.9.2-10) 4.9.2 / Xeon E5620. At the moment I rechecked on CentOS 7.3.1611/ cc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11) / i7-4770HQ.

And also using clang on CentOS (clang version 3.4.2 (tags/RELEASE_34/dot2-final)) and got the same result everywhere.

P.S. I'm not sure but one C dev who I know said that this should be guaranteed by C ABI (https://en.m.wikipedia.org/wiki/Application_binary_interface).

@etehtsea

etehtsea May 11, 2017

Contributor

Originally I tried on Debian 8.8 / cc (Debian 4.9.2-10) 4.9.2 / Xeon E5620. At the moment I rechecked on CentOS 7.3.1611/ cc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11) / i7-4770HQ.

And also using clang on CentOS (clang version 3.4.2 (tags/RELEASE_34/dot2-final)) and got the same result everywhere.

P.S. I'm not sure but one C dev who I know said that this should be guaranteed by C ABI (https://en.m.wikipedia.org/wiki/Application_binary_interface).

This comment has been minimized.

@enebo

enebo May 11, 2017

Member

@etehtsea yeah I guess I am mostly asking because by ABI then this should have never worked until this PR. So that makes me wonder if some Linux variants are actually missing a field that the system you tested have (which might just be a literal pad).

Unfortunately, this structure since the very beginning has not had that extra 32 bit pad. We can probably land this as-is and write off the old code as a mistake but I will poke around and see if I can understand why there is a pad (or more importantly why we committed something without the pad).

@enebo

enebo May 11, 2017

Member

@etehtsea yeah I guess I am mostly asking because by ABI then this should have never worked until this PR. So that makes me wonder if some Linux variants are actually missing a field that the system you tested have (which might just be a literal pad).

Unfortunately, this structure since the very beginning has not had that extra 32 bit pad. We can probably land this as-is and write off the old code as a mistake but I will poke around and see if I can understand why there is a pad (or more importantly why we committed something without the pad).

This comment has been minimized.

@enebo

enebo May 11, 2017

Member

It seems like these pads are in for word alignment purposes. Our .java files are pretty old. I wonder if they corrected alignment of stat in the last 10 years and ours are out of date with newer linuxes. I see in FC25 the same pads. I wish history was documented better in software.

@enebo

enebo May 11, 2017

Member

It seems like these pads are in for word alignment purposes. Our .java files are pretty old. I wonder if they corrected alignment of stat in the last 10 years and ours are out of date with newer linuxes. I see in FC25 the same pads. I wish history was documented better in software.

This comment has been minimized.

@etehtsea

etehtsea May 11, 2017

Contributor

I made sure that StructLayout handles padding automatically so I updated PR.

@etehtsea

etehtsea May 11, 2017

Contributor

I made sure that StructLayout handles padding automatically so I updated PR.

etehtsea added some commits May 10, 2017

Fix failing spec on AARCH64
ioprioThreadedTest(jnr.posix.LinuxPOSIXTest)  Time elapsed: 0.038 sec  <<< ERROR!
java.lang.IllegalStateException: ioprio_set is not implemented in jnr-posix
        at jnr.posix.util.DefaultPOSIXHandler.unimplementedError(DefaultPOSIXHandler.java:28)
        at jnr.posix.LinuxPOSIX.ioprio_set(LinuxPOSIX.java:254)
        at jnr.posix.LinuxPOSIXTest.ioprioThreadedTest(LinuxPOSIXTest.java:44)

@enebo enebo merged commit 6335c46 into jnr:master May 11, 2017

1 of 2 checks passed

continuous-integration/travis-ci/pr The Travis CI build failed
Details
continuous-integration/appveyor/pr AppVeyor build succeeded
Details

@etehtsea etehtsea deleted the etehtsea:linux-file-stat64 branch May 11, 2017

@nirvdrum

This comment has been minimized.

Show comment
Hide comment
@nirvdrum

nirvdrum May 17, 2017

Contributor

What distribution are you using? I'm on Ubuntu 17.04 and this is off_t, not size_t.

What distribution are you using? I'm on Ubuntu 17.04 and this is off_t, not size_t.

This comment has been minimized.

Show comment
Hide comment
@etehtsea

etehtsea May 17, 2017

Contributor

Thank you!
#103

Contributor

etehtsea replied May 17, 2017

Thank you!
#103

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment