NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lib/54266: strange -m32 bug?

>Number:         54266
>Category:       lib
>Synopsis:       strange -m32 bug?
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jun 03 13:50:00 +0000 2019
>Originator:     Martin Husemann
>Release:        NetBSD 8.99.42
The NetBSD Foundation, Inc.
System: NetBSD 8.99.42 NetBSD 8.99.42 (GENERIC) #274: Fri May 31 07:45:03 CEST 2019 amd64
Architecture: x86_64
Machine: amd64

I ran into a very strange "COMPAT_NETBSD32" issue (but actually I am pretty
sure it is not the kernel at fault).


cd /var/tmp
dd if=/dev/zero of=disk.img seek=6g count=1
vnconfig -c vnd0 disk.img

then compile the program below, once with -m32 and once without.

Run both binaries with "vnd0" as argument and watch the number of total
sectors being clamped:

 # cc -Wall -I /work/src/sbin/fsck -O2 test.c /work/src/sbin/fsck/partutil.c -lprop -l util
 # ./a.out vnd0
disk vnd0:
        sec size: 512
        total secs: 6442450944
 # cc -m32 -Wall -I /work/src/sbin/fsck -O2 test.c /work/src/sbin/fsck/partutil.c -lprop -l util
 # ./a.out vnd0
disk vnd0:
        sec size: 512
        total secs: 4294967295

The implementation relies on the kernel copying out the disk geometry 
dictionary, and you can inspect that via drvctl -p vnd0, and compare it
to the output of a 32bit drvctl binary - which is the same. This is why
I think the kernel is doing the proper thing, but I have a hard time seing
where the difference in userland comes from.

The code works fine on a real i386 machine.

 * Compile with:
 *  cc -Wall -I /usr/src/sbin/fsck -O2 test.c /usr/src/sbin/fsck/partutil.c -lprop -lutil

#include <stdlib.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/disk.h>
#include <fcntl.h>
#include <util.h>
#include <errno.h>
#include <unistd.h>
#include "partutil.h"

get_disk_geom(const char *disk, struct disk_geom *d)
	char buf[1024];
	int fd, error;

 	if ((fd = opendisk(disk, O_RDONLY, buf, sizeof(buf), 0)) == -1)
		return 0;
	error = getdiskinfo(disk, fd, NULL, d, NULL);
	if (error < 0) {
		errno = error;
		return 0;
	return 1;

main(int argc, char **argv)
	struct disk_geom geo;

	if (argc != 2) {
		fprintf(stderr, "usage: %s (disk)\n", argv[0]);
		return 1;

	if (get_disk_geom(argv[1], &geo))
		printf("disk %s:\n\tsec size: %u\n\ttotal secs: %" PRIu64 "\n",
		    argv[1], geo.dg_secsize, geo.dg_secperunit);

	return 0;

totally puzzled - no idea.

Home | Main Index | Thread Index | Old Index