Subject: Re: new sysctl(KERN_PROC, ...) interface (was: sysinfo(2))
To: Simon Burge <simonb@netbsd.org>
From: Eduardo Horvath <eeh@turbolinux.com>
List: tech-kern
Date: 04/17/2000 19:46:51
On Tue, 18 Apr 2000, Simon Burge wrote:
> matthew green wrote:
>
> >
> > > #define PTRTOINT64(foo) ((u_int64_t)(long)(foo))
> >
> > That's not.
> >
> >
> > right. one should always use unsigned long in these case. adding
> > a (u_long) fixes *many* warnings :-)
>
> uintptr_t? :)
>
> Anyways, how much is this a problem in the real world? The program at
> the end when run on i386 and pmax gives:
>
> a = (int64_t)(intptr_t)-1 = 0xffffffffffffffff
> b = (u_int64_t)(intptr_t)-1 = 0xffffffffffffffff
> c = (int64_t)(uintptr_t)-1 = 0xffffffff
> d = (u_int64_t)(uintptr_t)-1 = 0xffffffff
> (void *)(intptr_t)a = 0xffffffff
> (void *)(intptr_t)b = 0xffffffff
> (void *)(intptr_t)c = 0xffffffff
> (void *)(intptr_t)d = 0xffffffff
> (void *)(uintptr_t)a = 0xffffffff
> (void *)(uintptr_t)b = 0xffffffff
> (void *)(uintptr_t)c = 0xffffffff
> (void *)(uintptr_t)d = 0xffffffff
>
> and on alpha give:
>
> a = (int64_t)(intptr_t)-1 = 0xffffffffffffffff
> b = (u_int64_t)(intptr_t)-1 = 0xffffffffffffffff
> c = (int64_t)(uintptr_t)-1 = 0xffffffffffffffff
> d = (u_int64_t)(uintptr_t)-1 = 0xffffffffffffffff
> (void *)(intptr_t)a = 0xffffffffffffffff
> (void *)(intptr_t)b = 0xffffffffffffffff
> (void *)(intptr_t)c = 0xffffffffffffffff
> (void *)(intptr_t)d = 0xffffffffffffffff
> (void *)(uintptr_t)a = 0xffffffffffffffff
> (void *)(uintptr_t)b = 0xffffffffffffffff
> (void *)(uintptr_t)c = 0xffffffffffffffff
> (void *)(uintptr_t)d = 0xffffffffffffffff
>
> So for these platforms at least we can cast any long to any int64 and
> get away with it. Can you (or Eric) provide results on sparc, sparc64
> and sparc64/compat32?
I don't think that this will demonstrate much but here goes:
32-bit mode:
a = (int64_t)(intptr_t)-1 = 0xffffffffffffffff
b = (u_int64_t)(intptr_t)-1 = 0xffffffffffffffff
c = (int64_t)(uintptr_t)-1 = 0xffffffff
d = (u_int64_t)(uintptr_t)-1 = 0xffffffff
(void *)(intptr_t)a = 0xffffffff
(void *)(intptr_t)b = 0xffffffff
(void *)(intptr_t)c = 0xffffffff
(void *)(intptr_t)d = 0xffffffff
(void *)(uintptr_t)a = 0xffffffff
(void *)(uintptr_t)b = 0xffffffff
(void *)(uintptr_t)c = 0xffffffff
(void *)(uintptr_t)d = 0xffffffff
64-bit mode:
a = (int64_t)(intptr_t)-1 = 0xffffffffffffffff
b = (u_int64_t)(intptr_t)-1 = 0xffffffffffffffff
c = (int64_t)(uintptr_t)-1 = 0xffffffffffffffff
d = (u_int64_t)(uintptr_t)-1 = 0xffffffffffffffff
(void *)(intptr_t)a = 0xffffffffffffffff
(void *)(intptr_t)b = 0xffffffffffffffff
(void *)(intptr_t)c = 0xffffffffffffffff
(void *)(intptr_t)d = 0xffffffffffffffff
(void *)(uintptr_t)a = 0xffffffffffffffff
(void *)(uintptr_t)b = 0xffffffffffffffff
(void *)(uintptr_t)c = 0xffffffffffffffff
(void *)(uintptr_t)d = 0xffffffffffffffff
Emul-32:
a = (int64_t)(intptr_t)-1 = 0xffffffffffffffff
b = (u_int64_t)(intptr_t)-1 = 0xffffffffffffffff
c = (int64_t)(uintptr_t)-1 = 0xffffffff
d = (u_int64_t)(uintptr_t)-1 = 0xffffffff
(void *)(intptr_t)a = 0xffffffff
(void *)(intptr_t)b = 0xffffffff
(void *)(intptr_t)c = 0xffffffff
(void *)(intptr_t)d = 0xffffffff
(void *)(uintptr_t)a = 0xffffffff
(void *)(uintptr_t)b = 0xffffffff
(void *)(uintptr_t)c = 0xffffffff
(void *)(uintptr_t)d = 0xffffffff
The problem is when you take a real 32-bit address, extend it to 64-bits,
then pass it to a 64-bit application to dereference.
A valid address of 0xf100000 (which is the current stack base) needs to be
referenced as 0x00000000f1000000 from a 64-bit application on sparc64
cause that's how the hardware works. 0xfffffffff1000000, while a valid
32-bit address, is not the one that the hardware generates in 32-bit mode.
Eduardo Horvath