Re: -current build failure

From: David Chisnall <theraven_at_freebsd.org>
Date: Sat, 21 Jul 2012 12:59:07 +0100
On 21 Jul 2012, at 00:16, Konstantin Belousov wrote:

> 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).

See 6.5.3.2, paragraph 4.  In particular:

> If an invalid value has been assigned to the pointer, the behavior of the unary * operator is undefined.

and then (footnote 87 from the same page):

> Among the invalid values for dereferencing a pointer by the unary * operator are a null pointer


This clearly states that any dereference of the null pointer is explicitly invalid.  You can look up the correct paragraph for the other reason yourself (that any valid pointer must be the result of pointer arithmetic on a valid pointer).

> So, lets reformulate it other way: freestanding implementation in clang
> has no use, at least for general purpose kernel.

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.  Compiling for a freestanding target does not let you opt out of the C memory model.

> 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.

C is not a macro assembler, it is a well-defined (mostly) language with a complex memory model.  The relevant bit of code is:

>  (*(char *)OFFSETOF_CURTHREAD)

This is dereferencing the NULL pointer if OFFSETOF_CURTHREAD is 0.  If you want to pass the 0 into the assembly then passing it as something other than a memory operand would make sense.  Or, as the warning suggests, add a volatile qualification to indicate that the asm is not actually dereferencing this pointer.

However...

> 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.

Clang designates address space 256 for GS-relative addressing (and 257 for FS-relative addressing), so you don't need to use any assembly if all that you want to do is load something relative to one of these segments.  From the clang manual:

> Annotating a pointer with address space #256 causes it to be code generated 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).
> 
> Here is an example:
> 

> #define GS_RELATIVE __attribute__((address_space(256)))
> int foo(int GS_RELATIVE *P) {
>   return *P;
> }
> 
> Which compiles to (on X86-32):
> 
> _foo:
> 	movl	4(%esp), %eax
> 	movl	%gs:(%eax), %eax
> 	ret

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.

David
Received on Sat Jul 21 2012 - 09:59:15 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:29 UTC