Bug #1450: Illumos should be buildable with GCC4
i86 kernel should be more careful when casting pointers
As with the changes to cpr made in #1865, there are other portions of the i86 kernel which cast pointers in a manner which gcc4 warns about (and which we tried to get gcc3 to warn about)
1. mp_pc should cast pointers to uintptr_t, do math, and then truncate to 32bit for realmode access, as was done to cpr for #1865
2. dboot_startkern should cast through uintptr_t when assigning current pointers to native_ptr_t (this will be explained below)
3. GATESEG_GETOFFSET should cast to uintptr_t in general.
4. GATESEG_GETOFFSET should be careful when shifting a component value by 32 places that the resulting type is guaranteed to be greater than 32bits wide (which GCC believes it is not).
Point 2 is perhaps confusing, so I'm going to go into painful detail (and hope I get it all right!)
Initially, with newboot, we had a separate 'multiboot' executable which spoke the multiboot protocol on one side, and did what unix requires on the other. This was grand. As a pre-cursor to Xen the dboot (Direct Boot) project integrated, which made unix directly bootable. However this is not direct in the traditional sense, but is instead the disk-file, 'unix' being itself bootable. The executable 'unix' as you probably think of it still is not. What happens is that the loader, not entirely dissimilar to the multiboot loader mentioned above is placed into the unix executable as an otherwise entirely separate entity, at the address multiboot requires, and linked such as to be identity mapped. This means that on i86pc, this portion of unix is always 32bit, regardless of the rest of the unix. Thus, within dboot, actual pointers are 32bit and we use native_ptr_t to refer to a potentially 64bit machine pointer. With i86xpv, the ABI of dboot matches that of unix. 32bit i86pc also, of course, matches.
GCC is very picky about pointer casts because:
- Casting to a smaller type may lose information in truncation (as we all known)
- It may sign-extend the pointer if casting to a larger integer type, see http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Arrays-and-pointers-implementation.html, replace 3.4.6 with 4.4.4, 4.6.2, as desirable.