ld: Support ELF GNU program properties
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 3 Apr 2017 15:03:14 +0000 (08:03 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 3 Apr 2017 15:08:27 +0000 (08:08 -0700)
From .note.gnu.property section in each ELF input, we build a list of
GNU properties if .note.gnu.property section isn't corrupt.  The unknown
properties are ignored.  All property lists in relocatable inputs are
merged into an output property list.  When -z stack-size=N is used and
N isn't 0, the GNU_PROPERTY_STACK_SIZE property will be merged with or
added to the output property list.  .note.gnu.property section is
generated in output from the output property list.

bfd/

* Makefile.am (BFD32_BACKENDS): Add elf-properties.lo.
(BFD32_BACKENDS_CFILES): Add elf-properties.c.
* configure.ac (elf): Add elf-properties.lo.
* Makefile.in: Regenerated.
* configure: Likewise.
* elf-bfd.h (elf_property_kind): New.
(elf_property): Likewise.
(elf_property_list): Likewise.
(elf_properties): Likewise.
(_bfd_elf_parse_gnu_properties): Likewise.
(_bfd_elf_get_property): Likewise.
(_bfd_elf_link_setup_gnu_properties): Likewise.
(elf_backend_data): Add parse_gnu_properties, merge_gnu_properties
and setup_gnu_properties.
(elf_obj_tdata): Add properties.
* elf-properties.c: New file.
* elf32-i386.c (elf_i386_parse_gnu_properties): New.
(elf_i386_merge_gnu_properties): Likewise.
(elf_backend_parse_gnu_properties): Likewise.
(elf_backend_merge_gnu_properties): Likewise.
* elf64-x86-64.c (elf_x86_64_parse_gnu_properties): Likewise.
(elf_x86_64_merge_gnu_properties): Likewise.
(elf_backend_parse_gnu_properties): Likewise.
(elf_backend_merge_gnu_properties): Likewise.
* elfxx-target.h (elf_backend_merge_gnu_properties): Likewise.
(elf_backend_parse_gnu_properties): Likewise.
(elf_backend_setup_gnu_properties): Likewise.
(elfNN_bed): Add elf_backend_parse_gnu_properties,
elf_backend_merge_gnu_properties and
elf_backend_setup_gnu_properties.

ld/

* ld/NEWS: Mention support for ELF GNU program properties.
* emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Call
ELF setup_gnu_properties.
* testsuite/ld-i386/i386.exp: Run property tests for Linux/i386.
* testsuite/ld-i386/pass.c: New file.
* testsuite/ld-i386/property-1.r: Likewise.
* testsuite/ld-i386/property-2.r: Likewise.
* testsuite/ld-i386/property-3.r: Likewise.
* testsuite/ld-i386/property-4.r: Likewise.
* testsuite/ld-i386/property-5.r: Likewise.
* testsuite/ld-i386/property-6.r: Likewise.
* testsuite/ld-i386/property-6a.c: Likewise.
* testsuite/ld-i386/property-6b.c: Likewise.
* testsuite/ld-i386/property-6c.S: Likewise.
* testsuite/ld-i386/property-7.r: Likewise.
* testsuite/ld-i386/property-no-copy.S: Likewise.
* testsuite/ld-i386/property-stack.S: Likewise.
* testsuite/ld-i386/property-unsorted-1.S: Likewise.
* testsuite/ld-i386/property-unsorted-2.S: Likewise.
* testsuite/ld-i386/property-x86-1.S: Likewise.
* testsuite/ld-i386/property-x86-2.S: Likewise.
* testsuite/ld-x86-64/pass.c: Likewise.
* testsuite/ld-x86-64/property-1.r: Likewise.
* testsuite/ld-x86-64/property-2.r: Likewise.
* testsuite/ld-x86-64/property-3.r: Likewise.
* testsuite/ld-x86-64/property-4.r: Likewise.
* testsuite/ld-x86-64/property-5.r: Likewise.
* testsuite/ld-x86-64/property-6.r: Likewise.
* testsuite/ld-x86-64/property-6a.c: Likewise.
* testsuite/ld-x86-64/property-6b.c: Likewise.
* testsuite/ld-x86-64/property-6c.S: Likewise.
* testsuite/ld-x86-64/property-7.r: Likewise.
* testsuite/ld-x86-64/property-no-copy.S: Likewise.
* testsuite/ld-x86-64/property-stack.S: Likewise.
* testsuite/ld-x86-64/property-unsorted-1.S: Likewise.
* testsuite/ld-x86-64/property-unsorted-2.S: Likewise.
* testsuite/ld-x86-64/property-x86-1.S: Likewise.
* testsuite/ld-x86-64/property-x86-2.S: Likewise.
* testsuite/ld-x86-64/x86-64.exp: Run property tests for
Linux/x86-64.

50 files changed:
bfd/ChangeLog
bfd/Makefile.am
bfd/Makefile.in
bfd/configure
bfd/configure.ac
bfd/elf-bfd.h
bfd/elf-properties.c [new file with mode: 0644]
bfd/elf.c
bfd/elf32-i386.c
bfd/elf64-x86-64.c
bfd/elfxx-target.h
ld/ChangeLog
ld/NEWS
ld/emultempl/elf32.em
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-i386/pass.c [new file with mode: 0644]
ld/testsuite/ld-i386/property-1.r [new file with mode: 0644]
ld/testsuite/ld-i386/property-2.r [new file with mode: 0644]
ld/testsuite/ld-i386/property-3.r [new file with mode: 0644]
ld/testsuite/ld-i386/property-4.r [new file with mode: 0644]
ld/testsuite/ld-i386/property-5.r [new file with mode: 0644]
ld/testsuite/ld-i386/property-6.r [new file with mode: 0644]
ld/testsuite/ld-i386/property-6a.c [new file with mode: 0644]
ld/testsuite/ld-i386/property-6b.c [new file with mode: 0644]
ld/testsuite/ld-i386/property-6c.S [new file with mode: 0644]
ld/testsuite/ld-i386/property-7.r [new file with mode: 0644]
ld/testsuite/ld-i386/property-no-copy.S [new file with mode: 0644]
ld/testsuite/ld-i386/property-stack.S [new file with mode: 0644]
ld/testsuite/ld-i386/property-unsorted-1.S [new file with mode: 0644]
ld/testsuite/ld-i386/property-unsorted-2.S [new file with mode: 0644]
ld/testsuite/ld-i386/property-x86-1.S [new file with mode: 0644]
ld/testsuite/ld-i386/property-x86-2.S [new file with mode: 0644]
ld/testsuite/ld-x86-64/pass.c [new file with mode: 0644]
ld/testsuite/ld-x86-64/property-1.r [new file with mode: 0644]
ld/testsuite/ld-x86-64/property-2.r [new file with mode: 0644]
ld/testsuite/ld-x86-64/property-3.r [new file with mode: 0644]
ld/testsuite/ld-x86-64/property-4.r [new file with mode: 0644]
ld/testsuite/ld-x86-64/property-5.r [new file with mode: 0644]
ld/testsuite/ld-x86-64/property-6.r [new file with mode: 0644]
ld/testsuite/ld-x86-64/property-6a.c [new file with mode: 0644]
ld/testsuite/ld-x86-64/property-6b.c [new file with mode: 0644]
ld/testsuite/ld-x86-64/property-6c.S [new file with mode: 0644]
ld/testsuite/ld-x86-64/property-7.r [new file with mode: 0644]
ld/testsuite/ld-x86-64/property-no-copy.S [new file with mode: 0644]
ld/testsuite/ld-x86-64/property-stack.S [new file with mode: 0644]
ld/testsuite/ld-x86-64/property-unsorted-1.S [new file with mode: 0644]
ld/testsuite/ld-x86-64/property-unsorted-2.S [new file with mode: 0644]
ld/testsuite/ld-x86-64/property-x86-1.S [new file with mode: 0644]
ld/testsuite/ld-x86-64/property-x86-2.S [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp

index bb851c7a9fad3a6413edd8be465e681fb400e04e..c676e6d1cbcc1ccce12e3330b5fce7a672afbf5c 100644 (file)
@@ -1,3 +1,36 @@
+2017-04-03  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * Makefile.am (BFD32_BACKENDS): Add elf-properties.lo.
+       (BFD32_BACKENDS_CFILES): Add elf-properties.c.
+       * configure.ac (elf): Add elf-properties.lo.
+       * Makefile.in: Regenerated.
+       * configure: Likewise.
+       * elf-bfd.h (elf_property_kind): New.
+       (elf_property): Likewise.
+       (elf_property_list): Likewise.
+       (elf_properties): Likewise.
+       (_bfd_elf_parse_gnu_properties): Likewise.
+       (_bfd_elf_get_property): Likewise.
+       (_bfd_elf_link_setup_gnu_properties): Likewise.
+       (elf_backend_data): Add parse_gnu_properties, merge_gnu_properties
+       and setup_gnu_properties.
+       (elf_obj_tdata): Add properties.
+       * elf-properties.c: New file.
+       * elf32-i386.c (elf_i386_parse_gnu_properties): New.
+       (elf_i386_merge_gnu_properties): Likewise.
+       (elf_backend_parse_gnu_properties): Likewise.
+       (elf_backend_merge_gnu_properties): Likewise.
+       * elf64-x86-64.c (elf_x86_64_parse_gnu_properties): Likewise.
+       (elf_x86_64_merge_gnu_properties): Likewise.
+       (elf_backend_parse_gnu_properties): Likewise.
+       (elf_backend_merge_gnu_properties): Likewise.
+       * elfxx-target.h (elf_backend_merge_gnu_properties): Likewise.
+       (elf_backend_parse_gnu_properties): Likewise.
+       (elf_backend_setup_gnu_properties): Likewise.
+       (elfNN_bed): Add elf_backend_parse_gnu_properties,
+       elf_backend_merge_gnu_properties and
+       elf_backend_setup_gnu_properties.
+
 2017-03-30  Pip Cet  <pipcet@gmail.com>
 
        * elf32-wasm32.c: Add relocation code, two relocs.
index 49ab092fc3d4ee37507e343ebb6530d75e50c922..97b608ca97567cc5034b402afb201a5b9bf1fcbd 100644 (file)
@@ -321,6 +321,7 @@ BFD32_BACKENDS = \
        elf-m10200.lo \
        elf-m10300.lo \
        elf-nacl.lo \
+       elf-properties.lo \
        elf-strtab.lo \
        elf-vxworks.lo \
        elf.lo \
@@ -516,6 +517,7 @@ BFD32_BACKENDS_CFILES = \
        elf-m10200.c \
        elf-m10300.c \
        elf-nacl.c \
+       elf-properties.c \
        elf-strtab.c \
        elf-vxworks.c \
        elf.c \
index fed5117b44874090382a5155fbbf678f826ea72c..e48abaf7388459f13f50db8ed829c264aaf91dda 100644 (file)
@@ -655,6 +655,7 @@ BFD32_BACKENDS = \
        elf-m10200.lo \
        elf-m10300.lo \
        elf-nacl.lo \
+       elf-properties.lo \
        elf-strtab.lo \
        elf-vxworks.lo \
        elf.lo \
@@ -850,6 +851,7 @@ BFD32_BACKENDS_CFILES = \
        elf-m10200.c \
        elf-m10300.c \
        elf-nacl.c \
+       elf-properties.c \
        elf-strtab.c \
        elf-vxworks.c \
        elf.c \
@@ -1471,6 +1473,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf-m10200.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf-m10300.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf-nacl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf-properties.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf-strtab.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf-vxworks.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf.Plo@am__quote@
index 7cae4ae3d85baadbdef6186d1aee932a42884e2f..24e3e2f679057cde52d28933c317658540ccec63 100755 (executable)
@@ -14234,7 +14234,7 @@ selarchs="$f"
 # Target backend .o files.
 tb=
 
-elf="elf.lo elflink.lo elf-attrs.lo elf-strtab.lo
+elf="elf.lo elflink.lo elf-attrs.lo elf-strtab.lo elf-properties.lo
      elf-eh-frame.lo dwarf1.lo dwarf2.lo"
 coffgen="coffgen.lo dwarf2.lo"
 coff="cofflink.lo $coffgen"
index feb1231c91949a9365d04997380882a95078b6ae..e568847e464bcfd5683ede2e21cf2bd69f1f2160 100644 (file)
@@ -365,7 +365,7 @@ selarchs="$f"
 # Target backend .o files.
 tb=
 
-elf="elf.lo elflink.lo elf-attrs.lo elf-strtab.lo
+elf="elf.lo elflink.lo elf-attrs.lo elf-strtab.lo elf-properties.lo
      elf-eh-frame.lo dwarf1.lo dwarf2.lo"
 coffgen="coffgen.lo dwarf2.lo"
 coff="cofflink.lo $coffgen"
index 9e3d6f5fed810c59836b69cffeb62290a44c5f2e..af377eedc0864ba24b47827763acbebd8e1dbef6 100644 (file)
@@ -766,6 +766,39 @@ typedef asection * (*elf_gc_mark_hook_fn)
   (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
    struct elf_link_hash_entry *, Elf_Internal_Sym *);
 
+enum elf_property_kind
+ {
+    /* A new property.  */
+    property_unknown = 0,
+    /* A property ignored by backend.  */
+    property_ignored,
+    /* A corrupt property reported by backend.  */
+    property_corrupt,
+    /* A property should be removed due to property merge.  */
+    property_remove,
+    /* A property which is a number.  */
+    property_number
+ };
+
+typedef struct elf_property
+{
+  unsigned int pr_type;
+  unsigned int pr_datasz;
+  union
+    {
+      /* For property_number, this is a number.  */
+      bfd_vma number;
+      /* Add a new one if elf_property_kind is updated.  */
+    } u;
+  enum elf_property_kind pr_kind;
+} elf_property;
+
+typedef struct elf_property_list
+{
+  struct elf_property_list *next;
+  struct elf_property property;
+} elf_property_list;
+
 struct bfd_elf_section_reloc_data;
 
 struct elf_backend_data
@@ -1389,6 +1422,19 @@ struct elf_backend_data
      or give an error and return FALSE.  */
   bfd_boolean (*obj_attrs_handle_unknown) (bfd *, int);
 
+  /* Parse GNU properties.  Return the property kind.  If the property
+     is corrupt, issue an error message and return property_corrupt.  */
+  enum elf_property_kind (*parse_gnu_properties) (bfd *, unsigned int,
+                                                 bfd_byte *,
+                                                 unsigned int);
+
+  /* Merge GNU properties.  Return TRUE if property is updated.  */
+  bfd_boolean (*merge_gnu_properties) (bfd *, elf_property *,
+                                      elf_property *);
+
+  /* Set up GNU properties.  */
+  void (*setup_gnu_properties) (struct bfd_link_info *);
+
   /* Encoding used for compact EH tables.  */
   int (*compact_eh_encoding) (struct bfd_link_info *);
 
@@ -1798,6 +1844,10 @@ struct elf_obj_tdata
   /* Symbol buffer.  */
   void *symbuf;
 
+  /* List of GNU properties.  Will be updated by setup_gnu_properties
+     after all input GNU properties are merged for output.  */
+  elf_property_list *properties;
+
   obj_attribute known_obj_attributes[2][NUM_KNOWN_OBJ_ATTRIBUTES];
   obj_attribute_list *other_obj_attributes[2];
 
@@ -1882,6 +1932,7 @@ struct elf_obj_tdata
   (elf_known_obj_attributes (bfd) [OBJ_ATTR_PROC])
 #define elf_other_obj_attributes_proc(bfd) \
   (elf_other_obj_attributes (bfd) [OBJ_ATTR_PROC])
+#define elf_properties(bfd) (elf_tdata (bfd) -> properties)
 \f
 extern void _bfd_elf_swap_verdef_in
   (bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *);
@@ -2538,6 +2589,13 @@ extern bfd_boolean _bfd_elf_merge_unknown_attribute_low (bfd *, bfd *, int);
 extern bfd_boolean _bfd_elf_merge_unknown_attribute_list (bfd *, bfd *);
 extern Elf_Internal_Shdr *_bfd_elf_single_rel_hdr (asection *sec);
 
+extern bfd_boolean _bfd_elf_parse_gnu_properties
+  (bfd *, Elf_Internal_Note *);
+extern elf_property * _bfd_elf_get_property
+  (bfd *, unsigned int, unsigned int);
+extern void _bfd_elf_link_setup_gnu_properties
+  (struct bfd_link_info *);
+
 /* The linker may need to keep track of the number of relocs that it
    decides to copy as dynamic relocs in check_relocs for each symbol.
    This is so that it can later discard them if they are found to be
diff --git a/bfd/elf-properties.c b/bfd/elf-properties.c
new file mode 100644 (file)
index 0000000..a0456f8
--- /dev/null
@@ -0,0 +1,483 @@
+/* ELF program property support.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* GNU program property draft is at:
+
+   https://github.com/hjl-tools/linux-abi/wiki/property-draft.pdf
+ */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+
+/* Get a property, allocate a new one if needed.  */
+
+elf_property *
+_bfd_elf_get_property (bfd *abfd, unsigned int type, unsigned int datasz)
+{
+  elf_property_list *p, **lastp;
+
+  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
+    {
+      /* Never should happen.  */
+      abort ();
+    }
+
+  /* Keep the property list in order of type.  */
+  lastp = &elf_properties (abfd);
+  for (p = *lastp; p; p = p->next)
+    {
+      /* Reuse the existing entry.  */
+      if (type == p->property.pr_type)
+       {
+         if (datasz > p->property.pr_datasz)
+           {
+             /* This can happen when mixing 32-bit and 64-bit objects.  */
+             p->property.pr_datasz = datasz;
+           }
+         return &p->property;
+       }
+      else if (type < p->property.pr_type)
+       break;
+      lastp = &p->next;
+    }
+  p = (elf_property_list *) bfd_alloc (abfd, sizeof (*p));
+  if (p == NULL)
+    {
+      _bfd_error_handler (_("%B: out of memory in _bfd_elf_get_property"),
+                         abfd);
+      _exit (EXIT_FAILURE);
+    }
+  memset (p, 0, sizeof (*p));
+  p->property.pr_type = type;
+  p->property.pr_datasz = datasz;
+  p->next = *lastp;
+  *lastp = p;
+  return &p->property;
+}
+
+/* Parse GNU properties.  */
+
+bfd_boolean
+_bfd_elf_parse_gnu_properties (bfd *abfd, Elf_Internal_Note *note)
+{
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  unsigned int align_size = bed->s->elfclass == ELFCLASS64 ? 8 : 4;
+  bfd_byte *ptr = (bfd_byte *) note->descdata;
+  bfd_byte *ptr_end = ptr + note->descsz;
+
+  if (note->descsz < 8 || (note->descsz % align_size) != 0)
+    {
+bad_size:
+      _bfd_error_handler
+       (_("warning: %B: corrupt GNU_PROPERTY_TYPE (%ld) size: %#lx\n"),
+        abfd, note->type, note->descsz);
+      return FALSE;
+    }
+
+  while (1)
+    {
+      unsigned int type = bfd_h_get_32 (abfd, ptr);
+      unsigned int datasz = bfd_h_get_32 (abfd, ptr + 4);
+      elf_property *prop;
+
+      ptr += 8;
+
+      if ((ptr + datasz) > ptr_end)
+       {
+         _bfd_error_handler
+           (_("warning: %B: corrupt GNU_PROPERTY_TYPE (%ld) type (0x%x) datasz: 0x%x\n"),
+            abfd, note->type, type, datasz);
+         /* Clear all properties.  */
+         elf_properties (abfd) = NULL;
+         return FALSE;
+       }
+
+      if (type >= GNU_PROPERTY_LOPROC)
+       {
+         if (type < GNU_PROPERTY_LOUSER && bed->parse_gnu_properties)
+           {
+             enum elf_property_kind kind
+               = bed->parse_gnu_properties (abfd, type, ptr, datasz);
+             if (kind == property_corrupt)
+               {
+                 /* Clear all properties.  */
+                 elf_properties (abfd) = NULL;
+                 return FALSE;
+               }
+             else if (kind != property_ignored)
+               goto next;
+           }
+       }
+      else
+       {
+         switch (type)
+           {
+           case GNU_PROPERTY_STACK_SIZE:
+             if (datasz != align_size)
+               {
+                 _bfd_error_handler
+                   (_("warning: %B: corrupt stack size: 0x%x\n"),
+                    abfd, datasz);
+                 /* Clear all properties.  */
+                 elf_properties (abfd) = NULL;
+                 return FALSE;
+               }
+             prop = _bfd_elf_get_property (abfd, type, datasz);
+             if (datasz == 8)
+               prop->u.number = bfd_h_get_64 (abfd, ptr);
+             else
+               prop->u.number = bfd_h_get_32 (abfd, ptr);
+             prop->pr_kind = property_number;
+             goto next;
+
+           case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
+             if (datasz != 0)
+               {
+                 _bfd_error_handler
+                   (_("warning: %B: corrupt no copy on protected size: 0x%x\n"),
+                    abfd, datasz);
+                 /* Clear all properties.  */
+                 elf_properties (abfd) = NULL;
+                 return FALSE;
+               }
+             prop = _bfd_elf_get_property (abfd, type, datasz);
+             prop->pr_kind = property_number;
+             goto next;
+
+           default:
+             break;
+           }
+       }
+
+      _bfd_error_handler
+       (_("warning: %B: unsupported GNU_PROPERTY_TYPE (%ld) type: 0x%x\n"),
+        abfd, note->type, type);
+
+next:
+      ptr += (datasz + (align_size - 1)) & ~ (align_size - 1);
+      if (ptr == ptr_end)
+       break;
+
+      if (ptr > (ptr_end - 8))
+       goto bad_size;
+    }
+
+  return TRUE;
+}
+
+/* Merge GNU property BPROP with APROP.  If APROP isn't NULL, return TRUE
+   if APROP is updated.  Otherwise, return TRUE if BPROP should be merged
+   with ABFD.  */
+
+static bfd_boolean
+elf_merge_gnu_properties (bfd *abfd, elf_property *aprop,
+                         elf_property *bprop)
+{
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  unsigned int pr_type = aprop != NULL ? aprop->pr_type : bprop->pr_type;
+
+  if (bed->merge_gnu_properties != NULL
+      && pr_type >= GNU_PROPERTY_LOPROC
+      && pr_type < GNU_PROPERTY_LOUSER)
+    return bed->merge_gnu_properties (abfd, aprop, bprop);
+
+  switch (pr_type)
+    {
+    case GNU_PROPERTY_STACK_SIZE:
+      if (aprop != NULL && bprop != NULL)
+       {
+         if (bprop->u.number > aprop->u.number)
+           {
+             aprop->u.number = bprop->u.number;
+             return TRUE;
+           }
+         break;
+       }
+      /* FALLTHROUGH */
+
+    case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
+      /* Return TRUE if APROP is NULL to indicate that BPROP should
+        be added to ABFD.  */
+      return aprop == NULL;
+
+    default:
+      /* Never should happen.  */
+      abort ();
+    }
+
+  return FALSE;
+}
+
+/* Return the property of TYPE on *LISTP and remove it from *LISTP.
+   Return NULL if not found.  */
+
+static elf_property *
+elf_find_and_remove_property (elf_property_list **listp,
+                             unsigned int type)
+{
+  elf_property_list *list;
+
+  for (list = *listp; list; list = list->next)
+    {
+      if (type == list->property.pr_type)
+       {
+         /* Remove this property.  */
+         *listp = list->next;
+         return &list->property;
+       }
+      else if (type < list->property.pr_type)
+       break;
+      listp = &list->next;
+    }
+
+  return NULL;
+}
+
+/* Merge GNU property list *LISTP with ABFD.  */
+
+static void
+elf_merge_gnu_property_list (bfd *abfd, elf_property_list **listp)
+{
+  elf_property_list *p, **lastp;
+  elf_property *pr;
+
+  /* Merge each GNU property in ABFD with the one on *LISTP.  */
+  lastp = &elf_properties (abfd);
+  for (p = *lastp; p; p = p->next)
+    {
+      pr = elf_find_and_remove_property (listp, p->property.pr_type);
+      /* Pass NULL to elf_merge_gnu_properties for the property which
+        isn't on *LISTP.  */
+      elf_merge_gnu_properties (abfd, &p->property, pr);
+      if (p->property.pr_kind == property_remove)
+       {
+         /* Remove this property.  */
+         *lastp = p->next;
+         continue;
+       }
+      lastp = &p->next;
+    }
+
+  /* Merge the remaining properties on *LISTP with ABFD.  */
+  for (p = *listp; p != NULL; p = p->next)
+    if (elf_merge_gnu_properties (abfd, NULL, &p->property))
+      {
+       pr = _bfd_elf_get_property (abfd, p->property.pr_type,
+                                   p->property.pr_datasz);
+       /* It must be a new property.  */
+       if (pr->pr_kind != property_unknown)
+         abort ();
+       /* Add a new property.  */
+       *pr = p->property;
+      }
+}
+
+/* Set up GNU properties.  */
+
+void
+_bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info)
+{
+  bfd *abfd, *first_pbfd = NULL;
+  elf_property_list *list;
+  asection *sec;
+  bfd_boolean has_properties = FALSE;
+  const struct elf_backend_data *bed
+    = get_elf_backend_data (info->output_bfd);
+  unsigned int elfclass = bed->s->elfclass;
+  int elf_machine_code = bed->elf_machine_code;
+
+  /* Find the first relocatable ELF input with GNU properties.  */
+  for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
+    if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
+       && bfd_count_sections (abfd) != 0
+       && elf_properties (abfd) != NULL)
+      {
+       has_properties = TRUE;
+
+       /* Ignore GNU properties from ELF objects with different machine
+          code or class.  */
+       if ((elf_machine_code
+            == get_elf_backend_data (abfd)->elf_machine_code)
+           && (elfclass
+               == get_elf_backend_data (abfd)->s->elfclass))
+         {
+           /* Keep .note.gnu.property section in FIRST_PBFD.  */
+           first_pbfd = abfd;
+           break;
+         }
+      }
+
+  /* Do nothing if there is no .note.gnu.property section.  */
+  if (!has_properties)
+    return;
+
+  /* Merge .note.gnu.property sections.  */
+  for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
+    if (abfd != first_pbfd && bfd_count_sections (abfd) != 0)
+      {
+       elf_property_list *null_ptr = NULL;
+       elf_property_list **listp = &null_ptr;
+
+       /* Merge .note.gnu.property section in relocatable ELF input.  */
+       if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+         {
+           list = elf_properties (abfd);
+
+           /* Ignore GNU properties from ELF objects with different
+              machine code.  */
+           if (list != NULL
+               && (elf_machine_code
+                   == get_elf_backend_data (abfd)->elf_machine_code))
+             listp = &elf_properties (abfd);
+         }
+       else
+         list = NULL;
+
+       /* Merge properties with FIRST_PBFD.  FIRST_PBFD can be NULL
+          when all properties are from ELF objects with different
+          machine code or class.  */
+       if (first_pbfd != NULL)
+         elf_merge_gnu_property_list (first_pbfd, listp);
+
+       if (list != NULL)
+         {
+           /* Discard .note.gnu.property section in the rest inputs.  */
+           sec = bfd_get_section_by_name (abfd,
+                                          NOTE_GNU_PROPERTY_SECTION_NAME);
+           sec->output_section = bfd_abs_section_ptr;
+         }
+      }
+
+  /* Rewrite .note.gnu.property section so that GNU properties are
+     always sorted by type even if input GNU properties aren't sorted.  */
+  if (first_pbfd != NULL)
+    {
+      unsigned int size;
+      unsigned int descsz;
+      bfd_byte *contents;
+      Elf_External_Note *e_note;
+      unsigned int align_size = bed->s->elfclass == ELFCLASS64 ? 8 : 4;
+
+      sec = bfd_get_section_by_name (first_pbfd,
+                                    NOTE_GNU_PROPERTY_SECTION_NAME);
+
+      /* Update stack size in .note.gnu.property with -z stack-size=N
+        if N > 0.  */
+      if (info->stacksize > 0)
+       {
+         elf_property *p;
+         bfd_vma stacksize = info->stacksize;
+
+         p = _bfd_elf_get_property (first_pbfd, GNU_PROPERTY_STACK_SIZE,
+                                    align_size);
+         if (p->pr_kind == property_unknown)
+           {
+             /* Create GNU_PROPERTY_STACK_SIZE.  */
+             p->u.number = stacksize;
+             p->pr_kind = property_number;
+           }
+         else if (stacksize > p->u.number)
+           p->u.number = stacksize;
+       }
+      else if (elf_properties (first_pbfd) == NULL)
+       {
+         /* Discard .note.gnu.property section if all properties have
+            been removed.  */
+         sec->output_section = bfd_abs_section_ptr;
+         return;
+       }
+
+      /* Compute the section size.  */
+      descsz = offsetof (Elf_External_Note, name[sizeof "GNU"]);
+      descsz = (descsz + 3) & -(unsigned int) 4;
+      size = descsz;
+      for (list = elf_properties (first_pbfd);
+          list != NULL;
+          list = list->next)
+       {
+         /* There are 4 byte type + 4 byte datasz for each property.  */
+         size += 4 + 4 + list->property.pr_datasz;
+         /* Align each property.  */
+         size = (size + (align_size - 1)) & ~(align_size - 1);
+       }
+
+      /* Update .note.gnu.property section now.  */
+      sec->size = size;
+      contents = (bfd_byte *) bfd_zalloc (first_pbfd, size);
+
+      e_note = (Elf_External_Note *) contents;
+      bfd_h_put_32 (first_pbfd, sizeof "GNU", &e_note->namesz);
+      bfd_h_put_32 (first_pbfd, size - descsz, &e_note->descsz);
+      bfd_h_put_32 (first_pbfd, NT_GNU_PROPERTY_TYPE_0, &e_note->type);
+      memcpy (e_note->name, "GNU", sizeof "GNU");
+
+      size = descsz;
+      for (list = elf_properties (first_pbfd);
+          list != NULL;
+          list = list->next)
+       {
+         /* There are 4 byte type + 4 byte datasz for each property.  */
+         bfd_h_put_32 (first_pbfd, list->property.pr_type,
+                       contents + size);
+         bfd_h_put_32 (first_pbfd, list->property.pr_datasz,
+                       contents + size + 4);
+         size += 4 + 4;
+
+         /* Write out property value.  */
+         switch (list->property.pr_kind)
+           {
+           case property_number:
+             switch (list->property.pr_datasz)
+               {
+               default:
+                 /* Never should happen.  */
+                 abort ();
+
+               case 0:
+                 break;
+
+               case 4:
+                 bfd_h_put_32 (first_pbfd, list->property.u.number,
+                               contents + size);
+                 break;
+
+               case 8:
+                 bfd_h_put_64 (first_pbfd, list->property.u.number,
+                               contents + size);
+                 break;
+               }
+             break;
+
+           default:
+             /* Never should happen.  */
+             abort ();
+           }
+         size += list->property.pr_datasz;
+
+         /* Align each property.  */
+         size = (size + (align_size - 1)) & ~ (align_size - 1);
+       }
+
+      /* Cache the section contents for elf_link_input_bfd.  */
+      elf_section_data (sec)->this_hdr.contents = contents;
+    }
+}
index 9418e51a7e0e30f09fc5a0798175125ec5a1b69c..d4d91b65c7893a87b556569877cb55465b9471fd 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -9691,6 +9691,9 @@ elfobj_grok_gnu_note (bfd *abfd, Elf_Internal_Note *note)
     default:
       return TRUE;
 
+    case NT_GNU_PROPERTY_TYPE_0:
+      return _bfd_elf_parse_gnu_properties (abfd, note);
+
     case NT_GNU_BUILD_ID:
       return elfobj_grok_gnu_build_id (abfd, note);
     }
index 2784ef71cbe323a9de9625553c7d9996312e6303..b1afb49c6a106362f09a8d0b2ce8ce9185e8fb3b 100644 (file)
@@ -6131,6 +6131,78 @@ elf_i386_hash_symbol (struct elf_link_hash_entry *h)
   return _bfd_elf_hash_symbol (h);
 }
 
+/* Parse i386 GNU properties.  */
+
+static enum elf_property_kind
+elf_i386_parse_gnu_properties (bfd *abfd, unsigned int type,
+                              bfd_byte *ptr, unsigned int datasz)
+{
+  elf_property *prop;
+
+  switch (type)
+    {
+    case GNU_PROPERTY_X86_ISA_1_USED:
+    case GNU_PROPERTY_X86_ISA_1_NEEDED:
+      if (datasz != 4)
+       {
+         _bfd_error_handler
+           ((type == GNU_PROPERTY_X86_ISA_1_USED
+             ? _("error: %B: <corrupt x86 ISA used size: 0x%x>\n")
+             : _("error: %B: <corrupt x86 ISA needed size: 0x%x>\n")),
+            abfd, datasz);
+         return property_corrupt;
+       }
+      prop = _bfd_elf_get_property (abfd, type, datasz);
+      prop->u.number = bfd_h_get_32 (abfd, ptr);
+      prop->pr_kind = property_number;
+      break;
+
+    default:
+      return property_ignored;
+    }
+
+  return property_number;
+}
+
+/* Merge i386 GNU property BPROP with APROP.  If APROP isn't NULL,
+   return TRUE if APROP is updated.  Otherwise, return TRUE if BPROP
+   should be merged with ABFD.  */
+
+static bfd_boolean
+elf_i386_merge_gnu_properties (bfd *abfd ATTRIBUTE_UNUSED,
+                              elf_property *aprop,
+                              elf_property *bprop)
+{
+  unsigned int number;
+  bfd_boolean updated = FALSE;
+  unsigned int pr_type = aprop != NULL ? aprop->pr_type : bprop->pr_type;
+
+  switch (pr_type)
+    {
+    case GNU_PROPERTY_X86_ISA_1_USED:
+    case GNU_PROPERTY_X86_ISA_1_NEEDED:
+      if (aprop != NULL && bprop != NULL)
+       {
+         number = aprop->u.number;
+         aprop->u.number = number | bprop->u.number;
+         updated = number != (unsigned int) aprop->u.number;
+       }
+      else
+       {
+         /* Return TRUE if APROP is NULL to indicate that BPROP should
+            be added to ABFD.  */
+         updated = aprop == NULL;
+       }
+      break;
+
+    default:
+      /* Never should happen.  */
+      abort ();
+    }
+
+  return updated;
+}
+
 #define TARGET_LITTLE_SYM              i386_elf32_vec
 #define TARGET_LITTLE_NAME             "elf32-i386"
 #define ELF_ARCH                       bfd_arch_i386
@@ -6182,6 +6254,8 @@ elf_i386_hash_symbol (struct elf_link_hash_entry *h)
   ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
 #define elf_backend_hash_symbol                      elf_i386_hash_symbol
 #define elf_backend_fixup_symbol             elf_i386_fixup_symbol
+#define elf_backend_parse_gnu_properties      elf_i386_parse_gnu_properties
+#define elf_backend_merge_gnu_properties      elf_i386_merge_gnu_properties
 
 #include "elf32-target.h"
 
index e0e6c16fcd32b077228851597d087b98d053d9f0..6d92c79c931a32e746a34c726138101f71189043 100644 (file)
@@ -6896,8 +6896,80 @@ elf_x86_64_relocs_compatible (const bfd_target *input,
          && _bfd_elf_relocs_compatible (input, output));
 }
 
+/* Parse x86-64 GNU properties.  */
+
+static enum elf_property_kind
+elf_x86_64_parse_gnu_properties (bfd *abfd, unsigned int type,
+                                bfd_byte *ptr, unsigned int datasz)
+{
+  elf_property *prop;
+
+  switch (type)
+    {
+    case GNU_PROPERTY_X86_ISA_1_USED:
+    case GNU_PROPERTY_X86_ISA_1_NEEDED:
+      if (datasz != 4)
+       {
+         _bfd_error_handler
+           ((type == GNU_PROPERTY_X86_ISA_1_USED
+             ? _("error: %B: <corrupt x86 ISA used size: 0x%x>\n")
+             : _("error: %B: <corrupt x86 ISA needed size: 0x%x>\n")),
+            abfd, datasz);
+         return property_corrupt;
+       }
+      prop = _bfd_elf_get_property (abfd, type, datasz);
+      prop->u.number = bfd_h_get_32 (abfd, ptr);
+      prop->pr_kind = property_number;
+      break;
+
+    default:
+      return property_ignored;
+    }
+
+  return property_number;
+}
+
+/* Merge x86-64 GNU property BPROP with APROP.  If APROP isn't NULL,
+   return TRUE if APROP is updated.  Otherwise, return TRUE if BPROP
+   should be merged with ABFD.  */
+
+static bfd_boolean
+elf_x86_64_merge_gnu_properties (bfd *abfd ATTRIBUTE_UNUSED,
+                                elf_property *aprop,
+                                elf_property *bprop)
+{
+  unsigned int number;
+  bfd_boolean updated = FALSE;
+  unsigned int pr_type = aprop != NULL ? aprop->pr_type : bprop->pr_type;
+
+  switch (pr_type)
+    {
+    case GNU_PROPERTY_X86_ISA_1_USED:
+    case GNU_PROPERTY_X86_ISA_1_NEEDED:
+      if (aprop != NULL && bprop != NULL)
+       {
+         number = aprop->u.number;
+         aprop->u.number = number | bprop->u.number;
+         updated = number != (unsigned int) aprop->u.number;
+       }
+      else
+       {
+         /* Return TRUE if APROP is NULL to indicate that BPROP should
+            be added to ABFD.  */
+         updated = aprop == NULL;
+       }
+      break;
+
+    default:
+      /* Never should happen.  */
+      abort ();
+    }
+
+  return updated;
+}
+
 static const struct bfd_elf_special_section
-  elf_x86_64_special_sections[]=
+elf_x86_64_special_sections[]=
 {
   { STRING_COMMA_LEN (".gnu.linkonce.lb"), -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
   { STRING_COMMA_LEN (".gnu.linkonce.lr"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE},
@@ -6988,6 +7060,10 @@ static const struct bfd_elf_special_section
   ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
 #define elf_backend_fixup_symbol \
   elf_x86_64_fixup_symbol
+#define elf_backend_parse_gnu_properties \
+  elf_x86_64_parse_gnu_properties
+#define elf_backend_merge_gnu_properties \
+ elf_x86_64_merge_gnu_properties
 
 #include "elf64-target.h"
 
index d063fb7f1bae918706f7d34cde622070e1e75903..6cc9f3f7a600bf14493c642b6ee49f3a637024f3 100644 (file)
 #ifndef elf_backend_obj_attrs_handle_unknown
 #define elf_backend_obj_attrs_handle_unknown   NULL
 #endif
+#ifndef elf_backend_parse_gnu_properties
+#define elf_backend_parse_gnu_properties       NULL
+#endif
+#ifndef elf_backend_merge_gnu_properties
+#define elf_backend_merge_gnu_properties       NULL
+#endif
+#ifndef elf_backend_setup_gnu_properties
+#define elf_backend_setup_gnu_properties       _bfd_elf_link_setup_gnu_properties
+#endif
 #ifndef elf_backend_static_tls_alignment
 #define elf_backend_static_tls_alignment       1
 #endif
@@ -838,6 +847,9 @@ static struct elf_backend_data elfNN_bed =
   elf_backend_obj_attrs_section_type,
   elf_backend_obj_attrs_order,
   elf_backend_obj_attrs_handle_unknown,
+  elf_backend_parse_gnu_properties,
+  elf_backend_merge_gnu_properties,
+  elf_backend_setup_gnu_properties,
   elf_backend_compact_eh_encoding,
   elf_backend_cant_unwind_opcode,
   elf_backend_static_tls_alignment,
index 84ef78ec4a2ec7f4ea01fe2da652f18d7a5e9645..62b78b13b75109b884500c854ba83f89abdbc390 100644 (file)
@@ -1,3 +1,46 @@
+2017-04-03  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * ld/NEWS: Mention support for ELF GNU program properties.
+       * emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Call
+       ELF setup_gnu_properties.
+       * testsuite/ld-i386/i386.exp: Run property tests for Linux/i386.
+       * testsuite/ld-i386/pass.c: New file.
+       * testsuite/ld-i386/property-1.r: Likewise.
+       * testsuite/ld-i386/property-2.r: Likewise.
+       * testsuite/ld-i386/property-3.r: Likewise.
+       * testsuite/ld-i386/property-4.r: Likewise.
+       * testsuite/ld-i386/property-5.r: Likewise.
+       * testsuite/ld-i386/property-6.r: Likewise.
+       * testsuite/ld-i386/property-6a.c: Likewise.
+       * testsuite/ld-i386/property-6b.c: Likewise.
+       * testsuite/ld-i386/property-6c.S: Likewise.
+       * testsuite/ld-i386/property-7.r: Likewise.
+       * testsuite/ld-i386/property-no-copy.S: Likewise.
+       * testsuite/ld-i386/property-stack.S: Likewise.
+       * testsuite/ld-i386/property-unsorted-1.S: Likewise.
+       * testsuite/ld-i386/property-unsorted-2.S: Likewise.
+       * testsuite/ld-i386/property-x86-1.S: Likewise.
+       * testsuite/ld-i386/property-x86-2.S: Likewise.
+       * testsuite/ld-x86-64/pass.c: Likewise.
+       * testsuite/ld-x86-64/property-1.r: Likewise.
+       * testsuite/ld-x86-64/property-2.r: Likewise.
+       * testsuite/ld-x86-64/property-3.r: Likewise.
+       * testsuite/ld-x86-64/property-4.r: Likewise.
+       * testsuite/ld-x86-64/property-5.r: Likewise.
+       * testsuite/ld-x86-64/property-6.r: Likewise.
+       * testsuite/ld-x86-64/property-6a.c: Likewise.
+       * testsuite/ld-x86-64/property-6b.c: Likewise.
+       * testsuite/ld-x86-64/property-6c.S: Likewise.
+       * testsuite/ld-x86-64/property-7.r: Likewise.
+       * testsuite/ld-x86-64/property-no-copy.S: Likewise.
+       * testsuite/ld-x86-64/property-stack.S: Likewise.
+       * testsuite/ld-x86-64/property-unsorted-1.S: Likewise.
+       * testsuite/ld-x86-64/property-unsorted-2.S: Likewise.
+       * testsuite/ld-x86-64/property-x86-1.S: Likewise.
+       * testsuite/ld-x86-64/property-x86-2.S: Likewise.
+       * testsuite/ld-x86-64/x86-64.exp: Run property tests for
+       Linux/x86-64.
+
 2017-03-28  Hans-Peter Nilsson  <hp@axis.com>
 
        PR ld/16044
diff --git a/ld/NEWS b/ld/NEWS
index 972e7a85ee6b8a1294deb34b28b5f48d9a1c170c..039a90e8cab1d0d862e49a0c1e8359850d6ad9df 100644 (file)
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,7 @@
 -*- text -*-
 
+* Add support for ELF GNU program properties.
+
 * Add support for the Texas Instruments PRU processor.
 
 * When configuring for arc*-*-linux* targets the default linker emulation will
index d4837d0415ac247bc239a281a81f2d6e789cd763..007e48d6a85897b0167c84a580f820dc006f67c1 100644 (file)
@@ -1258,6 +1258,8 @@ gld${EMULATION_NAME}_after_open (void)
        }
     }
 
+  get_elf_backend_data (link_info.output_bfd)->setup_gnu_properties (&link_info);
+
   if (bfd_link_relocatable (&link_info))
     {
       if (link_info.execstack == ! link_info.noexecstack)
index c489227df7f5639a3d1cb8e5e27173776bdd7c18..844b36f50711414a5f16429150e32ee0a81c2efd 100644 (file)
@@ -736,6 +736,174 @@ if { [isnative]
            {{objdump {-dw} pr19319.dd}} \
            "pr19319" \
        ] \
+       [list \
+           "Build property 1" \
+           "" \
+           "" \
+           {pass.c property-no-copy.S} \
+           {{readelf {-n} property-1.r}} \
+           "property-1" \
+       ] \
+       [list \
+           "Build property 1 (.o)" \
+           "-r -nostdlib" \
+           "" \
+           {pass.c property-no-copy.S} \
+           {{readelf {-n} property-1.r}} \
+           "property-1.o" \
+       ] \
+       [list \
+           "Build property 1 (.so)" \
+           "-shared" \
+           "-fPIC" \
+           {pass.c property-no-copy.S} \
+           {{readelf {-n} property-1.r}} \
+           "property-1.so" \
+       ] \
+       [list \
+           "Build property 2" \
+           "" \
+           "" \
+           {pass.c property-stack.S} \
+           {{readelf {-n} property-2.r}} \
+           "property-2" \
+       ] \
+       [list \
+           "Build property 2 (.o)" \
+           "-r -nostdlib" \
+           "" \
+           {pass.c property-stack.S} \
+           {{readelf {-n} property-2.r}} \
+           "property-2.o" \
+       ] \
+       [list \
+           "Build property 2 (.so)" \
+           "-shared" \
+           "-fPIC" \
+           {pass.c property-stack.S} \
+           {{readelf {-n} property-2.r}} \
+           "property-2.so" \
+       ] \
+       [list \
+           "Build property 3" \
+           "" \
+           "" \
+           {pass.c property-stack.S property-x86-1.S} \
+           {{readelf {-n} property-3.r}} \
+           "property-3" \
+       ] \
+       [list \
+           "Build property 3 (.o)" \
+           "-r -nostdlib" \
+           "" \
+           {pass.c property-x86-1.S property-stack.S} \
+           {{readelf {-n} property-3.r}} \
+           "property-3.o" \
+       ] \
+       [list \
+           "Build property 3 (.so)" \
+           "-shared" \
+           "-fPIC" \
+           {property-x86-1.S pass.c property-stack.S} \
+           {{readelf {-n} property-3.r}} \
+           "property-3.so" \
+       ] \
+       [list \
+           "Build property 4" \
+           "" \
+           "" \
+           {pass.c property-stack.S property-x86-1.S property-x86-2.S} \
+           {{readelf {-n} property-4.r}} \
+           "property-4" \
+       ] \
+       [list \
+           "Build property 4 (.o)" \
+           "-r -nostdlib" \
+           "" \
+           {pass.c property-x86-2.S property-x86-1.S property-stack.S} \
+           {{readelf {-n} property-4.r}} \
+           "property-4.o" \
+       ] \
+       [list \
+           "Build property 4 (.so)" \
+           "-shared" \
+           "-fPIC" \
+           {property-x86-2.S property-x86-1.S pass.c property-stack.S} \
+           {{readelf {-n} property-4.r}} \
+           "property-4.so" \
+       ] \
+       [list \
+           "Build property 4 (-Wl,-z,stack-size=0)" \
+           "-Wl,-z,stack-size=0" \
+           "" \
+           {pass.c property-stack.S property-x86-1.S property-x86-2.S} \
+           {{readelf {-n} property-4.r}} \
+           "property-4" \
+       ] \
+       [list \
+           "Build property 5" \
+           "-Wl,-z,stack-size=0x900000" \
+           "" \
+           {pass.c property-stack.S property-x86-1.S property-x86-2.S} \
+           {{readelf {-n} property-5.r}} \
+           "property-5" \
+       ] \
+       [list \
+           "Build property 5 (.o)" \
+           "-r -nostdlib -Wl,-z,stack-size=0x900000" \
+           "" \
+           {pass.c property-x86-2.S property-x86-1.S property-stack.S} \
+           {{readelf {-n} property-5.r}} \
+           "property-5.o" \
+       ] \
+       [list \
+           "Build property 5 (.so)" \
+           "-shared -Wl,-z,stack-size=0x900000" \
+           "-fPIC" \
+           {property-x86-2.S property-x86-1.S pass.c property-stack.S} \
+           {{readelf {-n} property-5.r}} \
+           "property-5.so" \
+       ] \
+       [list \
+           "Build property-6.so" \
+           "-shared" \
+           "-fPIC" \
+           {property-6a.c property-6c.S} \
+           {{readelf {-n} property-6.r}} \
+           "property-6.so" \
+       ] \
+       [list \
+           "Build property-6.o" \
+           "-r -nostdlib" \
+           "" \
+           {property-6b.c property-stack.S} \
+           {{readelf {-n} property-2.r}} \
+           "property-6.o" \
+       ] \
+       [list \
+           "Build property-6" \
+           "-Wl,--as-needed tmpdir/property-6.o tmpdir/property-6.so" \
+           { dummy.s } \
+           "" \
+           {{readelf {-n} property-2.r}} \
+           "property-6" \
+       ] \
+       [list \
+           "Build property 7a (.o)" \
+           "-r -nostdlib" \
+           "" \
+           {property-unsorted-1.S} \
+           {{readelf {-n} property-7.r}} \
+           "property-7a.o" \
+       ] \
+       [list \
+           "Build property 7b (.o)" \
+           "-r -nostdlib" \
+           "" \
+           {property-unsorted-2.S} \
+           {{readelf {-n} property-7.r}} \
+           "property-7b.o" \
+       ] \
     ]
 
     run_ld_link_exec_tests [list \
@@ -814,6 +982,111 @@ if { [isnative]
            "got1" \
            "got1.out" \
        ] \
+       [list \
+           "Run property 1" \
+           "" \
+           "" \
+           {pass.c property-no-copy.S} \
+           "property-1" "pass.out" \
+       ] \
+       [list \
+           "Run property 1 (PIE)" \
+           "-pie" \
+           "" \
+           {pass.c property-no-copy.S} \
+           "property-1-pie" "pass.out" "-fPIE" \
+       ] \
+       [list \
+           "Run property 1 (static)" \
+           "-static" \
+           "" \
+           {pass.c property-no-copy.S} \
+           "property-1-static" "pass.out" \
+       ] \
+       [list \
+           "Run property 2" \
+           "" \
+           "" \
+           {pass.c property-stack.S} \
+           "property-2" "pass.out" \
+       ] \
+       [list \
+           "Run property 2 (PIE)" \
+           "-pie" \
+           "" \
+           {pass.c property-stack.S} \
+           "property-2-pie" "pass.out" "-fPIE" \
+       ] \
+       [list \
+           "Run property 2 (static)" \
+           "-static" \
+           "" \
+           {pass.c property-stack.S} \
+           "property-3-static" "pass.out" \
+       ] \
+       [list \
+           "Run property 3" \
+           "" \
+           "" \
+           {pass.c property-stack.S property-x86-1.S} \
+           "property-3" "pass.out" \
+       ] \
+       [list \
+           "Run property 3 (PIE)" \
+           "-pie" \
+           "" \
+           {pass.c property-x86-1.S property-stack.S} \
+           "property-3-pie" "pass.out" "-fPIE" \
+       ] \
+       [list \
+           "Run property 3 (static)" \
+           "-static" \
+           "" \
+           {property-x86-1.S pass.c property-stack.S} \
+           "property-3-static" "pass.out" \
+       ] \
+       [list \
+           "Run property 4" \
+           "" \
+           "" \
+           {pass.c property-stack.S property-x86-1.S property-x86-2.S} \
+           "property-4" "pass.out" \
+       ] \
+       [list \
+           "Run property 4 (PIE)" \
+           "-pie" \
+           "" \
+           {pass.c property-x86-2.S property-x86-1.S property-stack.S} \
+           "property-4-pie" "pass.out" "-fPIE" \
+       ] \
+       [list \
+           "Run property 4 (static)" \
+           "-static" \
+           "" \
+           {property-x86-2.S property-x86-1.S pass.c property-stack.S} \
+           "property-4-static" "pass.out" \
+       ] \
+       [list \
+           "Run property 5" \
+           "-Wl,-z,stack-size=0x900000" \
+           "" \
+           {pass.c property-stack.S property-x86-1.S property-x86-2.S} \
+           "property-5" "pass.out" \
+       ] \
+       [list \
+           "Run property 5 (PIE)" \
+           "-pie -Wl,-z,stack-size=0x900000" \
+           "" \
+           {pass.c property-x86-2.S property-x86-1.S property-stack.S} \
+           "property-5-pie" "pass.out" "-fPIE" \
+       ] \
+       [list \
+           "Run property 5 (static)" \
+           "-static -Wl,-z,stack-size=0x900000" \
+           "" \
+           {property-x86-2.S property-x86-1.S pass.c property-stack.S} \
+           "property-5-static" "pass.out" \
+       ] \
     ]
 
     undefined_weak "" ""
diff --git a/ld/testsuite/ld-i386/pass.c b/ld/testsuite/ld-i386/pass.c
new file mode 100644 (file)
index 0000000..8fb892c
--- /dev/null
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int
+main ()
+{
+  printf ("PASS\n");
+  return 0;
+}
diff --git a/ld/testsuite/ld-i386/property-1.r b/ld/testsuite/ld-i386/property-1.r
new file mode 100644 (file)
index 0000000..d8f08c0
--- /dev/null
@@ -0,0 +1,7 @@
+#...
+Displaying notes found in: .note.gnu.property
+  Owner                 Data size      Description
+  GNU                  0x[0-9a-f]+     NT_GNU_PROPERTY_TYPE_0
+      Properties: no copy on protected 
+
+#pass
diff --git a/ld/testsuite/ld-i386/property-2.r b/ld/testsuite/ld-i386/property-2.r
new file mode 100644 (file)
index 0000000..5e3d156
--- /dev/null
@@ -0,0 +1,7 @@
+#...
+Displaying notes found in: .note.gnu.property
+  Owner                 Data size      Description
+  GNU                  0x[0-9a-f]+     NT_GNU_PROPERTY_TYPE_0
+      Properties: stack size: 0x800000
+
+#pass
diff --git a/ld/testsuite/ld-i386/property-3.r b/ld/testsuite/ld-i386/property-3.r
new file mode 100644 (file)
index 0000000..0ed91f5
--- /dev/null
@@ -0,0 +1,8 @@
+#...
+Displaying notes found in: .note.gnu.property
+  Owner                 Data size      Description
+  GNU                  0x[0-9a-f]+     NT_GNU_PROPERTY_TYPE_0
+      Properties: stack size: 0x800000
+       x86 ISA used: 586, SSE
+       x86 ISA needed: i486, 586
+#pass
diff --git a/ld/testsuite/ld-i386/property-4.r b/ld/testsuite/ld-i386/property-4.r
new file mode 100644 (file)
index 0000000..cb2bc15
--- /dev/null
@@ -0,0 +1,8 @@
+#...
+Displaying notes found in: .note.gnu.property
+  Owner                 Data size      Description
+  GNU                  0x[0-9a-f]+     NT_GNU_PROPERTY_TYPE_0
+      Properties: stack size: 0x800000
+       x86 ISA used: i486, 586, SSE
+       x86 ISA needed: i486, 586, SSE
+#pass
diff --git a/ld/testsuite/ld-i386/property-5.r b/ld/testsuite/ld-i386/property-5.r
new file mode 100644 (file)
index 0000000..5529650
--- /dev/null
@@ -0,0 +1,8 @@
+#...
+Displaying notes found in: .note.gnu.property
+  Owner                 Data size      Description
+  GNU                  0x[0-9a-f]+     NT_GNU_PROPERTY_TYPE_0
+      Properties: stack size: 0x900000
+       x86 ISA used: i486, 586, SSE
+       x86 ISA needed: i486, 586, SSE
+#pass
diff --git a/ld/testsuite/ld-i386/property-6.r b/ld/testsuite/ld-i386/property-6.r
new file mode 100644 (file)
index 0000000..97a479f
--- /dev/null
@@ -0,0 +1,7 @@
+#...
+Displaying notes found in: .note.gnu.property
+  Owner                 Data size      Description
+  GNU                  0x[0-9a-f]+     NT_GNU_PROPERTY_TYPE_0
+      Properties: stack size: 0xa00000
+
+#pass
diff --git a/ld/testsuite/ld-i386/property-6a.c b/ld/testsuite/ld-i386/property-6a.c
new file mode 100644 (file)
index 0000000..c7cc10b
--- /dev/null
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+void
+property (void)
+{
+  printf ("PASS\n");
+}
diff --git a/ld/testsuite/ld-i386/property-6b.c b/ld/testsuite/ld-i386/property-6b.c
new file mode 100644 (file)
index 0000000..5336b0e
--- /dev/null
@@ -0,0 +1,8 @@
+extern void property (void);
+
+int
+main ()
+{
+  property ();
+  return 0;
+}
diff --git a/ld/testsuite/ld-i386/property-6c.S b/ld/testsuite/ld-i386/property-6c.S
new file mode 100644 (file)
index 0000000..13f729d
--- /dev/null
@@ -0,0 +1,18 @@
+       .section ".note.gnu.property", "a"
+       .p2align 2
+       .long 1f - 0f           /* name length.  */
+       .long 3f - 1f           /* data length.  */
+       /* NT_GNU_PROPERTY_TYPE_0 */
+       .long 5                 /* note type.  */
+0:
+       .asciz "GNU"            /* vendor name.  */
+1:
+       .p2align 2
+       /* GNU_PROPERTY_STACK_SIZE */
+       .long 1                 /* pr_type.  */
+       .long 5f - 4f           /* pr_datasz.  */
+4:
+       .dc.a 0xa00000          /* Stack size.  */
+5:
+       .p2align 2
+3:
diff --git a/ld/testsuite/ld-i386/property-7.r b/ld/testsuite/ld-i386/property-7.r
new file mode 100644 (file)
index 0000000..ad6af84
--- /dev/null
@@ -0,0 +1,6 @@
+#...
+Displaying notes found in: .note.gnu.property
+  Owner                 Data size      Description
+  GNU                  0x[0-9a-f]+     NT_GNU_PROPERTY_TYPE_0
+      Properties: stack size: 0x800000
+       no copy on protected 
diff --git a/ld/testsuite/ld-i386/property-no-copy.S b/ld/testsuite/ld-i386/property-no-copy.S
new file mode 100644 (file)
index 0000000..3116911
--- /dev/null
@@ -0,0 +1,15 @@
+       .section ".note.gnu.property", "a"
+       .p2align 2
+       .long 1f - 0f           /* name length.  */
+       .long 3f - 1f           /* data length.  */
+       /* NT_GNU_PROPERTY_TYPE_0 */
+       .long 5                 /* note type.  */
+0:
+       .asciz "GNU"            /* vendor name.  */
+1:
+       .p2align 2
+       /* GNU_PROPERTY_NO_COPY_ON_PROTECTED */
+       .long 2                 /* pr_type.  */
+       .long 0                 /* pr_datasz.  */
+       .p2align 2
+3:
diff --git a/ld/testsuite/ld-i386/property-stack.S b/ld/testsuite/ld-i386/property-stack.S
new file mode 100644 (file)
index 0000000..5e9bcce
--- /dev/null
@@ -0,0 +1,18 @@
+       .section ".note.gnu.property", "a"
+       .p2align 2
+       .long 1f - 0f           /* name length.  */
+       .long 3f - 1f           /* data length.  */
+       /* NT_GNU_PROPERTY_TYPE_0 */
+       .long 5                 /* note type.  */
+0:
+       .asciz "GNU"            /* vendor name.  */
+1:
+       .p2align 2
+       /* GNU_PROPERTY_STACK_SIZE */
+       .long 1                 /* pr_type.  */
+       .long 5f - 4f           /* pr_datasz.  */
+4:
+       .dc.a 0x800000          /* Stack size.  */
+5:
+       .p2align 2
+3:
diff --git a/ld/testsuite/ld-i386/property-unsorted-1.S b/ld/testsuite/ld-i386/property-unsorted-1.S
new file mode 100644 (file)
index 0000000..1cbb272
--- /dev/null
@@ -0,0 +1,34 @@
+       .section ".note.gnu.property", "a"
+       .p2align 2
+       .long 1f - 0f           /* name length.  */
+       .long 3f - 1f           /* data length.  */
+       /* NT_GNU_PROPERTY_TYPE_0 */
+       .long 5                 /* note type.  */
+0:
+       .asciz "GNU"            /* vendor name.  */
+1:
+       .p2align 2
+       /* GNU_PROPERTY_NO_COPY_ON_PROTECTED */
+       .long 2                 /* pr_type.  */
+       .long 0                 /* pr_datasz.  */
+       .p2align 2
+3:
+
+       .section ".note.gnu.property", "a"
+       .p2align 2
+       .long 1f - 0f           /* name length.  */
+       .long 3f - 1f           /* data length.  */
+       /* NT_GNU_PROPERTY_TYPE_0 */
+       .long 5                 /* note type.  */
+0:
+       .asciz "GNU"            /* vendor name.  */
+1:
+       .p2align 2
+       /* GNU_PROPERTY_STACK_SIZE */
+       .long 1                 /* pr_type.  */
+       .long 5f - 4f           /* pr_datasz.  */
+4:
+       .dc.a 0x800000          /* Stack size.  */
+5:
+       .p2align 2
+3:
diff --git a/ld/testsuite/ld-i386/property-unsorted-2.S b/ld/testsuite/ld-i386/property-unsorted-2.S
new file mode 100644 (file)
index 0000000..0289399
--- /dev/null
@@ -0,0 +1,22 @@
+       .section ".note.gnu.property", "a"
+       .p2align 2
+       .long 1f - 0f           /* name length.  */
+       .long 3f - 1f           /* data length.  */
+       /* NT_GNU_PROPERTY_TYPE_0 */
+       .long 5                 /* note type.  */
+0:
+       .asciz "GNU"            /* vendor name.  */
+1:
+       .p2align 2
+       /* GNU_PROPERTY_NO_COPY_ON_PROTECTED */
+       .long 2                 /* pr_type.  */
+       .long 0                 /* pr_datasz.  */
+       .p2align 2
+       /* GNU_PROPERTY_STACK_SIZE */
+       .long 1                 /* pr_type.  */
+       .long 5f - 4f           /* pr_datasz.  */
+4:
+       .dc.a 0x800000          /* Stack size.  */
+5:
+       .p2align 2
+3:
diff --git a/ld/testsuite/ld-i386/property-x86-1.S b/ld/testsuite/ld-i386/property-x86-1.S
new file mode 100644 (file)
index 0000000..953ca87
--- /dev/null
@@ -0,0 +1,32 @@
+       .section ".note.gnu.property", "a"
+       .p2align 2
+       .long 1f - 0f           /* name length.  */
+       .long 3f - 1f           /* data length.  */
+       /* NT_GNU_PROPERTY_TYPE_0 */
+       .long 5                 /* note type.  */
+0:
+       .asciz "GNU"            /* vendor name.  */
+1:
+       .p2align 2
+       /* GNU_PROPERTY_STACK_SIZE */
+       .long 1                 /* pr_type.  */
+       .long 5f - 4f           /* pr_datasz.  */
+4:
+       .dc.a 0x600000          /* Stack size.  */
+5:
+       .p2align 2
+       /* GNU_PROPERTY_X86_ISA_1_USED */
+       .long 0xc0000000        /* pr_type.  */
+       .long 5f - 4f           /* pr_datasz.  */
+4:
+       .long 0xa
+5:
+       .p2align 2
+       /* GNU_PROPERTY_X86_ISA_1_NEEDED */
+       .long 0xc0000001        /* pr_type.  */
+       .long 5f - 4f           /* pr_datasz.  */
+4:
+       .long 0x3
+5:
+       .p2align 2
+3:
diff --git a/ld/testsuite/ld-i386/property-x86-2.S b/ld/testsuite/ld-i386/property-x86-2.S
new file mode 100644 (file)
index 0000000..f11e1fe
--- /dev/null
@@ -0,0 +1,25 @@
+       .section ".note.gnu.property", "a"
+       .p2align 2
+       .long 1f - 0f           /* name length.  */
+       .long 3f - 1f           /* data length.  */
+       /* NT_GNU_PROPERTY_TYPE_0 */
+       .long 5                 /* note type.  */
+0:
+       .asciz "GNU"            /* vendor name.  */
+1:
+       .p2align 2
+       /* GNU_PROPERTY_X86_ISA_1_USED */
+       .long 0xc0000000        /* pr_type.  */
+       .long 5f - 4f           /* pr_datasz.  */
+4:
+       .long 0x3
+5:
+       .p2align 2
+       /* GNU_PROPERTY_X86_ISA_1_NEEDED */
+       .long 0xc0000001        /* pr_type.  */
+       .long 5f - 4f           /* pr_datasz.  */
+4:
+       .long 0xa
+5:
+       .p2align 2
+3:
diff --git a/ld/testsuite/ld-x86-64/pass.c b/ld/testsuite/ld-x86-64/pass.c
new file mode 100644 (file)
index 0000000..8fb892c
--- /dev/null
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int
+main ()
+{
+  printf ("PASS\n");
+  return 0;
+}
diff --git a/ld/testsuite/ld-x86-64/property-1.r b/ld/testsuite/ld-x86-64/property-1.r
new file mode 100644 (file)
index 0000000..d8f08c0
--- /dev/null
@@ -0,0 +1,7 @@
+#...
+Displaying notes found in: .note.gnu.property
+  Owner                 Data size      Description
+  GNU                  0x[0-9a-f]+     NT_GNU_PROPERTY_TYPE_0
+      Properties: no copy on protected 
+
+#pass
diff --git a/ld/testsuite/ld-x86-64/property-2.r b/ld/testsuite/ld-x86-64/property-2.r
new file mode 100644 (file)
index 0000000..5e3d156
--- /dev/null
@@ -0,0 +1,7 @@
+#...
+Displaying notes found in: .note.gnu.property
+  Owner                 Data size      Description
+  GNU                  0x[0-9a-f]+     NT_GNU_PROPERTY_TYPE_0
+      Properties: stack size: 0x800000
+
+#pass
diff --git a/ld/testsuite/ld-x86-64/property-3.r b/ld/testsuite/ld-x86-64/property-3.r
new file mode 100644 (file)
index 0000000..0ed91f5
--- /dev/null
@@ -0,0 +1,8 @@
+#...
+Displaying notes found in: .note.gnu.property
+  Owner                 Data size      Description
+  GNU                  0x[0-9a-f]+     NT_GNU_PROPERTY_TYPE_0
+      Properties: stack size: 0x800000
+       x86 ISA used: 586, SSE
+       x86 ISA needed: i486, 586
+#pass
diff --git a/ld/testsuite/ld-x86-64/property-4.r b/ld/testsuite/ld-x86-64/property-4.r
new file mode 100644 (file)
index 0000000..cb2bc15
--- /dev/null
@@ -0,0 +1,8 @@
+#...
+Displaying notes found in: .note.gnu.property
+  Owner                 Data size      Description
+  GNU                  0x[0-9a-f]+     NT_GNU_PROPERTY_TYPE_0
+      Properties: stack size: 0x800000
+       x86 ISA used: i486, 586, SSE
+       x86 ISA needed: i486, 586, SSE
+#pass
diff --git a/ld/testsuite/ld-x86-64/property-5.r b/ld/testsuite/ld-x86-64/property-5.r
new file mode 100644 (file)
index 0000000..5529650
--- /dev/null
@@ -0,0 +1,8 @@
+#...
+Displaying notes found in: .note.gnu.property
+  Owner                 Data size      Description
+  GNU                  0x[0-9a-f]+     NT_GNU_PROPERTY_TYPE_0
+      Properties: stack size: 0x900000
+       x86 ISA used: i486, 586, SSE
+       x86 ISA needed: i486, 586, SSE
+#pass
diff --git a/ld/testsuite/ld-x86-64/property-6.r b/ld/testsuite/ld-x86-64/property-6.r
new file mode 100644 (file)
index 0000000..97a479f
--- /dev/null
@@ -0,0 +1,7 @@
+#...
+Displaying notes found in: .note.gnu.property
+  Owner                 Data size      Description
+  GNU                  0x[0-9a-f]+     NT_GNU_PROPERTY_TYPE_0
+      Properties: stack size: 0xa00000
+
+#pass
diff --git a/ld/testsuite/ld-x86-64/property-6a.c b/ld/testsuite/ld-x86-64/property-6a.c
new file mode 100644 (file)
index 0000000..c7cc10b
--- /dev/null
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+void
+property (void)
+{
+  printf ("PASS\n");
+}
diff --git a/ld/testsuite/ld-x86-64/property-6b.c b/ld/testsuite/ld-x86-64/property-6b.c
new file mode 100644 (file)
index 0000000..5336b0e
--- /dev/null
@@ -0,0 +1,8 @@
+extern void property (void);
+
+int
+main ()
+{
+  property ();
+  return 0;
+}
diff --git a/ld/testsuite/ld-x86-64/property-6c.S b/ld/testsuite/ld-x86-64/property-6c.S
new file mode 100644 (file)
index 0000000..41246d3
--- /dev/null
@@ -0,0 +1,23 @@
+#ifdef __LP64__
+# define ALIGN 3
+#else
+# define ALIGN 2
+#endif
+       .section ".note.gnu.property", "a"
+       .p2align ALIGN
+       .long 1f - 0f           /* name length.  */
+       .long 3f - 1f           /* data length.  */
+       /* NT_GNU_PROPERTY_TYPE_0 */
+       .long 5                 /* note type.  */
+0:
+       .asciz "GNU"            /* vendor name.  */
+1:
+       .p2align ALIGN
+       /* GNU_PROPERTY_STACK_SIZE */
+       .long 1                 /* pr_type.  */
+       .long 5f - 4f           /* pr_datasz.  */
+4:
+       .dc.a 0xa00000          /* Stack size.  */
+5:
+       .p2align ALIGN
+3:
diff --git a/ld/testsuite/ld-x86-64/property-7.r b/ld/testsuite/ld-x86-64/property-7.r
new file mode 100644 (file)
index 0000000..ad6af84
--- /dev/null
@@ -0,0 +1,6 @@
+#...
+Displaying notes found in: .note.gnu.property
+  Owner                 Data size      Description
+  GNU                  0x[0-9a-f]+     NT_GNU_PROPERTY_TYPE_0
+      Properties: stack size: 0x800000
+       no copy on protected 
diff --git a/ld/testsuite/ld-x86-64/property-no-copy.S b/ld/testsuite/ld-x86-64/property-no-copy.S
new file mode 100644 (file)
index 0000000..88cc252
--- /dev/null
@@ -0,0 +1,20 @@
+#ifdef __LP64__
+# define ALIGN 3
+#else
+# define ALIGN 2
+#endif
+       .section ".note.gnu.property", "a"
+       .p2align ALIGN
+       .long 1f - 0f           /* name length.  */
+       .long 3f - 1f           /* data length.  */
+       /* NT_GNU_PROPERTY_TYPE_0 */
+       .long 5                 /* note type.  */
+0:
+       .asciz "GNU"            /* vendor name.  */
+1:
+       .p2align ALIGN
+       /* GNU_PROPERTY_NO_COPY_ON_PROTECTED */
+       .long 2                 /* pr_type.  */
+       .long 0                 /* pr_datasz.  */
+       .p2align ALIGN
+3:
diff --git a/ld/testsuite/ld-x86-64/property-stack.S b/ld/testsuite/ld-x86-64/property-stack.S
new file mode 100644 (file)
index 0000000..7f45654
--- /dev/null
@@ -0,0 +1,23 @@
+#ifdef __LP64__
+# define ALIGN 3
+#else
+# define ALIGN 2
+#endif
+       .section ".note.gnu.property", "a"
+       .p2align ALIGN
+       .long 1f - 0f           /* name length.  */
+       .long 3f - 1f           /* data length.  */
+       /* NT_GNU_PROPERTY_TYPE_0 */
+       .long 5                 /* note type.  */
+0:
+       .asciz "GNU"            /* vendor name.  */
+1:
+       .p2align ALIGN
+       /* GNU_PROPERTY_STACK_SIZE */
+       .long 1                 /* pr_type.  */
+       .long 5f - 4f           /* pr_datasz.  */
+4:
+       .dc.a 0x800000          /* Stack size.  */
+5:
+       .p2align ALIGN
+3:
diff --git a/ld/testsuite/ld-x86-64/property-unsorted-1.S b/ld/testsuite/ld-x86-64/property-unsorted-1.S
new file mode 100644 (file)
index 0000000..de96e7a
--- /dev/null
@@ -0,0 +1,39 @@
+#ifdef __LP64__
+# define ALIGN 3
+#else
+# define ALIGN 2
+#endif
+       .section ".note.gnu.property", "a"
+       .p2align ALIGN
+       .long 1f - 0f           /* name length.  */
+       .long 3f - 1f           /* data length.  */
+       /* NT_GNU_PROPERTY_TYPE_0 */
+       .long 5                 /* note type.  */
+0:
+       .asciz "GNU"            /* vendor name.  */
+1:
+       .p2align ALIGN
+       /* GNU_PROPERTY_NO_COPY_ON_PROTECTED */
+       .long 2                 /* pr_type.  */
+       .long 0                 /* pr_datasz.  */
+       .p2align ALIGN
+3:
+
+       .section ".note.gnu.property", "a"
+       .p2align ALIGN
+       .long 1f - 0f           /* name length.  */
+       .long 3f - 1f           /* data length.  */
+       /* NT_GNU_PROPERTY_TYPE_0 */
+       .long 5                 /* note type.  */
+0:
+       .asciz "GNU"            /* vendor name.  */
+1:
+       .p2align ALIGN
+       /* GNU_PROPERTY_STACK_SIZE */
+       .long 1                 /* pr_type.  */
+       .long 5f - 4f           /* pr_datasz.  */
+4:
+       .dc.a 0x800000          /* Stack size.  */
+5:
+       .p2align ALIGN
+3:
diff --git a/ld/testsuite/ld-x86-64/property-unsorted-2.S b/ld/testsuite/ld-x86-64/property-unsorted-2.S
new file mode 100644 (file)
index 0000000..65d7fad
--- /dev/null
@@ -0,0 +1,27 @@
+#ifdef __LP64__
+# define ALIGN 3
+#else
+# define ALIGN 2
+#endif
+       .section ".note.gnu.property", "a"
+       .p2align ALIGN
+       .long 1f - 0f           /* name length.  */
+       .long 3f - 1f           /* data length.  */
+       /* NT_GNU_PROPERTY_TYPE_0 */
+       .long 5                 /* note type.  */
+0:
+       .asciz "GNU"            /* vendor name.  */
+1:
+       .p2align ALIGN
+       /* GNU_PROPERTY_NO_COPY_ON_PROTECTED */
+       .long 2                 /* pr_type.  */
+       .long 0                 /* pr_datasz.  */
+       .p2align ALIGN
+       /* GNU_PROPERTY_STACK_SIZE */
+       .long 1                 /* pr_type.  */
+       .long 5f - 4f           /* pr_datasz.  */
+4:
+       .dc.a 0x800000          /* Stack size.  */
+5:
+       .p2align ALIGN
+3:
diff --git a/ld/testsuite/ld-x86-64/property-x86-1.S b/ld/testsuite/ld-x86-64/property-x86-1.S
new file mode 100644 (file)
index 0000000..33f2ccd
--- /dev/null
@@ -0,0 +1,37 @@
+#ifdef __LP64__
+# define ALIGN 3
+#else
+# define ALIGN 2
+#endif
+       .section ".note.gnu.property", "a"
+       .p2align ALIGN
+       .long 1f - 0f           /* name length.  */
+       .long 3f - 1f           /* data length.  */
+       /* NT_GNU_PROPERTY_TYPE_0 */
+       .long 5                 /* note type.  */
+0:
+       .asciz "GNU"            /* vendor name.  */
+1:
+       .p2align ALIGN
+       /* GNU_PROPERTY_STACK_SIZE */
+       .long 1                 /* pr_type.  */
+       .long 5f - 4f           /* pr_datasz.  */
+4:
+       .dc.a 0x600000          /* Stack size.  */
+5:
+       .p2align ALIGN
+       /* GNU_PROPERTY_X86_ISA_1_USED */
+       .long 0xc0000000        /* pr_type.  */
+       .long 5f - 4f           /* pr_datasz.  */
+4:
+       .long 0xa
+5:
+       .p2align ALIGN
+       /* GNU_PROPERTY_X86_ISA_1_NEEDED */
+       .long 0xc0000001        /* pr_type.  */
+       .long 5f - 4f           /* pr_datasz.  */
+4:
+       .long 0x3
+5:
+       .p2align ALIGN
+3:
diff --git a/ld/testsuite/ld-x86-64/property-x86-2.S b/ld/testsuite/ld-x86-64/property-x86-2.S
new file mode 100644 (file)
index 0000000..132e521
--- /dev/null
@@ -0,0 +1,30 @@
+#ifdef __LP64__
+# define ALIGN 3
+#else
+# define ALIGN 2
+#endif
+       .section ".note.gnu.property", "a"
+       .p2align ALIGN
+       .long 1f - 0f           /* name length.  */
+       .long 3f - 1f           /* data length.  */
+       /* NT_GNU_PROPERTY_TYPE_0 */
+       .long 5                 /* note type.  */
+0:
+       .asciz "GNU"            /* vendor name.  */
+1:
+       .p2align ALIGN
+       /* GNU_PROPERTY_X86_ISA_1_USED */
+       .long 0xc0000000        /* pr_type.  */
+       .long 5f - 4f           /* pr_datasz.  */
+4:
+       .long 0x3
+5:
+       .p2align ALIGN
+       /* GNU_PROPERTY_X86_ISA_1_NEEDED */
+       .long 0xc0000001        /* pr_type.  */
+       .long 5f - 4f           /* pr_datasz.  */
+4:
+       .long 0xa
+5:
+       .p2align ALIGN
+3:
index 8e4e4225dd8fccaf3c2bb676e6a2c3c4e0a619c0..e7a7f80bdabc6346837519e10496e0c6f457490f 100644 (file)
@@ -828,6 +828,174 @@ if { [isnative] && [which $CC] != 0 } {
            {{objdump {-dw} pr19319.dd}} \
            "pr19319" \
        ] \
+       [list \
+           "Build property 1" \
+           "" \
+           "" \
+           {pass.c property-no-copy.S} \
+           {{readelf {-n} property-1.r}} \
+           "property-1" \
+       ] \
+       [list \
+           "Build property 1 (.o)" \
+           "-r -nostdlib" \
+           "" \
+           {pass.c property-no-copy.S} \
+           {{readelf {-n} property-1.r}} \
+           "property-1.o" \
+       ] \
+       [list \
+           "Build property 1 (.so)" \
+           "-shared" \
+           "-fPIC" \
+           {pass.c property-no-copy.S} \
+           {{readelf {-n} property-1.r}} \
+           "property-1.so" \
+       ] \
+       [list \
+           "Build property 2" \
+           "" \
+           "" \
+           {pass.c property-stack.S} \
+           {{readelf {-n} property-2.r}} \
+           "property-2" \
+       ] \
+       [list \
+           "Build property 2 (.o)" \
+           "-r -nostdlib" \
+           "" \
+           {pass.c property-stack.S} \
+           {{readelf {-n} property-2.r}} \
+           "property-2.o" \
+       ] \
+       [list \
+           "Build property 2 (.so)" \
+           "-shared" \
+           "-fPIC" \
+           {pass.c property-stack.S} \
+           {{readelf {-n} property-2.r}} \
+           "property-2.so" \
+       ] \
+       [list \
+           "Build property 3" \
+           "" \
+           "" \
+           {pass.c property-stack.S property-x86-1.S} \
+           {{readelf {-n} property-3.r}} \
+           "property-3" \
+       ] \
+       [list \
+           "Build property 3 (.o)" \
+           "-r -nostdlib" \
+           "" \
+           {pass.c property-x86-1.S property-stack.S} \
+           {{readelf {-n} property-3.r}} \
+           "property-3.o" \
+       ] \
+       [list \
+           "Build property 3 (.so)" \
+           "-shared" \
+           "-fPIC" \
+           {property-x86-1.S pass.c property-stack.S} \
+           {{readelf {-n} property-3.r}} \
+           "property-3.so" \
+       ] \
+       [list \
+           "Build property 4" \
+           "" \
+           "" \
+           {pass.c property-stack.S property-x86-1.S property-x86-2.S} \
+           {{readelf {-n} property-4.r}} \
+           "property-4" \
+       ] \
+       [list \
+           "Build property 4 (.o)" \
+           "-r -nostdlib" \
+           "" \
+           {pass.c property-x86-2.S property-x86-1.S property-stack.S} \
+           {{readelf {-n} property-4.r}} \
+           "property-4.o" \
+       ] \
+       [list \
+           "Build property 4 (.so)" \
+           "-shared" \
+           "-fPIC" \
+           {property-x86-2.S property-x86-1.S pass.c property-stack.S} \
+           {{readelf {-n} property-4.r}} \
+           "property-4.so" \
+       ] \
+       [list \
+           "Build property 4 (-Wl,-z,stack-size=0)" \
+           "-Wl,-z,stack-size=0" \
+           "" \
+           {pass.c property-stack.S property-x86-1.S property-x86-2.S} \
+           {{readelf {-n} property-4.r}} \
+           "property-4" \
+       ] \
+       [list \
+           "Build property 5" \
+           "-Wl,-z,stack-size=0x900000" \
+           "" \
+           {pass.c property-stack.S property-x86-1.S property-x86-2.S} \
+           {{readelf {-n} property-5.r}} \
+           "property-5" \
+       ] \
+       [list \
+           "Build property 5 (.o)" \
+           "-r -nostdlib -Wl,-z,stack-size=0x900000" \
+           "" \
+           {pass.c property-x86-2.S property-x86-1.S property-stack.S} \
+           {{readelf {-n} property-5.r}} \
+           "property-5.o" \
+       ] \
+       [list \
+           "Build property 5 (.so)" \
+           "-shared -Wl,-z,stack-size=0x900000" \
+           "-fPIC" \
+           {property-x86-2.S property-x86-1.S pass.c property-stack.S} \
+           {{readelf {-n} property-5.r}} \
+           "property-5.so" \
+       ] \
+       [list \
+           "Build property-6.so" \
+           "-shared" \
+           "-fPIC" \
+           {property-6a.c property-6c.S} \
+           {{readelf {-n} property-6.r}} \
+           "property-6.so" \
+       ] \
+       [list \
+           "Build property-6.o" \
+           "-r -nostdlib" \
+           "" \
+           {property-6b.c property-stack.S} \
+           {{readelf {-n} property-2.r}} \
+           "property-6.o" \
+       ] \
+       [list \
+           "Build property-6" \
+           "-Wl,--as-needed tmpdir/property-6.o tmpdir/property-6.so" \
+           { dummy.s } \
+           "" \
+           {{readelf {-n} property-2.r}} \
+           "property-6" \
+       ] \
+       [list \
+           "Build property 7a (.o)" \
+           "-r -nostdlib" \
+           "" \
+           {property-unsorted-1.S} \
+           {{readelf {-n} property-7.r}} \
+           "property-7a.o" \
+       ] \
+       [list \
+           "Build property 7b (.o)" \
+           "-r -nostdlib" \
+           "" \
+           {property-unsorted-2.S} \
+           {{readelf {-n} property-7.r}} \
+           "property-7b.o" \
+       ] \
     ]
 
     run_ld_link_exec_tests [list \
@@ -898,6 +1066,111 @@ if { [isnative] && [which $CC] != 0 } {
            "gotpcrel1" \
            "gotpcrel1.out" \
        ] \
+       [list \
+           "Run property 1" \
+           "" \
+           "" \
+           {pass.c property-no-copy.S} \
+           "property-1" "pass.out" \
+       ] \
+       [list \
+           "Run property 1 (PIE)" \
+           "-pie" \
+           "" \
+           {pass.c property-no-copy.S} \
+           "property-1-pie" "pass.out" "-fPIE" \
+       ] \
+       [list \
+           "Run property 1 (static)" \
+           "-static" \
+           "" \
+           {pass.c property-no-copy.S} \
+           "property-1-static" "pass.out" \
+       ] \
+       [list \
+           "Run property 2" \
+           "" \
+           "" \
+           {pass.c property-stack.S} \
+           "property-2" "pass.out" \
+       ] \
+       [list \
+           "Run property 2 (PIE)" \
+           "-pie" \
+           "" \
+           {pass.c property-stack.S} \
+           "property-2-pie" "pass.out" "-fPIE" \
+       ] \
+       [list \
+           "Run property 2 (static)" \
+           "-static" \
+           "" \
+           {pass.c property-stack.S} \
+           "property-3-static" "pass.out" \
+       ] \
+       [list \
+           "Run property 3" \
+           "" \
+           "" \
+           {pass.c property-stack.S property-x86-1.S} \
+           "property-3" "pass.out" \
+       ] \
+       [list \
+           "Run property 3 (PIE)" \
+           "-pie" \
+           "" \
+           {pass.c property-x86-1.S property-stack.S} \
+           "property-3-pie" "pass.out" "-fPIE" \
+       ] \
+       [list \
+           "Run property 3 (static)" \
+           "-static" \
+           "" \
+           {property-x86-1.S pass.c property-stack.S} \
+           "property-3-static" "pass.out" \
+       ] \
+       [list \
+           "Run property 4" \
+           "" \
+           "" \
+           {pass.c property-stack.S property-x86-1.S property-x86-2.S} \
+           "property-4" "pass.out" \
+       ] \
+       [list \
+           "Run property 4 (PIE)" \
+           "-pie" \
+           "" \
+           {pass.c property-x86-2.S property-x86-1.S property-stack.S} \
+           "property-4-pie" "pass.out" "-fPIE" \
+       ] \
+       [list \
+           "Run property 4 (static)" \
+           "-static" \
+           "" \
+           {property-x86-2.S property-x86-1.S pass.c property-stack.S} \
+           "property-4-static" "pass.out" \
+       ] \
+       [list \
+           "Run property 5" \
+           "-Wl,-z,stack-size=0x900000" \
+           "" \
+           {pass.c property-stack.S property-x86-1.S property-x86-2.S} \
+           "property-5" "pass.out" \
+       ] \
+       [list \
+           "Run property 5 (PIE)" \
+           "-pie -Wl,-z,stack-size=0x900000" \
+           "" \
+           {pass.c property-x86-2.S property-x86-1.S property-stack.S} \
+           "property-5-pie" "pass.out" "-fPIE" \
+       ] \
+       [list \
+           "Run property 5 (static)" \
+           "-static -Wl,-z,stack-size=0x900000" \
+           "" \
+           {property-x86-2.S property-x86-1.S pass.c property-stack.S} \
+           "property-5-static" "pass.out" \
+       ] \
     ]
 
     # Run-time tests which require working ifunc attribute support.