amd64/119771: troubles w/ -m32 executables on both amd64 and i386

A.Yu.Isupov isupov at moonhe.jinr.ru
Sat Jan 19 10:50:02 PST 2008


The following reply was made to PR amd64/119771; it has been noted by GNATS.

From: "A.Yu.Isupov" <isupov at moonhe.jinr.ru>
To: bug-followup at FreeBSD.org
Cc: swhetzel at gmail.com
Subject: Re: amd64/119771: troubles w/ -m32 executables on both amd64
    and i386
Date: Sat, 19 Jan 2008 21:28:45 +0300 (MSK)

 *From:*	"Scot Hetzel" <swhetzel at gmail.com>
 *Date:*	Fri, 18 Jan 2008 10:07:26 -0600
 
 >Currently, building i386 programs under FreeBSD/amd64 is not
 >supported. The reason for this is you need the i386 includes to build
 >your program, but they are not installed during a installworld (see
 >stage 5.1 in src/Makefile.inc1).
 
   I assume, that all needed includes are the same under amd64 and i386...
 Problems are not connected with sizeof(int) or prototyping.
   Unfortunately, I can't port my program (that is cernlib) to 64-bit
 (I try !), because one intensively uses int (and integer*4 :) to store
 pointers, so I need to compile it in 32-bit environment - if possible,
 on FreeBSD/amd64, if not - I should choose to continue using the
 FreeBSD/i386 on 64-bit CPU :(
   Note, that Sun's OpenLook (ports/x11-toolkits/xview{,-clients}) compiled,
 but not work under amd64 for the same reasons - pointer should fit into int.
 However 32-bit binaries are OK.
   At least, I encounter too less problematic places (really two - syscalls
 getrlimit() and lseek(), see below) during 32-bit compiling in comparison with
 porting to 64-bit...
 
 >It's not clear in your report, are you recompiling the program under
 >i386, or copying the binary from FreeBSD/amd64 to the FreeBSD/i386
 >system?
 
   Failed binary produced under FreeBSD/amd64 as static w/ -m32
 and executed on FreeBSD/amd64 and (after copying :) on FreeBSD/i386 -
 with the same faulty results.
 
 >If you build your program under FreeBSD/i386, does your program run
 >without these problems on i386 and amd64?
 
   Yes, binary produced under FreeBSD/i386 as static have not a problem
 during execution under both FreeBSD/i386 and FreeBSD/amd64.
 
   So I conclude, that problem possibly in FreeBSD/amd64's 32-bit
 compatibility support, at least in syscall getrlimit().
 
   Furthermore, I have now yet another example of faulty syscall - lseek().
 Example text (see below) compiled natively under i386 and amd64 works as
 expected (outputs the same):
 
 i386> ./tseek.32
 or
 amd64> ./tseek.64
 
 fildes=3, nbdo=0
 isw=0, errno=0
 1 stat=0
 1 write(): res=4096, errno=0
 fildes=3, nbdo=8192
 isw=8192, errno=0
 2 stat=0
 2 write(): res=4096, errno=0
 fildes=3, nbdo=4096
 isw=4096, errno=0
 3 stat=0
 3 write(): res=4096, errno=0
 
   However compiled under amd64 as
 
 	cc -c -g -W -Wall -m32 -o tseek.o tseek.c
 	cc -c -g -W -Wall -m32 -o cfseek.o cfseek.c
 	cc -g -W -Wall -m32 -static -B/usr/lib32 -o tseek tseek.o cfseek.o
 
 says:
 
 amd64> ./tseek.32on64
 fildes=3, nbdo=0
 isw=0, errno=0
 1 stat=0
 1 write(): res=4096, errno=0
 fildes=3, nbdo=8192
 isw=-1, errno=22
  error in CFSEEK: Invalid argument
 2 stat=-1
 2 write(): res=4096, errno=0
 fildes=3, nbdo=4096
 isw=-1, errno=22
  error in CFSEEK: Invalid argument
 3 stat=-1
 3 write(): res=4096, errno=0
 
   Produced output file shows, that lseek() really does nothing when failed.
 
   Note, that effect also subtle and depends on statements near (before and
 after) lseek(), and totally absent in simplified example, where wrapper
 cfseek_() eliminated.
 
 -----cut here-tseek.c----
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <string.h>
 #include <strings.h>
 
 void cfseek_(int *lundes, int *medium, int *nwrec, int *jcrec, int *stat);
 
 int
 main()
 {
 	int fd;
 	int medium=0, nwrec, jcrec, stat=0;
 	off_t res=0;
 	char mbuf[4096];
 
 	errno = 0;
 	fd = open("./seek.dat", O_RDWR|O_TRUNC|O_CREAT, 0644);
 	if (fd==-1) {
 		printf("open(): %i\n", errno);
 		exit(1);
 	}
 
 	nwrec = 2;
 	jcrec = 0;
 	cfseek_(&fd, &medium, &nwrec, &jcrec, &stat);
 	printf("1 stat=%i\n", stat);
 
 	bzero((void *)mbuf, sizeof(mbuf));
 	strcpy(mbuf, "1wertyui");
 	strcpy(&mbuf[4088], "1xcvbnm");
 	errno = 0;
 	res = write(fd, mbuf, 4096);
 	printf("1 write(): res=%i, errno=%i\n", res, errno);
 
 	nwrec = 2;
 	jcrec = 1024;
 	cfseek_(&fd, &medium, &nwrec, &jcrec, &stat);
 	printf("2 stat=%i\n", stat);
 
 	bzero((void *)mbuf, sizeof(mbuf));
 	strcpy(mbuf, "2wertyui");
 	strcpy(&mbuf[4088], "2xcvbnm");
 	errno = 0;
 	res = write(fd, mbuf, 4096);
 	printf("2 write(): res=%i, errno=%i\n", res, errno);
 
 	nwrec = 1;
 	jcrec = 1024;
 	cfseek_(&fd, &medium, &nwrec, &jcrec, &stat);
 	printf("3 stat=%i\n", stat);
 
 	bzero((void *)mbuf, sizeof(mbuf));
 	strcpy(mbuf, "3wertyui");
 	strcpy(&mbuf[4088], "3xcvbnm");
 	errno = 0;
 	res = write(fd, mbuf, 4096);
 	printf("3 write(): res=%i, errno=%i\n", res, errno);
 
 	close(fd);
 
 	exit(0);
 }
 -----cut here-----
 
 -----cut here-cfseek.c----
 #define	NBYTPW	4
 
 #include <sys/types.h>
 #include <unistd.h>
 
 #include <stdio.h>
 #include <errno.h>
 
 void cfseek_(lundes, medium, nwrec, jcrec, stat)
       int  *lundes, *medium, *nwrec, *jcrec, *stat;
 {
       int  fildes;
       off_t  nbdo;
       off_t  isw;
 
 	errno = 0;
       fildes = *lundes;
       nbdo   = *jcrec * *nwrec * NBYTPW;
 	fprintf(stderr, "fildes=%i, nbdo=%i\n", fildes, nbdo);
       isw    = lseek (fildes, nbdo, SEEK_SET);
 	fprintf(stderr, "isw=%i, errno=%i\n", isw, errno);
       if (isw <  0)                goto trouble;
       *stat = 0;
       return;
 
 trouble:  *stat = -1;
           perror (" error in CFSEEK");
           return;
 }
 -----cut here-----
 
     Isupov A.
 


More information about the freebsd-amd64 mailing list