[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v6 1/4] xen: introduce SYMBOL

On Wed, 16 Jan 2019, Jan Beulich wrote:
> >>> On 15.01.19 at 21:03, <Stewart.Hildebrand@xxxxxxxxxxxxxxx> wrote:
> > On Tuesday, January 15, 2019 3:21 AM, Jan Beulich wrote:
> >> The thing that I don't understand though is how the undefined
> >> behavior (if there really is any) goes away: Even if you compare
> >> the contents of the variables instead of the original (perhaps
> >> casted) pointers, in the end you still compare what C would
> >> consider pointers to different objects. It's merely a different
> >> way of hiding that fact from C. Undefined behavior would imo
> >> go away only if those comparisons/subtractions didn't happen
> >> in C anymore. IOW - see my .startof.() / .sizeof.() proposal.
> > 
> > No, the C standard provides us a guarantee.
> > 
> > To quote the ISO/IEC 9899 C99 standard regarding the subtract operator:
> >> For subtraction, one of the following shall hold:
> >> - both operands have arithmetic type;
> >> - both operands are pointers to qualified or unqualified versions of
> >>   compatible object types; or
> >> - the left operand is a pointer to an object type and the right operand
> >>   has integer type.
> >> 
> >> If both operands have arithmetic type, the usual arithmetic conversions
> >> are performed on them.
> >> 
> >> When an expression that has integer type is added to or subtracted from
> >> a pointer ... If both the pointer operand and the result point to
> >> elements of the same array object, or one past the last element of the
> >> array object, the evaluation shall not produce an overflow; otherwise,
> >> the behavior is undefined.
> > 
> > Here, "arithmetic type" is either integer type or floating point type (but
> > NOT pointer type).
> > 
> > There is similar language for the equality comparison operator that
> > Stefano quoted earlier in the thread.
> > 
> > My interpretation of the standard is:
> > Subtract/compare operations where one or both operands are pointer types
> > are potentially subject to the "pointers to different objects" issue, and
> > the compiler is free to make that determination by any means available.
> > Subtract/compare operations where both operands are integer types are well
> > defined in the C standard, and, per the C standard, are NOT subject to the
> > "pointers to different objects" issue. If the compiler starts to consider
> > integer types being "pointers to different objects" then the compiler
> > clearly does not adhere to the C standard. The compiler may look through
> > *pointer type* casts, but if it started to look through *integer type*
> > casts, we would have good reason to complain to the GCC mailing list.
> All fine. Yet wasn't it you who suggested that a future, very smart
> compiler could "look through" casts and even inline assembly? 

Yes, that is because we were doing:

  pointers -- (asm) --> pointers
  pointers -- (asm) --> unsigned long

Either way there were pointers to start with, plus some asm obfuscation.
Stewart's approach is very different.  More on this below.

> Of
> course subtraction and comparison of arithmetic types is well
> defined. The question is whether this also holds for pointers
> casted to such types. Let's not forget that in the abstract case,
> casting a pointer to an integral type may be lossy, and subtraction
> of two such casted values may not represent what you'd expect
> it to be.
> The best way to demonstrate this are the historic large and huge
> memory models on 16-bit x86. Pointers are comprised of a
> segment/selector and an offset there. When the former is a
> segment (real or vm86 modes), conversion can be done such that
> the difference is "meaningful" in our sense. When it's a selector,
> otoh, I can't think of a conversion that would allow meaningful
> comparison / subtraction. Even worse, two entirely distinct
> pointers (different selectors referring to descriptors with
> different base addresses) may point at the same object.
> Luckily we don't have to consider such obscure environments
> (and hence we can make certain implications), but the C standard
> has to.
> In any event - since intermediate variables merely hide the
> casting from the compiler, but they don't remove the casts, the
> solution involving casts is better imo, for incurring less overhead.

This is where I completely disagree. The intermediate variables are not
hiding casts from the compiler. There were never any pointers in this
case.  The linker creates "symbols", not pointers, completely invisible
from C land. Assembly uses these symbols to initialize variables. We
expose these assembly variables as integer to C lands. LD scripts and
assembly have their own terminology and rules: neither "_start" nor
"start" are pointers at any point in time. The operations done in var.S
is not a cast. The C spec is happy, the compiler is happy, MISRA-C is
happy. And we get to avoid the ugly SYMBOL macro that Linux uses. It is
really a win-win.

Xen-devel mailing list



Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.