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