[PATCH] x86: Don't remove empty x86 properties

Jim Dehnert dehnert@gmail.com
Fri Dec 7 06:22:00 GMT 2018

Something's been bothering me about much of this discussion, which is
probably related to Cary's question about intended usage.  We had some
features analogous to these, for example concerning floating point
behavior, in the SGI compilers and tools 20+ years ago.  One of the things
we realized in the process was that there are at least two different
classes of usage with different desired properties.

The first class involves what this discussion is focused on -- the ability
to catch invalid mixtures of assumptions, e.g., code that assumes or
requires something (like your X86 features) vs. other code or hardware that
doesn't satisfy those requirements.  When one catches such a mismatch (in
the linker or loader, say), one could reject the program, or it might be
preferable to let it pass and just use the information for better error
messages if a failure occurs at runtime.  The latter decision might make
sense if an actual failure is unlikely, but the decision might vary for
different features, or different tools, or different vendors.

For such usage, it is not necessarily critical that the property
information be available for every component object.  For example, it may
be known that old objects created before the property became available
didn't ever require it.  It may also be desirable to just accept objects
from toolchains that don't (yet) support the property bits, and accept that
they might fail more dramatically.

The second class involves things like cross-object optimization decisions,
where some global attribute must apply to make the optimization valid.  In
this case, missing information might produce an incorrect optimization.  An
example might be a linker decision to include software FP support for a
simple processor depending on whether any object uses FP.

The point of bringing up this distinction is that the same property
information might be used by different tools or toolchains, or in different
contexts, in different ways in terms of whether a property is required or
not, and in terms of whether accurate information is required from all
component objects.  It's not a good idea to make assumptions when defining
the property bit treatment about which case applies -- you should just
carefully define what the bit means, how it's combined when linking objects
(AND vs. OR), and, importantly, how a downstream consumer knows whether or
not the information is complete.  In particular, a decision to discard data
if it's missing from some objects, or if the operation applied yields a
particular result, can make it impossible for a downstream consumer to tell
the difference between missing information and combinations yielding 0, and
it removes the ability of a consumer to do something intelligent for the
first case.

The above are general observations.  There's a more subtle issue in this
particular proposal that's related (as I understand it).  Because you're
packing property bits into larger units, and will presumably be adding
additional properties in the future, you'll want to be able to tell which
bits are valid in a particular object (e.g., was it created before or after
the new property was added?).  Otherwise, bits might be zero either because
the property isn't true, or because it wasn't supported by the tool
that created the object.  You can't really deal with this using version
information, because there's no good way to combine versions without
discarding information.  I'd suggest including a "complete" bit for each
property bit, meaning that all components of the object provided valid
values for the property.  Non-complete property bits could still contain
useful data, but a consumer could not assume it was a valid combination of
all the component objects.  (This implies that the complete bits are all
AND bits - the output value should be an AND of all the input values when
combining objects.)   Note that the separate complete bits removes the need
for the OR_AND construct, which was trying to combine two separate concepts
in a single bit.

On Thu, Dec 6, 2018 at 5:38 AM H.J. Lu <hjl.tools@gmail.com> wrote:

> Let's take GNU_PROPERTY_X86_FEATURE_2_USED.  Here are
> what x86-64 psABI says:
> A bit in the output pr_data field is set if it is set in any
> relocatable input pr_data
> fields and this property is present in all relocatable input files. A
> missing property
> implies that its bits have unknown values. When all bits in the the
> output pr_data
> field are zero, this property should not be removed from output to
> indicate it has
> zero in all bits. If the property is in output, all input relocatables
> have the property.
> If the bit is 1, some input relocatables have the feature. If the bit
> is 0, none of input
> relocatables have the feature.

Based on the above, this is not a good idea.  The property should be
present in output if it was present in any input, and its value should
probably reflect the combination of those inputs.  A complete bit can
provide this last bit of information, which can have utility independent of
the (possibly partial) combined property bits.  Besides, you can't remove a
subset of the property bits in a storage unit anyway, if the input objects
were generated by tools supporting different numbers of them.

> GNU_PROPERTY_X86_FEATURE_2_USED The x86 processor features indicated
> by the corresponding bits are used in program. Their support in the
> hardware is
> optional. Its absence in an x86 ELF binary implies that any x86
> processor features
> may be used. GNU_PROPERTY_X86_FEATURE_2_USED can be used to check
> for features used in the program
> [hjl@gnu-cfl-1 tmp]$ cat foo.s
> .text
> movaps %xmm0, %xmm0
> [hjl@gnu-cfl-1 tmp]$ as -mx86-used-note=no foo.s -o foo1.o
> [hjl@gnu-cfl-1 tmp]$ as -mx86-used-note=yes foo.s -o foo2.o
> [hjl@gnu-cfl-1 tmp]$ as -mx86-used-note=yes foo.s -o foo3.o
> [hjl@gnu-cfl-1 tmp]$ readelf -n foo1.o
> [hjl@gnu-cfl-1 tmp]$ readelf -n foo2.o
> Displaying notes found in: .note.gnu.property
>   Owner                 Data size Description
>   GNU                  0x00000020 NT_GNU_PROPERTY_TYPE_0
>       Properties: x86 ISA used: SSE
> x86 feature used: x86, XMM
> [hjl@gnu-cfl-1 tmp]$ readelf -n foo3.o
> Displaying notes found in: .note.gnu.property
>   Owner                 Data size Description
>   GNU                  0x00000020 NT_GNU_PROPERTY_TYPE_0
>       Properties: x86 ISA used: SSE
> x86 feature used: x86, XMM
> [hjl@gnu-cfl-1 tmp]$ ld.bfd foo1.o foo2.o
> ld.bfd: warning: cannot find entry symbol _start; defaulting to
> 0000000000401000
> [hjl@gnu-cfl-1 tmp]$ readelf -n a.out
> [hjl@gnu-cfl-1 tmp]$ ld.bfd foo3.o foo2.o
> ld.bfd: warning: cannot find entry symbol _start; defaulting to
> 0000000000401000
> [hjl@gnu-cfl-1 tmp]$ readelf -n a.out
> Displaying notes found in: .note.gnu.property
>   Owner                 Data size Description
>   GNU                  0x00000020 NT_GNU_PROPERTY_TYPE_0
>       Properties: x86 ISA used: SSE
> x86 feature used: x86, XMM
> [hjl@gnu-cfl-1 tmp]$
> Can you tell me what the issues are?
> --
> H.J.
> --
> You received this message because you are subscribed to the Google Groups
> "X86-64 System V Application Binary Interface" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to x86-64-abi+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

             Jim Dehnert

More information about the Binutils mailing list