Hi guys,

(I'm not subscribed to the list, so please CC)

After digging through the buildd logs of libisoburn, we found out interesting compiler warnings on mips and mipsel.

https://buildd.debian.org/status/fetch.php?pkg=libisoburn&arch=mips&ver=1.1.8-1&stamp=1321892998

xorriso/iso_tree.c: In function 'Xorriso_fake_stbuf':
xorriso/iso_tree.c:256:4: warning: passing argument 4 of 'Xorriso_node_get_dev' from incompatible pointer type [enabled by default] xorriso/iso_tree.c:204:5: note: expected 'dev_t *' but argument is of type 'long unsigned int *' xorriso/iso_tree.c:259:4: warning: passing argument 4 of 'Xorriso_node_get_dev' from incompatible pointer type [enabled by default] xorriso/iso_tree.c:204:5: note: expected 'dev_t *' but argument is of type 'long unsigned int *'


Which basically means that st_rdev member of stat struct is not of type dev_t on mips and mipsel, which of course deviates from man 2 stat, that prescribes that st_rdev member (as well as st_dev member) of stat struct must be of type dev_t.

I wonder what could be wrong with the definition of the stat struct on mips/mipsel, it is a known flaw in libc, and whether it has anything to do with the situation of having 64-bit kernel and 32 bit userland, usually met on misp/mipsel.

Yes, the issue could be solved in the application side if one knows about the problem on these particular architectures (mips/mipsel), but I believe this is not the general case.


A simplified code demonstrating the issue:
~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

void func(dev_t *dev) {
   *dev=2;
}

int main() {
        struct stat ss;
        ss.st_rdev = 1;
        printf("ss.st_rdev %ld\n", ss.st_rdev);
        func( & (ss.st_rdev) );           // protested on mips{el}
dev_t dummy = ss.st_rdev; // work-around with a temp dev_t object
        func(&dummy);
        printf("ss.st_rdev %ld\n", ss.st_rdev);

        printf("sizeof st_rdev %u\n", sizeof(ss.st_rdev));
        printf("sizeof dev_t   %u\n", sizeof(dev_t));
        printf("sizeof __dev_t %u\n", sizeof(__dev_t));
        printf("sizeof ul  int %u\n", sizeof(unsigned long int));
        printf("sizeof ull int %u\n", sizeof(unsigned long long int));
        printf("sizeof stat    %u\n", sizeof(ss));

        return 0;
}


mips{el}
~~~~~~
$ gcc test.c
test.c: In function ‘main’:
test.c:14:2: warning: passing argument 1 of ‘func’ from incompatible pointer type [enabled by default] test.c:6:6: note: expected ‘dev_t *’ but argument is of type ‘long unsigned int *’

$ ./a.out
ss.st_rdev 1
ss.st_rdev 2
sizeof st_rdev 4
sizeof dev_t   8
sizeof __dev_t 8
sizeof ul  int 4
sizeof ull int 8
sizeof stat    144


amd64
~~~~
$ gcc test.c
$ ./a.out
ss.st_rdev 1
ss.st_rdev 2
sizeof st_rdev 8
sizeof dev_t   8
sizeof __dev_t 8
sizeof ul  int 8
sizeof ull int 8
sizeof stat    144



I tried to trace this type deviation of the stat dev_t members in the headers, but gave up, and tried to look at gcc -E output, where I realize that dev_t type is 'unsigned long long int', where stat.st_rdev is of type 'unsigned long int'


$ grep dev_t gcc-E
__extension__ typedef __u_quad_t __dev_t;
typedef __dev_t dev_t;

$ grep quad_t gcc-E
__extension__ typedef long long int __quad_t;
__extension__ typedef unsigned long long int __u_quad_t;
__extension__ typedef __u_quad_t __dev_t;
__extension__ typedef __u_quad_t __ino64_t;
__extension__ typedef __quad_t __off64_t;
__extension__ typedef __u_quad_t __rlim64_t;
__extension__ typedef __quad_t __blkcnt64_t;
__extension__ typedef __u_quad_t __fsblkcnt64_t;
__extension__ typedef __u_quad_t __fsfilcnt64_t;
typedef __quad_t *__qaddr_t;
typedef __quad_t quad_t;
typedef __u_quad_t u_quad_t;


--
pub 4096R/0E4BD0AB <people.fccf.net/danchev/key pgp.mit.edu>


--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]
Archive: http://lists.debian.org/[email protected]

Reply via email to