From owner-svn-src-all@freebsd.org Tue Nov 10 17:50:58 2015 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 12A15A2CB96; Tue, 10 Nov 2015 17:50:58 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from mail110.syd.optusnet.com.au (mail110.syd.optusnet.com.au [211.29.132.97]) by mx1.freebsd.org (Postfix) with ESMTP id C40CE1306; Tue, 10 Nov 2015 17:50:57 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from c211-30-166-197.carlnfd1.nsw.optusnet.com.au (c211-30-166-197.carlnfd1.nsw.optusnet.com.au [211.30.166.197]) by mail110.syd.optusnet.com.au (Postfix) with ESMTPS id EA952781041; Wed, 11 Nov 2015 04:50:52 +1100 (AEDT) Date: Wed, 11 Nov 2015 04:50:52 +1100 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: Conrad Meyer cc: Hans Petter Selasky , Ian Lepore , src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r290613 - head/sys/compat/linuxkpi/common/include/linux In-Reply-To: Message-ID: <20151111033555.P2914@besplex.bde.org> References: <201511091650.tA9Gog7d061645@repo.freebsd.org> <20151110080516.M4088@besplex.bde.org> <5641A056.2040805@selasky.org> <1447168083.91061.2.camel@freebsd.org> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.1 cv=R4L+YolX c=1 sm=1 tr=0 a=KA6XNC2GZCFrdESI5ZmdjQ==:117 a=PO7r1zJSAAAA:8 a=JzwRw_2MAAAA:8 a=nlC_4_pT8q9DhB4Ho9EA:9 a=6I5d2MoRAAAA:8 a=qW0Wa05-ZPK7qB2RKggA:9 a=45ClL6m2LaAA:10 Content-Type: TEXT/PLAIN; charset=X-UNKNOWN; format=flowed Content-Transfer-Encoding: QUOTED-PRINTABLE X-Content-Filtered-By: Mailman/MimeDel 2.1.20 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 10 Nov 2015 17:50:58 -0000 On Tue, 10 Nov 2015, Conrad Meyer wrote: > On Tue, Nov 10, 2015 at 7:08 AM, Ian Lepore wrote: >> On Tue, 2015-11-10 at 08:44 +0100, Hans Petter Selasky wrote: >>>> -sysctl_root_handler_locked(struct sysctl_oid *oid, void *arg1, >>>> intptr_t arg2, >>>> +sysctl_root_handler_locked(struct sysctl_oid *oid, void *arg1, >>>> intmax_t arg2, >>>> struct sysctl_req *req, struct rm_priotracker *tracker) >>> >>> Given that the second argument is sometimes used for pointers, maybe >>> we >>> should keep it intptr_t. Or add a compile time assert that >>> sizeof(intmax) >=3D sizeof(intptr_t) which I think doesn't hold? >> >> If intmax_t is the "maximum width integer type" and intptr_t is >> "integer type capable of holding a pointer", I think by definition >> sizeof(intmax_t) must be >=3D sizeof(intptr_t). intmax_t isn't the "maximum width integer type". It is a "signed integer type capable of representing any value of any signed integer type (includin= g extended ones). This imples that INTMAX_MAX >=3D INTPTR_MAX but not that sizeof(intmax_t) >=3D sizeof(intptr_t) or that rankof(intmax_t) >=3D rankof(intptr_t). intptr_t may have more padding bit= s than intmax_t. In FreeBSD, rankof(intmax_t) >=3D rankof(intptr_t), but rankof(intmax_t) doesn't have maximum rank. It is smaller than the long long abomination in rank on all 64-bit arches All arches declare intmax_t as int64_t, and this has to be long_long_abomination_t on 32-bit arches (except I made it a magic gcc type in old versions of FreeBSD and C where long long was a syntax error), but intmax_t is always plain long on 64 bit arches. In terms of rank, intptr_t =3D=3D int64_t =3D=3D intmax_t < long_long_abomination_t on 64-bit arches, and intptr_t < int64_t =3D=3D intmax_t =3D=3D long_long_abomination_t on 32-bit= arches. >> On the other hand, given >> the perverse way standards-writers think, I'm not sure "big enough" is >> all it takes to qualify as "capable of holding a pointer". But I think >> in reality it'll work out right anyway. Only on vaxes, unless you write correct code. E.g., consider the following reasonable implementation: - pointers have 64 bits, consisting of 32 high address bits and 32 low low type bits - the type bits for void have value 1=20 - intmax_t is also 64 bits - intptr_t is 32 bits (the type bits need not be represented because they are always 1) - conversion from void * to intmax_t then can and should be to copy all the bits. The void * pointer kernbase with bits 0xc000000000000001 gives the same bit when converted to intmax_t. The reversion conversion also copies the bits. - conversion from void * to intmax_t must reduce to 32 bits. It can and should do this in the obvious way by discarding the low type bits and shifting the top bits to the low bits. The kernbase becomes 0xc00000000 when converted to intptr_t. The reverse conversion shifts the addres bits back and sets the type bits to their known value for void *. Then wrong code breaks nicely. (intptr_t)(intmax_t)kernbase gives 1 and there is obviously no way to convert this back to kernbase. To use intmax_t for kernbase, you have write (intmax_t)(intptr_t)kernbase. This has value 0xc0000000. Then to get back to void *, first cast back to intptr_t. Qualified pointers to void are required to work too. In the above implementation, they should have different type bits and some only difference is that casting back must restore different type bits. Conversions of other pointers are not required to work, but would work accidentally. All the type info needed to recover the original type bits is in the cast back (provided it is really back to the same type). > +1 to what Ian said. > > In any C99 implementation where intptr_t is defined, I believe > intmax_t must be at least as big. See =C2=A7 7.18.1.5, "Greatest-width > integer types," and =C2=A7 7.18.1.4, "Integer types capable of holding > object pointers." >=20 >> The following type designates a signed integer type with the property th= at any valid pointer to void can be converted to this type, then converted = back to pointer to void, and the result will compare equal to the original = pointer: intptr_t Note that it only requires working when the conversion is to this type. Any conversion from a pointer to int may involve some reduction or reordering of the bits. The conversion might depend on the type of both the integer and the pointer in more complicated ways than the above. The requirement that the conversions are not required to work for all "large enough" types makes things simpler for everyone. >> The following type designates a signed integer type capable of represent= ing any value of any signed integer type: intmax_t > > Given that intptr_t exists in our implementation and is a signed > integer type, I see no reason why intmax_t could possibly not > represent any such value. Same argument for the unsigned variants. It can only represent integers directly. intptr_t is only required to represent pointers with some unique encoding. Other integer types are only required to represent (via conversion) pointers with some encoding. The encoding is not required to be unique. 0 for everything is a valid encoding and might be used to detect bugs or just accidentally for optimization. Bruce From owner-svn-src-all@freebsd.org Tue Nov 10 18:23:14 2015 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 7A954A2B4C0; Tue, 10 Nov 2015 18:23:14 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from mail109.syd.optusnet.com.au (mail109.syd.optusnet.com.au [211.29.132.80]) by mx1.freebsd.org (Postfix) with ESMTP id 370561B4E; Tue, 10 Nov 2015 18:23:13 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from c211-30-166-197.carlnfd1.nsw.optusnet.com.au (c211-30-166-197.carlnfd1.nsw.optusnet.com.au [211.30.166.197]) by mail109.syd.optusnet.com.au (Postfix) with ESMTPS id CEBC4D641AE; Wed, 11 Nov 2015 05:23:05 +1100 (AEDT) Date: Wed, 11 Nov 2015 05:23:04 +1100 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: Justin Hibbits cc: cem@freebsd.org, Hans Petter Selasky , Ian Lepore , src-committers , "svn-src-all@freebsd.org" , "svn-src-head@freebsd.org" Subject: Re: svn commit: r290613 - head/sys/compat/linuxkpi/common/include/linux In-Reply-To: Message-ID: <20151111051325.S3235@besplex.bde.org> References: <201511091650.tA9Gog7d061645@repo.freebsd.org> <20151110080516.M4088@besplex.bde.org> <5641A056.2040805@selasky.org> <1447168083.91061.2.camel@freebsd.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.1 cv=cK4dyQqN c=1 sm=1 tr=0 a=KA6XNC2GZCFrdESI5ZmdjQ==:117 a=PO7r1zJSAAAA:8 a=JzwRw_2MAAAA:8 a=kj9zAlcOel0A:10 a=6I5d2MoRAAAA:8 a=8_tSZztaHGgigfQZgVQA:9 a=CjuIK1q_8ugA:10 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 10 Nov 2015 18:23:14 -0000 On Tue, 10 Nov 2015, Justin Hibbits wrote: > On Tue, Nov 10, 2015 at 9:42 AM, Conrad Meyer wrote: >> ... >> Given that intptr_t exists in our implementation and is a signed >> integer type, I see no reason why intmax_t could possibly not >> represent any such value. Same argument for the unsigned variants. > > I may be wrong on this, but I *think* uintptr_t/intptr_t are required > to be *precisely* the same size as a pointer, which explains why you > can't cast directly from uintmax_t on 32-bit architectures. Good compilers use the size for a simple portability check. They should also complain if the types are different but have the same size, as is done for int vs long format mismatches on i386. Bruce