Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trap Representation, unsigned char and IA64 NaT

Tags:

c

Source:Uninitialized garbage on ia64 can be deadly

On the ia64, each 64-bit register is actually 65 bits. The extra bit is called "NaT" which stands for "not a thing". The bit is set when the register does not contain a valid value. Think of it as the integer version of the floating point NaN.

The NaT bit gets set most commonly from speculative execution. There is a special form of load instruction on the ia64 which attempts to load the value from memory, but if the load fails (because the memory is paged out or the address is invalid), then instead of raising a page fault, all that happens is that NaT bit gets set, and execution continues.

All mathematical operations on NaT just produce NaT again.

The source article went on to explain how a register could end up having a NaT representation during speculative loading and makes the following remark:

For you see, if you have a register whose value is NaT and you so much as breathe on it the wrong way (for example, try to save its value to memory), the processor will raise a STATUS_REG_NAT_CONSUMPTION exception.

it seems from other stack overflow answers to Trap representations that,
"Any type (except unsigned char) may have trap representations".

This link says that

The only guarantees the standard gives about accessing uninitialized data are that the unsigned char type has no trap representations, and that padding has no trap representations.

If such a register ( a register with NaT bit Set) is allocated for storing an uninitialized unsigned char ( similar to the code fragment from the defect report below), how is this handled according to ISO C11?

Is the defect report below points to the same problem and is it rectified in ISO C11?

If not how this special case is handled?

If the lvalue designates an object of automatic storage duration that could have been declared with register storage class (never had its address taken), and that object is uninitialized (not declared with an initializer, and no assignment to it has been performed prior to the use), the behavior is undefined

does the above addition at the end of the defect report in section "change for C1X" handle this case?

defect_report

The following function has undefined behavior under C90, but appears to be strictly conforming under C99

  int foo(void) {
      unsigned char uc;
      return uc + 1 >= 0;
  }
like image 410
bare_metal Avatar asked Oct 19 '14 15:10

bare_metal


1 Answers

First thing, if you haven't seen it for yourself, you can grab the final draft of the C11 standard from here (see also).

The text from the DR was indeed added to section 6.3.2.1 p2, which makes the code snipped undefined according to C11.

The sections in the standard about trap representations continue to exclude the possibility that unsigned char can have a trap representation - but that doesn't matter. The thing to note here is that, as the Spring 2008 note in the DR mentions, from a standard perspective this doesn't actually need to involve trap representations themselves at all (they're just the likely mechanism by which the UB would cause a problem for you on the metal). The issue is really about uninitialized automatic values; the amended paragraph resolves this by clarifying that unsigned char should not be considered exempt from a general type of UB simply because of one of its type-specific properties (not by adding more complexity to that property).

You could imagine that just as NaT bits are an implementation detail of integers on IA64, the absence of a trap representation is an "implementation detail" of one particular type within the general family of C types. The actual type of the variable is secondary to the more general rule that you shouldn't feel safe accessing any variable uninitialized; the addition clarifies that precedence.

like image 181
Leushenko Avatar answered Sep 23 '22 18:09

Leushenko