Date: Sat, 21 Jul 2012 15:28:27 +0300 From: Konstantin Belousov <kostikbel@gmail.com> To: David Chisnall <theraven@freebsd.org> Cc: Dimitry Andric <dim@freebsd.org>, freebsd-current@freebsd.org, Kim Culhan <w8hdkim@gmail.com> Subject: Re: -current build failure Message-ID: <20120721122827.GA2676@deviant.kiev.zoral.com.ua> In-Reply-To: <8A03FF40-9A33-402F-AA01-E7C25EFF7430@freebsd.org> References: <CAKZxVQV5xhFDN_WbTk-EMoQ18N8u1f4YhqKSJQFUzbX4NZxhUA@mail.gmail.com> <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>
next in thread | previous in thread | raw e-mail | index | archive | help
--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,%<any reg>" 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--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120721122827.GA2676>