kern/180628: Make 32-bit i386 compilation work properly on AMD64

Jukka Ukkonen jau at iki.fi
Thu Jul 18 10:30:01 UTC 2013


>Number:         180628
>Category:       kern
>Synopsis:       Make 32-bit i386 compilation work properly on AMD64
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jul 18 10:30:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator:     Jukka Ukkonen
>Release:        9.2-PRERELEASE
>Organization:
-----
>Environment:
FreeBSD sleipnir 9.2-PRERELEASE FreeBSD 9.2-PRERELEASE #6 r253336M: Thu Jul 18 09:59:05 EEST 2013     root at sleipnir:/usr/obj/usr/src/sys/Sleipnir  amd64
>Description:
When building 32-bit compilations of anything needing int64_t sized integers
the current <machine/_types.h> defines such types as long or unsigned long.
These are clearly wrong. When -m32 is used as part of the compilation command
the proper definitions would be long long and unsigned long long as they are
defined for i386.

The proposed change should fix also kern/169187 and some other trouble tickets
referring to problems with 32-bit compilation on amd64.

The problem is simply that the current <machine/_types.h> is single mindedly
geared towards 64-bit environments, though, it should be tuned for both 64 and
32 bit binaries.

>How-To-Repeat:
Try compiling this code snippet on amd64 with and without -m32, run the
resulting binary, and compare the output of the two binaries...

#include <sys/types.h>
#include <sys/procset.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>

int
main (ac, av)
    int     ac;
    char    *av[];
{
    printf ("sizeof (id_t) == %lu\n", (unsigned long) sizeof (id_t));
    printf ("sizeof (int64_t) == %lu\n", (unsigned long) sizeof (int64_t));
    printf ("sizeof (long) == %lu\n", (unsigned long) sizeof (long));
    printf ("sizeof (long long) == %lu\n", (unsigned long) sizeof (long long));

    exit (0);
}

For a 64-bit binary you should see...

sizeof (id_t) == 8
sizeof (int64_t) == 8
sizeof (long) == 8
sizeof (long long) == 8

For a 32-bit binary the output is expected to be...

sizeof (id_t) == 4
sizeof (int64_t) == 4
sizeof (long) == 4
sizeof (long long) == 8

This causes a whole lot of unnecessary alignment issues as well
as truncated values among other problems.

>Fix:
Install sys/i386/include/_types.h to machine/_i386_types.h and
sys/amd64/include/_types.h to machine/_amd64_types.h.
Remember to hange the inclusion test macros to
_MACHINE__I386_TYPES_H_ and
_MACHINE__AMD64_TYPES_H_
in the beginning of the new header files.
Then replace the contents of the current machine/_types.h with this...

#ifndef _MACHINE__TYPES_H_
#define _MACHINE__TYPES_H_

#if defined(__amd64__)
#  include <machine/_amd64_types.h>
#else
#  include <machine/_i386_types.h>
#endif

#endif /* !_MACHINE__TYPES_H_ */

and magically 32-bit compilations should start coming out just fine.

When -m32 is given on the command line the __amd64__ macro will no longer
be defined during compilation. So, the correctly tuned type definition will
be included automatically.




>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list