This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFH: Annotating ELF binaries


On Wed, Mar 1, 2017 at 1:56 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Fri, Jan 20, 2017 at 11:06 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Fri, Jan 20, 2017 at 11:02 AM, Carlos O'Donell <carlos@redhat.com> wrote:
>>> On 01/20/2017 11:55 AM, H.J. Lu wrote:
>>>> We can classify properties into 2 categories: used by run-time loader,
>>>> not used by run-time loader.  We put properties for run-time loader into
>>>> .note.gnu.property section and the rest into GNU attribute section.
>>>
>>> Agreed.
>>>
>>> Can we use the same noun/adjective for our names?
>>>
>>> Is there any reason to use property over attribute?
>>
>> Nothing other than avoiding confusion between note attribute
>> vs non-note attribute.
>>
>>> As a Friday bikeshed I suggest:
>>>
>>> .note.gnu.attributes - GNU Attributes optimized for the dynamic loader.
>>> -- New. Follows H.J's proposal. Bit-level, packed, and optimized for the
>>>    dynamic loader processing.
>>>
>>> .gnu.attributes - GNU Attributes optimized for offline and static linker
>>>                   processing.
>>> -- Existing section. Discussions with Nick ongoing if we can continue
>>>    to use existing infrastructure e.g. Tag_Range to extend this data.
>>>
>>
>> Works for me.
>>
>>
>> --
>> H.J.
>
> Here is the updated proposal with .note.gnu.attributes.
>
>
> --
> H.J.
> ---
> Program Attribute Note
>
> There are cases where linker and run-time loader need more information
> about ELF objects beyond what the current gABI provides:
>
> 1. Minimum ISAs.  Executables and shared objects, which are optimized
> specifically to run on a particular processor, will not run on processors
> which don't support the same set of ISAs.  Since x86 only has EM_IAMCU,
> EM_386 and EM_X86_64 ELF machine codes, run-time loader needs additional
> information to tell if an executable or a shared object is compatible
> with available ISAs.
> 2. Stack size.  Compilers may generate binaries which require larger stack
> size than normal.  If run-time loader can query the stack size required
> by executable or shared object, it can increase stack size as needed.
> 3. Copy relocation and protected visibility are fundamentally incompatible.
> On one hand, copy relocation is the part of the psABI and is used to
> access global data defined in a shared object from the executable.  It
> moves the definition of global data, which is defined in a share object,
> to the executable at run-time.  On the other hand, protected visibility
> indicates that a symbol is defined locally in the shared object at
> run-time.  Both can't be true at the same time.  The current solution
> is to make protected symbol more or less like normal symbol, which
> prevents optimizing local access to protected symbol within the shared
> object.
>
> GNU attributes
>
> GNU binutils supports build attribute and run-time platform compatibility
> data in relocatable object files.  Issues with GNU attributes:
>
> 1. Many architectures, including x86, don't support GNU attributes.
> 2. On x86, linking a relocatable object full of AVX instructions doesn't
> always make the resulting executables or shared libraries to require AVX
> to run since AVX functions may be called only via GNU_IFUNC at run-time.
> Linker can't set minimum ISAs just from ISAs used by input relocatable
> objects.
> 3. There is no program segment for GNU attributes in executables and
> shared objects.
> 4. Most of attributes aren't applicable to run-time loader.
> 5. The format of GNU attributes isn't optimal for run-time loader.  A
> separate string table is used to store string attributes.
>
> gABI support for program attribute note
>
> To the "Special Sections" section, add:
>
>      Name              Type                 Attributes
> .note.gnu.attributes  SHT_NOTE              SHF_ALLOC
>
> A .note.gnu.attributes section contains at least one attribute note
> descriptor, starting with an attribute note descriptor header and
> followed by an array of attributes.  The attribute note descriptor
> header has the following structure:
>
> typedef struct {
>   Elf_Word namsz;
>   Elf_Word descsz;
>   Elf_Word type;
>   unsigned char name[4];
> } Elf_GNU_Notehdr;
>
> 1. namesz is 4.
> 2. descsz contains the size of the attribute array.
> 3. type specifies the attribute type:
>
> #define NT_GNU_ATTRIBUTE_TYPE_0   5
>
> 4. name is a null-terminated character string. It should be "GNU".
>
> Each array element represents one attribute with type, data size and data.
> In 64-bit objects, each element is an array of 8-byte words, whose first
> element is 4-byte type and data size, in the format of the target processor.
> In 32-bit objects, each element is an array of 4-byte words, whose first 2
> elements are 4-byte type and data size, in the format of the target
> processor.  An array element has the following structure:
>
> typedef struct {
>   Elf_Word at_type;
>   Elf_Word at_datasz;
>   unsigned char at_data[AT_DATASZ];
>   unsigned char at_padding[AT_PADDING];
> } Elf_Prop;
>
> where AT_DATASZ is the data size and AT_PADDING, if necessary, aligns
> array element to 8 or 4-byte alignment (depending on whether the file
> is a 64-bit or 32-bit object).  The array elements are sorted by the
> attribute type.  The interpretation of attribute array depends on at_type.
>
> Types of program attributes
>
> The last 3 bits of program attribute indicate how it should be
> processed.
>
> #define GNU_ATTRIBUTE_TYPE_SHIFT    3
> #define GNU_ATTRIBUTE_TYPE_MASK     (-(1 << GNU_ATTRIBUTE_TYPE_SHIFT))
> #define GNU_ATTRIBUTE_EVAL_MASK     ((1 << GNU_ATTRIBUTE_TYPE_SHIFT) - 1)
>
> #define GNU_ATTRIBUTE_EVAL_REQ      0
>
> Linker should refuse to generate output if input attribute type is
> unknown.
>
> #define GNU_ATTRIBUTE_EVAL_EQ       1
>
> Linker should refuse to generate output if input attribute data aren't
> identical.
>
> #define GNU_ATTRIBUTE_EVAL_OR       2
>
> Output attribute data is logical OR of input attribute data.
>
> #define GNU_ATTRIBUTE_EVAL_AND      3
>
> Output attribute data is logical AND of input attribute data.
>
> Linker should refuse to generate output for other evaluation values in
> input attribute type.
>
> #define GNU_ATTRIBUTE_LOPROC        0xb0000000
> #define GNU_ATTRIBUTE_HIPROC        0xdfffffff
> #define GNU_ATTRIBUTE_LOUSER        0xe0000000
> #define GNU_ATTRIBUTE_HIUSER        0xffffffff
>
> Proposed properties
>
> For NT_GNU_ATTRIBUTE_TYPE_0:
>
> #define GNU_ATTRIBUTE_STACK_SIZE \
>  ((1 << GNU_ATTRIBUTE_TYPE_SHIFT)|GNU_ATTRIBUTE_EVAL_REQ)
>
> Integer value for minimum stack size whose is 8 bytes in 64-bit object
> and 4 bytes in 32-bit object.
>
> #define GNU_ATTRIBUTE_NO_COPY_ON_PROTECTED \
>  ((2 << GNU_ATTRIBUTE_TYPE_SHIFT)|GNU_ATTRIBUTE_EVAL_REQ)
>
> Its at_datasz is 0.  This indicates that there should be no copy
> relocations against protected data symbols.  If a relocatable object
> contains this attribute, linker should treat protected data symbol as
> defined locally at run-time and copy this attribute to the output share
> object.  Run-time loader should disallow copy relocations against
> protected data symbols defined in share objects with
> GNU_ATTRIBUTE_NO_COPY_ON_PROTECTED attribute.
>
> #define GNU_ATTRIBUTE_X86_ISA_1_USED \
>   ((0 << GNU_ATTRIBUTE_TYPE_SHIFT)|GNU_ATTRIBUTE_LOPROC|GNU_ATTRIBUTE_EVAL_OR)
>
> The x86 instruction sets indicated by the corresponding bits are used
> in program.  But their support in the hardware is optional.
>
> #define GNU_ATTRIBUTE_X86_ISA_1_NEEDED \
>   ((1 << GNU_ATTRIBUTE_TYPE_SHIFT)|GNU_ATTRIBUTE_LOPROC|GNU_ATTRIBUTE_EVAL_OR)
>
> The x86 instruction sets indicated by the corresponding bits are used
> in program and they must be supported by the hardware.  A bit set in
> GNU_ATTRIBUTE_X86_ISA_1_NEEDED must also be set in
> GNU_ATTRIBUTE_X86_ISA_1_USED.
>
> 4-byte integer value for the x86 instruction set support.
>
> #define GNU_ATTRIBUTE_X86_ISA_1_486           (1U << 0)
> #define GNU_ATTRIBUTE_X86_ISA_1_586           (1U << 1)
> #define GNU_ATTRIBUTE_X86_ISA_1_686           (1U << 2)
> #define GNU_ATTRIBUTE_X86_ISA_1_SSE           (1U << 3)
> #define GNU_ATTRIBUTE_X86_ISA_1_SSE2          (1U << 4)
> #define GNU_ATTRIBUTE_X86_ISA_1_SSE3          (1U << 5)
> #define GNU_ATTRIBUTE_X86_ISA_1_SSSE3         (1U << 6)
> #define GNU_ATTRIBUTE_X86_ISA_1_SSE4_1        (1U << 7)
> #define GNU_ATTRIBUTE_X86_ISA_1_SSE4_2        (1U << 8)
> #define GNU_ATTRIBUTE_X86_ISA_1_AVX           (1U << 9)
> #define GNU_ATTRIBUTE_X86_ISA_1_AVX2          (1U << 10)
> #define GNU_ATTRIBUTE_X86_ISA_1_AVX512F       (1U << 11)
> #define GNU_ATTRIBUTE_X86_ISA_1_AVX512CD      (1U << 12)
> #define GNU_ATTRIBUTE_X86_ISA_1_AVX512ER      (1U << 13)
> #define GNU_ATTRIBUTE_X86_ISA_1_AVX512PF      (1U << 14)
> #define GNU_ATTRIBUTE_X86_ISA_1_AVX512VL      (1U << 15)
> #define GNU_ATTRIBUTE_X86_ISA_1_AVX512DQ      (1U << 16)
> #define GNU_ATTRIBUTE_X86_ISA_1_AVX512BW      (1U << 17)
> #define GNU_ATTRIBUTE_X86_ISA_1_ENDBR         (1U << 18)

Apparently, Nick has committed a patch to implement .note.gnu.property:

https://sourceware.org/ml/binutils/2017-03/msg00005.html

I will go with it.

-- 
H.J.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]