Bug 22914 - Gold doesn't support .note.gnu.property section (NT_GNU_PROPERTY_TYPE_0)
Summary: Gold doesn't support .note.gnu.property section (NT_GNU_PROPERTY_TYPE_0)
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: gold (show other bugs)
Version: 2.31
: P2 enhancement
Target Milestone: 2.36
Assignee: Cary Coutant
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-03-02 16:31 UTC by H.J. Lu
Modified: 2020-10-13 12:32 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2018-03-02 16:31:17 UTC
.note.gnu.property section and NT_GNU_PROPERTY_TYPE_0 are specified in
Linux Extensions to gABI:

https://github.com/hjl-tools/linux-abi/wiki/linux-abi-draft.pdf

[hjl@gnu-cfl-1 gold-2]$ cat x.S
#ifndef NT_GNU_PROPERTY_TYPE_0
# define NT_GNU_PROPERTY_TYPE_0 5
#endif

#ifndef GNU_PROPERTY_STACK_SIZE
# define GNU_PROPERTY_STACK_SIZE 1
#endif

#if __SIZEOF_PTRDIFF_T__  == 8
# define ALIGN 3
#elif __SIZEOF_PTRDIFF_T__  == 4
# define ALIGN 2
#endif

	.section ".note.gnu.property", "a"
	.p2align ALIGN

	.long 1f - 0f		/* name length */
	.long 5f - 2f		/* data length */
	.long NT_GNU_PROPERTY_TYPE_0	/* note type */
0:	.asciz "GNU"		/* vendor name */
1:
	.p2align ALIGN
2:	.long GNU_PROPERTY_STACK_SIZE	/* pr_type.  */
	.long 4f - 3f	/* pr_datasz.  */
3:
	.dc.a 0x800	/* Stack size.  */
4:
	.p2align ALIGN
5:
[hjl@gnu-cfl-1 gold-2]$ cat y.S
#ifndef NT_GNU_PROPERTY_TYPE_0
# define NT_GNU_PROPERTY_TYPE_0 5
#endif

#ifndef GNU_PROPERTY_NO_COPY_ON_PROTECTED
# define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2
#endif

#if __SIZEOF_PTRDIFF_T__  == 8
# define ALIGN 3
#elif __SIZEOF_PTRDIFF_T__  == 4
# define ALIGN 2
#endif

	.section ".note.gnu.property", "a"
	.p2align ALIGN
	.long 1f - 0f		/* name length */
	.long 3f - 2f		/* data length */
	.long NT_GNU_PROPERTY_TYPE_0	/* note type */
0:	.asciz "GNU"		/* vendor name */
1:
	.p2align ALIGN
2:	.long GNU_PROPERTY_NO_COPY_ON_PROTECTED	/* pr_type.  */
	.long 0	/* pr_datasz.  */
3:
	.p2align ALIGN
[hjl@gnu-cfl-1 gold-2]$ cat z.S
#ifndef NT_GNU_PROPERTY_TYPE_0
# define NT_GNU_PROPERTY_TYPE_0 5
#endif

#ifndef GNU_PROPERTY_STACK_SIZE
# define GNU_PROPERTY_STACK_SIZE 1
#endif

#ifndef GNU_PROPERTY_NO_COPY_ON_PROTECTED
# define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2
#endif

#if __SIZEOF_PTRDIFF_T__  == 8
# define ALIGN 3
#elif __SIZEOF_PTRDIFF_T__  == 4
# define ALIGN 2
#endif

	.section ".note.gnu.property", "a"
	.p2align ALIGN
	.long 1f - 0f		/* name length */
	.long 5f - 2f		/* data length */
	.long NT_GNU_PROPERTY_TYPE_0	/* note type */
0:	.asciz "GNU"		/* vendor name */
1:
	.p2align ALIGN
2:	.long GNU_PROPERTY_STACK_SIZE	/* pr_type.  */
	.long 4f - 3f	/* pr_datasz.  */
3:
	.dc.a 0x111100	/* Stack size.  */
4:
	.p2align ALIGN
	.long GNU_PROPERTY_NO_COPY_ON_PROTECTED	/* pr_type.  */
	.long 0	/* pr_datasz.  */
	.p2align ALIGN
5:
[hjl@gnu-cfl-1 gold-2]$ cat bar.c
void
_start (void)
{
}
[hjl@gnu-cfl-1 gold-2]$ make
gcc -B./  -c -o x.o x.S
gcc -B./  -c -o y.o y.S
gcc -B./  -c -o z.o z.S
gcc -B./  -c -o bar.o bar.c
./ld  -o x x.o y.o z.o bar.o
ld  -o y x.o y.o z.o bar.o
readelf -n x y

File: x

Displaying notes found in: .note.gnu.property
  Owner                 Data size	Description
  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
      Properties: stack size: 0x800
  GNU                  0x00000008	NT_GNU_PROPERTY_TYPE_0
      Properties: no copy on protected 
  GNU                  0x00000018	NT_GNU_PROPERTY_TYPE_0
      Properties: stack size: 0x111100
	no copy on protected 

Displaying notes found in: .note.gnu.gold-version
  Owner                 Data size	Description
  GNU                  0x00000009	NT_GNU_GOLD_VERSION (gold version)
    Version: gold 1.15

File: y

Displaying notes found in: .note.gnu.property
  Owner                 Data size	Description
  GNU                  0x00000018	NT_GNU_PROPERTY_TYPE_0
      Properties: stack size: 0x111100
	no copy on protected 
[hjl@gnu-cfl-1 gold-2]$
Comment 1 Cary Coutant 2018-06-21 15:52:28 UTC
HJ,

The linux-abi document leaves a few things unspecified:

- Is the .note.gnu.property section SHF_ALLOC or not?

- Does it go in the PT_NOTE segment? Should it be placed at the
beginning of the segment?

- It says the .note.gnu.property section may be combined with other
note sections. (Is that true, or is it missing a "not"?) If the linker
combines it with other SHT_NOTE sections, does the name matter at all?

- Does the linker key off the name of the section, or does it need to
parse all SHT_NOTE sections looking for NT_GNU_PROPERTY_TYPE_0 and
"GNU"? (Neither option is attractive -- I'd much prefer using a custom
section type and program header type, like ARM, MIPS, and Itanium do
for their attributes sections. The linker and loader aren't meant to
be parsing note sections.)

- Where did we end up with note section alignment for 64-bit objects?
Is it still 4-byte aligned?




On Fri, Mar 2, 2018 at 8:31 AM, hjl.tools at gmail dot com
<sourceware-bugzilla@sourceware.org> wrote:
> https://sourceware.org/bugzilla/show_bug.cgi?id=22914
>
>             Bug ID: 22914
>            Summary: Gold doesn't support .note.gnu.property section
>                     (NT_GNU_PROPERTY_TYPE_0)
>            Product: binutils
>            Version: 2.31 (HEAD)
>             Status: NEW
>           Severity: enhancement
>           Priority: P2
>          Component: gold
>           Assignee: ccoutant at gmail dot com
>           Reporter: hjl.tools at gmail dot com
>                 CC: ian at airs dot com
>   Target Milestone: ---
>
> .note.gnu.property section and NT_GNU_PROPERTY_TYPE_0 are specified in
> Linux Extensions to gABI:
>
> https://github.com/hjl-tools/linux-abi/wiki/linux-abi-draft.pdf
>
> [hjl@gnu-cfl-1 gold-2]$ cat x.S
> #ifndef NT_GNU_PROPERTY_TYPE_0
> # define NT_GNU_PROPERTY_TYPE_0 5
> #endif
>
> #ifndef GNU_PROPERTY_STACK_SIZE
> # define GNU_PROPERTY_STACK_SIZE 1
> #endif
>
> #if __SIZEOF_PTRDIFF_T__  == 8
> # define ALIGN 3
> #elif __SIZEOF_PTRDIFF_T__  == 4
> # define ALIGN 2
> #endif
>
>         .section ".note.gnu.property", "a"
>         .p2align ALIGN
>
>         .long 1f - 0f           /* name length */
>         .long 5f - 2f           /* data length */
>         .long NT_GNU_PROPERTY_TYPE_0    /* note type */
> 0:      .asciz "GNU"            /* vendor name */
> 1:
>         .p2align ALIGN
> 2:      .long GNU_PROPERTY_STACK_SIZE   /* pr_type.  */
>         .long 4f - 3f   /* pr_datasz.  */
> 3:
>         .dc.a 0x800     /* Stack size.  */
> 4:
>         .p2align ALIGN
> 5:
> [hjl@gnu-cfl-1 gold-2]$ cat y.S
> #ifndef NT_GNU_PROPERTY_TYPE_0
> # define NT_GNU_PROPERTY_TYPE_0 5
> #endif
>
> #ifndef GNU_PROPERTY_NO_COPY_ON_PROTECTED
> # define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2
> #endif
>
> #if __SIZEOF_PTRDIFF_T__  == 8
> # define ALIGN 3
> #elif __SIZEOF_PTRDIFF_T__  == 4
> # define ALIGN 2
> #endif
>
>         .section ".note.gnu.property", "a"
>         .p2align ALIGN
>         .long 1f - 0f           /* name length */
>         .long 3f - 2f           /* data length */
>         .long NT_GNU_PROPERTY_TYPE_0    /* note type */
> 0:      .asciz "GNU"            /* vendor name */
> 1:
>         .p2align ALIGN
> 2:      .long GNU_PROPERTY_NO_COPY_ON_PROTECTED /* pr_type.  */
>         .long 0 /* pr_datasz.  */
> 3:
>         .p2align ALIGN
> [hjl@gnu-cfl-1 gold-2]$ cat z.S
> #ifndef NT_GNU_PROPERTY_TYPE_0
> # define NT_GNU_PROPERTY_TYPE_0 5
> #endif
>
> #ifndef GNU_PROPERTY_STACK_SIZE
> # define GNU_PROPERTY_STACK_SIZE 1
> #endif
>
> #ifndef GNU_PROPERTY_NO_COPY_ON_PROTECTED
> # define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2
> #endif
>
> #if __SIZEOF_PTRDIFF_T__  == 8
> # define ALIGN 3
> #elif __SIZEOF_PTRDIFF_T__  == 4
> # define ALIGN 2
> #endif
>
>         .section ".note.gnu.property", "a"
>         .p2align ALIGN
>         .long 1f - 0f           /* name length */
>         .long 5f - 2f           /* data length */
>         .long NT_GNU_PROPERTY_TYPE_0    /* note type */
> 0:      .asciz "GNU"            /* vendor name */
> 1:
>         .p2align ALIGN
> 2:      .long GNU_PROPERTY_STACK_SIZE   /* pr_type.  */
>         .long 4f - 3f   /* pr_datasz.  */
> 3:
>         .dc.a 0x111100  /* Stack size.  */
> 4:
>         .p2align ALIGN
>         .long GNU_PROPERTY_NO_COPY_ON_PROTECTED /* pr_type.  */
>         .long 0 /* pr_datasz.  */
>         .p2align ALIGN
> 5:
> [hjl@gnu-cfl-1 gold-2]$ cat bar.c
> void
> _start (void)
> {
> }
> [hjl@gnu-cfl-1 gold-2]$ make
> gcc -B./  -c -o x.o x.S
> gcc -B./  -c -o y.o y.S
> gcc -B./  -c -o z.o z.S
> gcc -B./  -c -o bar.o bar.c
> ./ld  -o x x.o y.o z.o bar.o
> ld  -o y x.o y.o z.o bar.o
> readelf -n x y
>
> File: x
>
> Displaying notes found in: .note.gnu.property
>   Owner                 Data size       Description
>   GNU                  0x00000010       NT_GNU_PROPERTY_TYPE_0
>       Properties: stack size: 0x800
>   GNU                  0x00000008       NT_GNU_PROPERTY_TYPE_0
>       Properties: no copy on protected
>   GNU                  0x00000018       NT_GNU_PROPERTY_TYPE_0
>       Properties: stack size: 0x111100
>         no copy on protected
>
> Displaying notes found in: .note.gnu.gold-version
>   Owner                 Data size       Description
>   GNU                  0x00000009       NT_GNU_GOLD_VERSION (gold version)
>     Version: gold 1.15
>
> File: y
>
> Displaying notes found in: .note.gnu.property
>   Owner                 Data size       Description
>   GNU                  0x00000018       NT_GNU_PROPERTY_TYPE_0
>       Properties: stack size: 0x111100
>         no copy on protected
> [hjl@gnu-cfl-1 gold-2]$
>
> --
> You are receiving this mail because:
> You are the assignee for the bug.
Comment 2 Sourceware Commits 2018-06-22 16:53:14 UTC
The master branch has been updated by Cary Coutant <ccoutant@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6c04fd9b2fb4396c0189cb414ce598161ac8673e

commit 6c04fd9b2fb4396c0189cb414ce598161ac8673e
Author: Cary Coutant <ccoutant@gmail.com>
Date:   Fri Jun 22 09:27:39 2018 -0700

    Add support for .note.gnu.property sections.
    
    elfcpp/
    	PR gold/22914
    	* elfcpp.h (NT_GNU_PROPERTY_TYPE_0): New note type.
    	(GNU_PROPERTY_*): New Gnu property types.
    	* x86_64.h (GNU_PROPERTY_X86_FEATURE_1_IBT)
    	(GNU_PROPERTY_X86_FEATURE_1_SHSTK): New x86 feature bits.
    
    gold/
    	PR gold/22914
    	* layout.cc (Layout::Layout): Initialize gnu_properties_.
    	(read_sized_value, write_sized_value): New functions.
    	(Layout::layout_gnu_property): New method.
    	(Layout::create_notes): Call create_gnu_properties_note.
    	(Layout::create_gnu_properties_note): New method.
    	* layout.h (Layout::layout_gnu_property): New method.
    	(Layout::create_gnu_properties_note): New method.
    	(Layout::Gnu_property, Layout::Gnu_properties): New types.
    	(Layout::gnu_properties_): New data member.
    	* object.cc (Sized_relobj_file::layout_gnu_property_section): New
    	method.
    	(Sized_relobj_file::do_layout): Handle .note.gnu.property sections.
    	* object.h (Sized_relobj_file::layout_gnu_property_section): New
    	method.
    	* target.h (Target::merge_gnu_property): New method.
    	(Target::do_merge_gnu_property): New virtual method.
    	* x86_64.cc (Target_x86_64::do_merge_gnu_property): New method.
    	* testsuite/Makefile.am (gnu_property_test): New test case.
    	* testsuite/Makefile.in: Regenerate.
    	* testsuite/gnu_property_a.S: New source file.
    	* testsuite/gnu_property_b.S: New source file.
    	* testsuite/gnu_property_c.S: New source file.
    	* testsuite/gnu_property_main.c: New source file.
    	* testsuite/gnu_property_test.sh: New test script.
Comment 3 Cary Coutant 2018-06-22 16:54:10 UTC
Support added for 2.31.
Comment 4 Sourceware Commits 2018-06-23 06:37:44 UTC
The master branch has been updated by Cary Coutant <ccoutant@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a2575bec2413d361c6ecfc4aecb2a31c86123f95

commit a2575bec2413d361c6ecfc4aecb2a31c86123f95
Author: Cary Coutant <ccoutant@gmail.com>
Date:   Fri Jun 22 23:36:50 2018 -0700

    Update support for .note.gnu.property sections.
    
    The original patch did not give the target enough hooks to discover that
    an input object file does not have a particular property. For the
    GNU_PROPERTY_X86_FEATURE_1_AND property, for example, where a missing
    property should be assumed to be all zeroes, and ANDed with other
    object modules, this is essential. We now store the target-specific
    properties locally in the Target structure as native uint32_t fields,
    then AND the per-object feature bits with the program's feature bits
    when we're finished processing each input object file. The target-specific
    properties are then added back to the output note section during
    finalization.
    
    gold/
    	PR gold/22914
    	* layout.cc (read_sized_value): Fix spelling of section name.
    	(Layout::layout_gnu_property): Call Sized_target::record_gnu_property
    	for target-specific properties;
    	don't store them with target-independent properties yet.
    	(Layout::merge_gnu_properties): New method.
    	(Layout::add_gnu_property): New method.
    	(Layout::create_gnu_properties_note): Call target to finalize
    	target-specific properties. Fix spelling of output section name.
    	* layout.h (Layout::merge_gnu_properties): New method.
    	(Layout::add_gnu_property): New method.
    	* object.cc (Sized_relobj_file::do_layout): Call
    	Layout::merge_gnu_properties.
    	* target.h (Target::merge_gnu_property): Remove.
    	(Target::finalize_gnu_properties): New method.
    	(Target::do_merge_gnu_property): Move to Sized_target and rename.
    	(Target::do_finalize_gnu_properties): New virtual method.
    	(Sized_target::record_gnu_property): Moved and renamed from
    	Target::do_merge_gnu_property.
    	(Sized_target::merge_gnu_properties): New virtual method.
    	* x86_64.cc (Target_x86_64::isa_1_used_, isa_1_needed_)
    	(feature_1_, object_feature_1_, seen_first_object_): New data members.
    	(Target_x86_64::do_merge_gnu_property): Rename to ...
    	(Target_x86_64::record_gnu_property): ... this.  Save target-specific
    	properties in Target class object.
    	(Target_x86_64::merge_gnu_properties): New method.
    	(add_property): New static inline function.
    	(Target_x86_64::do_finalize_gnu_properties): New method.
    	* testsuite/Makefile.am (gnu_property_test): Remove C source file;
    	link directly without compiler driver.
    	* testsuite/Makefile.in: Regenerate.
    	* testsuite/gnu_property_a.S: Add _start.
Comment 5 Sourceware Commits 2018-06-23 07:27:00 UTC
The master branch has been updated by Cary Coutant <ccoutant@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=add4131108de4b4a0f3003cb542e9548914fbed1

commit add4131108de4b4a0f3003cb542e9548914fbed1
Author: Cary Coutant <ccoutant@gmail.com>
Date:   Sat Jun 23 00:26:07 2018 -0700

    Fix "may be used uninitialized" warning.
    
    gold/
    	PR gold/22914
    	* x86_64.cc (Target_x86_64::record_gnu_property): Initialize val.
Comment 6 H.J. Lu 2018-07-03 12:08:47 UTC
(In reply to Cary Coutant from comment #1)
> HJ,
> 
> The linux-abi document leaves a few things unspecified:
> 
> - Is the .note.gnu.property section SHF_ALLOC or not?

It is no different from other SHT_NOTE sections.

> - Does it go in the PT_NOTE segment? Should it be placed at the
> beginning of the segment?

If it has SHF_ALLOC, it should go into the PT_NOTE segment.

> - It says the .note.gnu.property section may be combined with other
> note sections. (Is that true, or is it missing a "not"?) If the linker
> combines it with other SHT_NOTE sections, does the name matter at all?

It isn't strictly required.  It is just another special section.

> - Does the linker key off the name of the section, or does it need to
> parse all SHT_NOTE sections looking for NT_GNU_PROPERTY_TYPE_0 and
> "GNU"? (Neither option is attractive -- I'd much prefer using a custom
> section type and program header type, like ARM, MIPS, and Itanium do
> for their attributes sections. The linker and loader aren't meant to
> be parsing note sections.)

Linker and loader need to look for NT_GNU_PROPERTY_TYPE_0 and "GNU",
similar to other "GNU" note sections.

> - Where did we end up with note section alignment for 64-bit objects?
> Is it still 4-byte aligned?

No, as documented in linux gABI:

2.1.7 Alignment of Note Sections
All entries in a PT_NOTE segment have the same alignment which equals to the
p_align field in program header.
According to gABI, each note entry should be aligned to 4 bytes in 32-bit
objects or 8 bytes in 64-bit objects. But .note.ABI-tag section (see Section 2.1.6) and .note.gnu.build-id section (see Section 2.1.4) are aligned
to 4 bytes in both 32-bit and 64-bit objects. Note parser should use p_align for
note alignment, instead of assuming alignment based on ELF file class.
Comment 7 H.J. Lu 2018-08-16 13:44:19 UTC
Gold didn't properly align the NT_GNU_PROPERTY_TYPE_0 note:

[hjl@gnu-cet-1 simple-linux]$ make LD=ld.gold
gcc -g -fcf-protection   -c -o test.o test.S
gcc -g -fcf-protection   -c -o start.o start.S
gcc -g -fcf-protection   -c -o syscall.o syscall.S
ld.gold  -o test test.o start.o syscall.o
./test hello world
[hjl@gnu-cet-1 simple-linux]$ readelf -l test

Elf file type is EXEC (Executable file)
Entry point 0x400151
There are 3 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x00000000000001f0 0x00000000000001f0  R E    0x1000
  LOAD           0x0000000000001000 0x0000000000401000 0x0000000000401000
                 0x0000000000000000 0x0000000000000000  RW     0x1000
  NOTE           0x00000000000000e8 0x00000000004000e8 0x00000000004000e8
                 0x0000000000000030 0x0000000000000030  R      0x4

 Section to Segment mapping:
  Segment Sections...
   00     .note.gnu.property .text .eh_frame 
   01     .data .bss 
   02     .note.gnu.property 
[hjl@gnu-cet-1 simple-linux]$ 

The NT_GNU_PROPERTY_TYPE_0 note follows gABI and should have 8 byte
alignment for 64-bit ELF.
Comment 8 Sourceware Commits 2020-10-13 12:30:15 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6bf4a34047452f882c5cc66bd85812ee1bb5a41c

commit 6bf4a34047452f882c5cc66bd85812ee1bb5a41c
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Oct 13 05:18:13 2020 -0700

    gold: Properly align the NT_GNU_PROPERTY_TYPE_0 note
    
    The NT_GNU_PROPERTY_TYPE_0 note should be aligned to 8 bytes for 64-bit
    ELF as specified by gABI.  A note section can be only placed in a PT_NOTE
    segment with the same alignment.
    
            PR gold/22914
            PR gold/23535
            * layout.cc (Layout::attach_allocated_section_to_segment): Place
            a note section in a PT_NOTE segment with the same alignment.  Set
            the alignment of the PT_NOTE segment from the alignment of the
            note section.
            (Layout::create_note): Align the NT_GNU_PROPERTY_TYPE_0 note to 8
            bytes for 64-bit ELF.
            (Layout::segment_precedes): Place segments with larger alignments
            first.
            * output.cc (Output_segment::Output_segment): Initialize align_.
            * output.h (Output_segment): Add align, set_align and align_.
            * testsuite/Makefile.am (gnu_property_test.stdout): Pass -lhSWn
            to $(TEST_READELF).
            (gnu_property_test): Pass --build-id to ld.
            * testsuite/Makefile.in: Regenerated.
            * testsuite/gnu_property_test.sh (check_alignment): New.
            Use check_alignment to check the NT_GNU_PROPERTY_TYPE_0 note
            alignment.  Verify that there are 2 PT_NOTE segments.
Comment 9 H.J. Lu 2020-10-13 12:32:55 UTC
Fixed for 2.36.