From owner-freebsd-current@FreeBSD.ORG Sat Jul 21 12:28:31 2012 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id D173A106566B; Sat, 21 Jul 2012 12:28:31 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from mail.zoral.com.ua (mx0.zoral.com.ua [91.193.166.200]) by mx1.freebsd.org (Postfix) with ESMTP id 6B1D68FC17; Sat, 21 Jul 2012 12:28:31 +0000 (UTC) Received: from skuns.kiev.zoral.com.ua (localhost [127.0.0.1]) by mail.zoral.com.ua (8.14.2/8.14.2) with ESMTP id q6LCSeiC009612; Sat, 21 Jul 2012 15:28:40 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: from deviant.kiev.zoral.com.ua (kostik@localhost [127.0.0.1]) by deviant.kiev.zoral.com.ua (8.14.5/8.14.5) with ESMTP id q6LCSRYP037781; Sat, 21 Jul 2012 15:28:27 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by deviant.kiev.zoral.com.ua (8.14.5/8.14.5/Submit) id q6LCSRbC037780; Sat, 21 Jul 2012 15:28:27 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: deviant.kiev.zoral.com.ua: kostik set sender to kostikbel@gmail.com using -f Date: Sat, 21 Jul 2012 15:28:27 +0300 From: Konstantin Belousov To: David Chisnall Message-ID: <20120721122827.GA2676@deviant.kiev.zoral.com.ua> References: <50097BF0.9010103@FreeBSD.org> <20120720163352.GS2676@deviant.kiev.zoral.com.ua> <9EBB4101-3117-4FE0-AD08-1053423BECD6@FreeBSD.org> <20120720231604.GT2676@deviant.kiev.zoral.com.ua> <8A03FF40-9A33-402F-AA01-E7C25EFF7430@freebsd.org> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="0hyMCxJS7FIePeVX" Content-Disposition: inline In-Reply-To: <8A03FF40-9A33-402F-AA01-E7C25EFF7430@freebsd.org> User-Agent: Mutt/1.4.2.3i X-Virus-Scanned: clamav-milter 0.95.2 at skuns.kiev.zoral.com.ua X-Virus-Status: Clean X-Spam-Status: No, score=-4.0 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00 autolearn=ham version=3.2.5 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on skuns.kiev.zoral.com.ua Cc: Dimitry Andric , freebsd-current@freebsd.org, Kim Culhan Subject: Re: -current build failure X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 21 Jul 2012 12:28:31 -0000 --0hyMCxJS7FIePeVX Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Sat, Jul 21, 2012 at 12:59:07PM +0100, David Chisnall wrote: > On 21 Jul 2012, at 00:16, Konstantin Belousov wrote: >=20 > > Ok, I stand corrected. But the standard does not say what you claim > > either. It only specifies that NULL pointer is unequal to any pointer > > to object or function (implicitely saying that you can create a C object > > or function pointer to which is equal to NULL). >=20 > See 6.5.3.2, paragraph 4. In particular: >=20 > > If an invalid value has been assigned to the pointer, the behavior of t= he unary * operator is undefined. >=20 > and then (footnote 87 from the same page): >=20 > > Among the invalid values for dereferencing a pointer by the unary * ope= rator are a null pointer >=20 >=20 > This clearly states that any dereference of the null pointer is explicitl= y invalid. You can look up the correct paragraph for the other reason your= self (that any valid pointer must be the result of pointer arithmetic on a = valid pointer). >=20 As I said in the followup, the C part of the code does not dereferences NULL at all. > > So, lets reformulate it other way: freestanding implementation in clang > > has no use, at least for general purpose kernel. >=20 > The term 'freestanding' has a well-defined meaning in the C specification= . It does not mean 'the C memory model doesn't apply', it means that there= is no underlying operating system providing facilities such as I/O. Compi= ling for a freestanding target does not let you opt out of the C memory mod= el. >=20 > > Especially ridiculous > > is the fact that clang throws it hands for asm inline wanting to get > > null address, on the machine with linearly addressable memory. >=20 > C is not a macro assembler, it is a well-defined (mostly) language with a= complex memory model. The relevant bit of code is: Yes, implementation that interprets the freestanding this way is not useful as a tool for implementing kernel. >=20 > > (*(char *)OFFSETOF_CURTHREAD) >=20 > This is dereferencing the NULL pointer if OFFSETOF_CURTHREAD is 0. If yo= u want to pass the 0 into the assembly then passing it as something other t= han a memory operand would make sense. Or, as the warning suggests, add a = volatile qualification to indicate that the asm is not actually dereferenci= ng this pointer. I want the code to generate exact "movq %gs:0,%" instruction, without using volatile, and using C-level constant with the value of offsetof(struct pcpu, pc_curthread), to be able to assert that assumptions of the assembler fragment did not changed. Your words about specifying immediate operand instead of memory reference almost inevitably results in asm-level expression like $0, not 0. At least I cannot write such asm constraint. You are welcome to provide the snippet. >=20 > However... >=20 > > The point of existence of the inline __pure2 __curthread() is to allow > > a compiler to cache the result of the call. Basically, the curthread > > dereference uses %gs basing, which typically adds a measurable penalty > > on the frontend and sometimes on the execution as well. >=20 > Clang designates address space 256 for GS-relative addressing (and 257 fo= r FS-relative addressing), so you don't need to use any assembly if all tha= t you want to do is load something relative to one of these segments. From= the clang manual: >=20 > > Annotating a pointer with address space #256 causes it to be code gener= ated relative to the X86 GS segment register, and address space #257 causes= it to be relative to the X86 FS segment. Note that this is a very very low= -level feature that should only be used if you know what you're doing (for = example in an OS kernel). > >=20 > > Here is an example: > >=20 >=20 > > #define GS_RELATIVE __attribute__((address_space(256))) > > int foo(int GS_RELATIVE *P) { > > return *P; > > } > >=20 > > Which compiles to (on X86-32): > >=20 > > _foo: > > movl 4(%esp), %eax > > movl %gs:(%eax), %eax > > ret >=20 > Using this instead of the inline asm allows the front end to perform > numerous optimisations because it no longer has a bit of magic embedded > in the middle of the code that the optimisers don't understand. Great, how to express a fetch of the struct thread * from gs-based offset 0 using this machinery and both avoiding NULL pointer dereference warning and avoiding an addition of volatile ? --0hyMCxJS7FIePeVX Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (FreeBSD) iEYEARECAAYFAlAKoGsACgkQC3+MBN1Mb4i2PgCdE3braxORLPvB3UeoA3WnRCbO B4AAn1QMVuT4ZaKvrq/xbhLlU4fvhbZU =yE/T -----END PGP SIGNATURE----- --0hyMCxJS7FIePeVX--