* RFC: ld: Support ELF GNU program properties
@ 2017-03-13 18:21 H.J. Lu
2017-03-23 15:25 ` H.J. Lu
2017-03-24 12:23 ` Nick Clifton
0 siblings, 2 replies; 6+ messages in thread
From: H.J. Lu @ 2017-03-13 18:21 UTC (permalink / raw)
To: binutils
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.
Any comments?
H.J.
---
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 and
merge_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.
(elfNN_bed): Add elf_backend_parse_gnu_properties and
elf_backend_merge_gnu_properties.
ld/
* emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Call
_bfd_elf_link_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-no-copy.S: Likewise.
* testsuite/ld-i386/property-stack.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-no-copy.S: Likewise.
* testsuite/ld-x86-64/property-stack.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.
---
bfd/Makefile.am | 2 +
bfd/Makefile.in | 3 +
bfd/configure | 2 +-
bfd/configure.ac | 2 +-
bfd/elf-bfd.h | 44 ++++
bfd/elf-properties.c | 370 ++++++++++++++++++++++++++++++
bfd/elf.c | 3 +
bfd/elf32-i386.c | 62 +++++
bfd/elf64-x86-64.c | 66 +++++-
bfd/elfxx-target.h | 8 +
ld/emultempl/elf32.em | 2 +
ld/testsuite/ld-i386/i386.exp | 257 +++++++++++++++++++++
ld/testsuite/ld-i386/pass.c | 8 +
ld/testsuite/ld-i386/property-1.r | 7 +
ld/testsuite/ld-i386/property-2.r | 7 +
ld/testsuite/ld-i386/property-3.r | 8 +
ld/testsuite/ld-i386/property-4.r | 8 +
ld/testsuite/ld-i386/property-5.r | 8 +
ld/testsuite/ld-i386/property-6.r | 7 +
ld/testsuite/ld-i386/property-6a.c | 7 +
ld/testsuite/ld-i386/property-6b.c | 8 +
ld/testsuite/ld-i386/property-6c.S | 18 ++
ld/testsuite/ld-i386/property-no-copy.S | 15 ++
ld/testsuite/ld-i386/property-stack.S | 18 ++
ld/testsuite/ld-i386/property-x86-1.S | 32 +++
ld/testsuite/ld-i386/property-x86-2.S | 25 ++
ld/testsuite/ld-x86-64/pass.c | 8 +
ld/testsuite/ld-x86-64/property-1.r | 7 +
ld/testsuite/ld-x86-64/property-2.r | 7 +
ld/testsuite/ld-x86-64/property-3.r | 8 +
ld/testsuite/ld-x86-64/property-4.r | 8 +
ld/testsuite/ld-x86-64/property-5.r | 8 +
ld/testsuite/ld-x86-64/property-6.r | 7 +
ld/testsuite/ld-x86-64/property-6a.c | 7 +
ld/testsuite/ld-x86-64/property-6b.c | 8 +
ld/testsuite/ld-x86-64/property-6c.S | 23 ++
ld/testsuite/ld-x86-64/property-no-copy.S | 20 ++
ld/testsuite/ld-x86-64/property-stack.S | 23 ++
ld/testsuite/ld-x86-64/property-x86-1.S | 37 +++
ld/testsuite/ld-x86-64/property-x86-2.S | 30 +++
ld/testsuite/ld-x86-64/x86-64.exp | 257 +++++++++++++++++++++
41 files changed, 1452 insertions(+), 3 deletions(-)
create mode 100644 bfd/elf-properties.c
create mode 100644 ld/testsuite/ld-i386/pass.c
create mode 100644 ld/testsuite/ld-i386/property-1.r
create mode 100644 ld/testsuite/ld-i386/property-2.r
create mode 100644 ld/testsuite/ld-i386/property-3.r
create mode 100644 ld/testsuite/ld-i386/property-4.r
create mode 100644 ld/testsuite/ld-i386/property-5.r
create mode 100644 ld/testsuite/ld-i386/property-6.r
create mode 100644 ld/testsuite/ld-i386/property-6a.c
create mode 100644 ld/testsuite/ld-i386/property-6b.c
create mode 100644 ld/testsuite/ld-i386/property-6c.S
create mode 100644 ld/testsuite/ld-i386/property-no-copy.S
create mode 100644 ld/testsuite/ld-i386/property-stack.S
create mode 100644 ld/testsuite/ld-i386/property-x86-1.S
create mode 100644 ld/testsuite/ld-i386/property-x86-2.S
create mode 100644 ld/testsuite/ld-x86-64/pass.c
create mode 100644 ld/testsuite/ld-x86-64/property-1.r
create mode 100644 ld/testsuite/ld-x86-64/property-2.r
create mode 100644 ld/testsuite/ld-x86-64/property-3.r
create mode 100644 ld/testsuite/ld-x86-64/property-4.r
create mode 100644 ld/testsuite/ld-x86-64/property-5.r
create mode 100644 ld/testsuite/ld-x86-64/property-6.r
create mode 100644 ld/testsuite/ld-x86-64/property-6a.c
create mode 100644 ld/testsuite/ld-x86-64/property-6b.c
create mode 100644 ld/testsuite/ld-x86-64/property-6c.S
create mode 100644 ld/testsuite/ld-x86-64/property-no-copy.S
create mode 100644 ld/testsuite/ld-x86-64/property-stack.S
create mode 100644 ld/testsuite/ld-x86-64/property-x86-1.S
create mode 100644 ld/testsuite/ld-x86-64/property-x86-2.S
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 0b02263..87dd2db 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -319,6 +319,7 @@ BFD32_BACKENDS = \
elf-m10200.lo \
elf-m10300.lo \
elf-nacl.lo \
+ elf-properties.lo \
elf-strtab.lo \
elf-vxworks.lo \
elf.lo \
@@ -512,6 +513,7 @@ BFD32_BACKENDS_CFILES = \
elf-m10200.c \
elf-m10300.c \
elf-nacl.c \
+ elf-properties.c \
elf-strtab.c \
elf-vxworks.c \
elf.c \
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index 096c7ef..67d112d 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -653,6 +653,7 @@ BFD32_BACKENDS = \
elf-m10200.lo \
elf-m10300.lo \
elf-nacl.lo \
+ elf-properties.lo \
elf-strtab.lo \
elf-vxworks.lo \
elf.lo \
@@ -846,6 +847,7 @@ BFD32_BACKENDS_CFILES = \
elf-m10200.c \
elf-m10300.c \
elf-nacl.c \
+ elf-properties.c \
elf-strtab.c \
elf-vxworks.c \
elf.c \
@@ -1464,6 +1466,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@
diff --git a/bfd/configure b/bfd/configure
index 83256d2..a40e621 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -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"
diff --git a/bfd/configure.ac b/bfd/configure.ac
index ee0c537..e90ea9f 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -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"
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 9e3d6f5..fd500c5 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -766,6 +766,31 @@ 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
+ {
+ property_unknown = 0,
+ property_ignored,
+ property_corrupt,
+ property_value
+ };
+
+typedef struct elf_property
+{
+ unsigned int type;
+ unsigned int datasz;
+ union
+ {
+ bfd_vma value;
+ } u;
+ enum elf_property_kind 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 +1414,15 @@ struct elf_backend_data
or give an error and return FALSE. */
bfd_boolean (*obj_attrs_handle_unknown) (bfd *, int);
+ /* Parse GNU properties. */
+ enum elf_property_kind (*parse_gnu_properties) (bfd *, unsigned int,
+ bfd_byte *,
+ unsigned int);
+
+ /* Merge GNU properties. */
+ bfd_boolean (*merge_gnu_properties) (bfd *, elf_property *,
+ elf_property *);
+
/* Encoding used for compact EH tables. */
int (*compact_eh_encoding) (struct bfd_link_info *);
@@ -1798,6 +1832,8 @@ struct elf_obj_tdata
/* Symbol buffer. */
void *symbuf;
+ elf_property_list *properties;
+
obj_attribute known_obj_attributes[2][NUM_KNOWN_OBJ_ATTRIBUTES];
obj_attribute_list *other_obj_attributes[2];
@@ -1882,6 +1918,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 +2575,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
index 0000000..e849a43
--- /dev/null
+++ b/bfd/elf-properties.c
@@ -0,0 +1,370 @@
+/* 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. */
+
+#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;
+
+ /* 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.type)
+ return &p->property;
+ else if (type < p->property.type)
+ break;
+ lastp = &p->next;
+ }
+ p = (elf_property_list *) bfd_alloc (abfd, sizeof (*p));
+ memset (p, 0, sizeof (*p));
+ p->property.type = type;
+ p->property.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.value = bfd_h_get_64 (abfd, ptr);
+ else
+ prop->u.value = bfd_h_get_32 (abfd, ptr);
+ prop->kind = property_value;
+ 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->kind = property_value;
+ 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. Return TRUE if property is updated. */
+
+static bfd_boolean
+elf_merge_gnu_properties (bfd *abfd, elf_property *prop, elf_property *p)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ if (prop->type >= GNU_PROPERTY_LOPROC
+ && prop->type < GNU_PROPERTY_LOUSER
+ && bed->merge_gnu_properties != NULL)
+ return bed->merge_gnu_properties (abfd, prop, p);
+
+ switch (prop->type)
+ {
+ case GNU_PROPERTY_STACK_SIZE:
+ if (p->u.value > prop->u.value)
+ {
+ prop->u.value = p->u.value;
+ return TRUE;
+ }
+ break;
+
+ case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
+ break;
+
+ default:
+ /* Never should happen. */
+ abort ();
+ }
+
+ return FALSE;
+}
+
+/* Merge GNU property list. Return TRUE if property list is updated. */
+
+static bfd_boolean
+elf_merge_gnu_property_list (bfd *abfd, elf_property_list *list)
+{
+ bfd_boolean updated = FALSE;
+
+ for (; list != NULL; list = list->next)
+ {
+ elf_property *p;
+ p = _bfd_elf_get_property (abfd, list->property.type,
+ list->property.datasz);
+ if (p->kind == property_unknown)
+ {
+ /* Add a new property. */
+ *p = list->property;
+ updated = TRUE;
+ }
+ else
+ updated |= elf_merge_gnu_properties (abfd, p, &list->property);
+ }
+
+ return updated;
+}
+
+/* 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 updated = FALSE;
+ const struct elf_backend_data *bed;
+ unsigned int align_size;
+
+ 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)
+ {
+ /* Check .note.gnu.property section in relocatable ELF input. */
+ list = elf_properties (abfd);
+ if (list)
+ {
+ if (first_pbfd == NULL)
+ {
+ /* Keep .note.gnu.property section in FIRST_PBFD. */
+ first_pbfd = abfd;
+ continue;
+ }
+
+ /* Merge properties with FIRST_PBFD. */
+ updated |= elf_merge_gnu_property_list (first_pbfd, list);
+
+ /* Discard .note.gnu.property section in the rest inputs. */
+ sec = bfd_get_section_by_name (abfd, ".note.gnu.property");
+ sec->output_section = bfd_abs_section_ptr;
+ }
+ }
+
+ /* Do nothing if there is no .note.gnu.property section. */
+ if (first_pbfd == NULL)
+ return;
+
+ bed = get_elf_backend_data (first_pbfd);
+ align_size = bed->s->elfclass == ELFCLASS64 ? 8 : 4;
+
+ /* Update stack size in .note.gnu.property with -z stack-size=N if
+ N > 0. */
+ if (info->stacksize && first_pbfd != NULL && 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->kind == property_unknown)
+ {
+ /* Create GNU_PROPERTY_STACK_SIZE. */
+ p->u.value = stacksize;
+ p->kind = property_value;
+ updated = TRUE;
+ }
+ else if (stacksize > p->u.value)
+ {
+ p->u.value = stacksize;
+ updated = TRUE;
+ }
+ }
+
+ if (updated)
+ {
+ unsigned int size;
+ unsigned int descsz;
+ bfd_byte *contents;
+ Elf_External_Note *e_note;
+
+ sec = bfd_get_section_by_name (first_pbfd, ".note.gnu.property");
+
+ /* 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.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.type,
+ contents + size);
+ bfd_h_put_32 (first_pbfd, list->property.datasz,
+ contents + size + 4);
+ size += 4 + 4;
+
+ /* Write out property value. */
+ switch (list->property.kind)
+ {
+ case property_value:
+ switch (list->property.datasz)
+ {
+ default:
+ /* Never should happen. */
+ abort ();
+
+ case 0:
+ break;
+
+ case 4:
+ bfd_h_put_32 (first_pbfd, list->property.u.value,
+ contents + size);
+ break;
+
+ case 8:
+ bfd_h_put_64 (first_pbfd, list->property.u.value,
+ contents + size);
+ break;
+ }
+ break;
+
+ default:
+ /* Never should happen. */
+ abort ();
+ }
+ size += list->property.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;
+ }
+}
diff --git a/bfd/elf.c b/bfd/elf.c
index 9418e51..d4d91b6 100644
--- 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);
}
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 2784ef7..7e82b0d 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -6131,6 +6131,66 @@ 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.value = bfd_h_get_32 (abfd, ptr);
+ prop->kind = property_value;
+ break;
+
+ default:
+ return property_ignored;
+ }
+
+ return property_value;
+}
+
+/* Merge i386 GNU property. Return TRUE if property is updated. */
+
+static bfd_boolean
+elf_i386_merge_gnu_properties (bfd *abfd ATTRIBUTE_UNUSED,
+ elf_property *prop,
+ elf_property *p)
+{
+ unsigned int value;
+ bfd_boolean updated = FALSE;
+
+ switch (prop->type)
+ {
+ case GNU_PROPERTY_X86_ISA_1_USED:
+ case GNU_PROPERTY_X86_ISA_1_NEEDED:
+ value = prop->u.value;
+ prop->u.value = value | p->u.value;
+ updated = value != (unsigned int) prop->u.value;
+ 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 +6242,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"
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index e0e6c16..717e087 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -6896,8 +6896,68 @@ 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.value = bfd_h_get_32 (abfd, ptr);
+ prop->kind = property_value;
+ break;
+
+ default:
+ return property_ignored;
+ }
+
+ return property_value;
+}
+
+/* Merge x86-64 GNU property. Return TRUE if property is updated. */
+
+static bfd_boolean
+elf_x86_64_merge_gnu_properties (bfd *abfd ATTRIBUTE_UNUSED,
+ elf_property *prop,
+ elf_property *p)
+{
+ unsigned int value;
+ bfd_boolean updated = FALSE;
+
+ switch (prop->type)
+ {
+ case GNU_PROPERTY_X86_ISA_1_USED:
+ case GNU_PROPERTY_X86_ISA_1_NEEDED:
+ value = prop->u.value;
+ prop->u.value = value | p->u.value;
+ updated = value != (unsigned int) prop->u.value;
+ 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 +7048,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"
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
index d063fb7..8aa2de5 100644
--- a/bfd/elfxx-target.h
+++ b/bfd/elfxx-target.h
@@ -519,6 +519,12 @@
#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_static_tls_alignment
#define elf_backend_static_tls_alignment 1
#endif
@@ -838,6 +844,8 @@ 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_compact_eh_encoding,
elf_backend_cant_unwind_opcode,
elf_backend_static_tls_alignment,
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index d4837d0..1bd1265 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -1258,6 +1258,8 @@ gld${EMULATION_NAME}_after_open (void)
}
}
+ _bfd_elf_link_setup_gnu_properties (&link_info);
+
if (bfd_link_relocatable (&link_info))
{
if (link_info.execstack == ! link_info.noexecstack)
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index c489227..2f6fe76 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -736,6 +736,158 @@ 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" \
+ ] \
]
run_ld_link_exec_tests [list \
@@ -814,6 +966,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} \
+ "roperty-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} \
+ "roperty-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} \
+ "roperty-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} \
+ "roperty-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} \
+ "roperty-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
index 0000000..8fb892c
--- /dev/null
+++ b/ld/testsuite/ld-i386/pass.c
@@ -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
index 0000000..d8f08c0
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-1.r
@@ -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
index 0000000..5e3d156
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-2.r
@@ -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
index 0000000..0ed91f5
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-3.r
@@ -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
index 0000000..cb2bc15
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-4.r
@@ -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
index 0000000..5529650
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-5.r
@@ -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
index 0000000..97a479f
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-6.r
@@ -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
index 0000000..c7cc10b
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-6a.c
@@ -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
index 0000000..5336b0e
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-6b.c
@@ -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
index 0000000..13f729d
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-6c.S
@@ -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-no-copy.S b/ld/testsuite/ld-i386/property-no-copy.S
new file mode 100644
index 0000000..3116911
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-no-copy.S
@@ -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
index 0000000..5e9bcce
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-stack.S
@@ -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-x86-1.S b/ld/testsuite/ld-i386/property-x86-1.S
new file mode 100644
index 0000000..953ca87
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-x86-1.S
@@ -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
index 0000000..f11e1fe
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-x86-2.S
@@ -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
index 0000000..8fb892c
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pass.c
@@ -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
index 0000000..d8f08c0
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-1.r
@@ -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
index 0000000..5e3d156
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-2.r
@@ -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
index 0000000..0ed91f5
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-3.r
@@ -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
index 0000000..cb2bc15
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-4.r
@@ -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
index 0000000..5529650
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-5.r
@@ -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
index 0000000..97a479f
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-6.r
@@ -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
index 0000000..c7cc10b
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-6a.c
@@ -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
index 0000000..5336b0e
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-6b.c
@@ -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
index 0000000..fbe4713
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-6c.S
@@ -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 2
+ /* 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-no-copy.S b/ld/testsuite/ld-x86-64/property-no-copy.S
new file mode 100644
index 0000000..1b62f78
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-no-copy.S
@@ -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 2
+ /* 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
index 0000000..ccf7820
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-stack.S
@@ -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 2
+ /* 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
index 0000000..d2c1ff7
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-1.S
@@ -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 2
+ /* 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
index 0000000..a2f1b7a
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-2.S
@@ -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 2
+ /* 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:
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 8e4e422..070a2c2 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -828,6 +828,158 @@ 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" \
+ ] \
]
run_ld_link_exec_tests [list \
@@ -898,6 +1050,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} \
+ "roperty-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} \
+ "roperty-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} \
+ "roperty-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} \
+ "roperty-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} \
+ "roperty-5-static" "pass.out" \
+ ] \
]
# Run-time tests which require working ifunc attribute support.
--
2.9.3
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: RFC: ld: Support ELF GNU program properties
2017-03-13 18:21 RFC: ld: Support ELF GNU program properties H.J. Lu
@ 2017-03-23 15:25 ` H.J. Lu
2017-03-24 12:23 ` Nick Clifton
1 sibling, 0 replies; 6+ messages in thread
From: H.J. Lu @ 2017-03-23 15:25 UTC (permalink / raw)
To: Binutils
On Mon, Mar 13, 2017 at 11:20 AM, H.J. Lu <hongjiu.lu@intel.com> wrote:
> 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.
>
> Any comments?
>
> H.J.
> ---
> 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 and
> merge_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.
> (elfNN_bed): Add elf_backend_parse_gnu_properties and
> elf_backend_merge_gnu_properties.
>
> ld/
>
> * emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Call
> _bfd_elf_link_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-no-copy.S: Likewise.
> * testsuite/ld-i386/property-stack.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-no-copy.S: Likewise.
> * testsuite/ld-x86-64/property-stack.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.
> ---
> bfd/Makefile.am | 2 +
> bfd/Makefile.in | 3 +
> bfd/configure | 2 +-
> bfd/configure.ac | 2 +-
> bfd/elf-bfd.h | 44 ++++
> bfd/elf-properties.c | 370 ++++++++++++++++++++++++++++++
> bfd/elf.c | 3 +
> bfd/elf32-i386.c | 62 +++++
> bfd/elf64-x86-64.c | 66 +++++-
> bfd/elfxx-target.h | 8 +
> ld/emultempl/elf32.em | 2 +
> ld/testsuite/ld-i386/i386.exp | 257 +++++++++++++++++++++
> ld/testsuite/ld-i386/pass.c | 8 +
> ld/testsuite/ld-i386/property-1.r | 7 +
> ld/testsuite/ld-i386/property-2.r | 7 +
> ld/testsuite/ld-i386/property-3.r | 8 +
> ld/testsuite/ld-i386/property-4.r | 8 +
> ld/testsuite/ld-i386/property-5.r | 8 +
> ld/testsuite/ld-i386/property-6.r | 7 +
> ld/testsuite/ld-i386/property-6a.c | 7 +
> ld/testsuite/ld-i386/property-6b.c | 8 +
> ld/testsuite/ld-i386/property-6c.S | 18 ++
> ld/testsuite/ld-i386/property-no-copy.S | 15 ++
> ld/testsuite/ld-i386/property-stack.S | 18 ++
> ld/testsuite/ld-i386/property-x86-1.S | 32 +++
> ld/testsuite/ld-i386/property-x86-2.S | 25 ++
> ld/testsuite/ld-x86-64/pass.c | 8 +
> ld/testsuite/ld-x86-64/property-1.r | 7 +
> ld/testsuite/ld-x86-64/property-2.r | 7 +
> ld/testsuite/ld-x86-64/property-3.r | 8 +
> ld/testsuite/ld-x86-64/property-4.r | 8 +
> ld/testsuite/ld-x86-64/property-5.r | 8 +
> ld/testsuite/ld-x86-64/property-6.r | 7 +
> ld/testsuite/ld-x86-64/property-6a.c | 7 +
> ld/testsuite/ld-x86-64/property-6b.c | 8 +
> ld/testsuite/ld-x86-64/property-6c.S | 23 ++
> ld/testsuite/ld-x86-64/property-no-copy.S | 20 ++
> ld/testsuite/ld-x86-64/property-stack.S | 23 ++
> ld/testsuite/ld-x86-64/property-x86-1.S | 37 +++
> ld/testsuite/ld-x86-64/property-x86-2.S | 30 +++
> ld/testsuite/ld-x86-64/x86-64.exp | 257 +++++++++++++++++++++
> 41 files changed, 1452 insertions(+), 3 deletions(-)
> create mode 100644 bfd/elf-properties.c
> create mode 100644 ld/testsuite/ld-i386/pass.c
> create mode 100644 ld/testsuite/ld-i386/property-1.r
> create mode 100644 ld/testsuite/ld-i386/property-2.r
> create mode 100644 ld/testsuite/ld-i386/property-3.r
> create mode 100644 ld/testsuite/ld-i386/property-4.r
> create mode 100644 ld/testsuite/ld-i386/property-5.r
> create mode 100644 ld/testsuite/ld-i386/property-6.r
> create mode 100644 ld/testsuite/ld-i386/property-6a.c
> create mode 100644 ld/testsuite/ld-i386/property-6b.c
> create mode 100644 ld/testsuite/ld-i386/property-6c.S
> create mode 100644 ld/testsuite/ld-i386/property-no-copy.S
> create mode 100644 ld/testsuite/ld-i386/property-stack.S
> create mode 100644 ld/testsuite/ld-i386/property-x86-1.S
> create mode 100644 ld/testsuite/ld-i386/property-x86-2.S
> create mode 100644 ld/testsuite/ld-x86-64/pass.c
> create mode 100644 ld/testsuite/ld-x86-64/property-1.r
> create mode 100644 ld/testsuite/ld-x86-64/property-2.r
> create mode 100644 ld/testsuite/ld-x86-64/property-3.r
> create mode 100644 ld/testsuite/ld-x86-64/property-4.r
> create mode 100644 ld/testsuite/ld-x86-64/property-5.r
> create mode 100644 ld/testsuite/ld-x86-64/property-6.r
> create mode 100644 ld/testsuite/ld-x86-64/property-6a.c
> create mode 100644 ld/testsuite/ld-x86-64/property-6b.c
> create mode 100644 ld/testsuite/ld-x86-64/property-6c.S
> create mode 100644 ld/testsuite/ld-x86-64/property-no-copy.S
> create mode 100644 ld/testsuite/ld-x86-64/property-stack.S
> create mode 100644 ld/testsuite/ld-x86-64/property-x86-1.S
> create mode 100644 ld/testsuite/ld-x86-64/property-x86-2.S
>
> diff --git a/bfd/Makefile.am b/bfd/Makefile.am
> index 0b02263..87dd2db 100644
> --- a/bfd/Makefile.am
> +++ b/bfd/Makefile.am
> @@ -319,6 +319,7 @@ BFD32_BACKENDS = \
> elf-m10200.lo \
> elf-m10300.lo \
> elf-nacl.lo \
> + elf-properties.lo \
> elf-strtab.lo \
> elf-vxworks.lo \
> elf.lo \
> @@ -512,6 +513,7 @@ BFD32_BACKENDS_CFILES = \
> elf-m10200.c \
> elf-m10300.c \
> elf-nacl.c \
> + elf-properties.c \
> elf-strtab.c \
> elf-vxworks.c \
> elf.c \
> diff --git a/bfd/Makefile.in b/bfd/Makefile.in
> index 096c7ef..67d112d 100644
> --- a/bfd/Makefile.in
> +++ b/bfd/Makefile.in
> @@ -653,6 +653,7 @@ BFD32_BACKENDS = \
> elf-m10200.lo \
> elf-m10300.lo \
> elf-nacl.lo \
> + elf-properties.lo \
> elf-strtab.lo \
> elf-vxworks.lo \
> elf.lo \
> @@ -846,6 +847,7 @@ BFD32_BACKENDS_CFILES = \
> elf-m10200.c \
> elf-m10300.c \
> elf-nacl.c \
> + elf-properties.c \
> elf-strtab.c \
> elf-vxworks.c \
> elf.c \
> @@ -1464,6 +1466,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@
> diff --git a/bfd/configure b/bfd/configure
> index 83256d2..a40e621 100755
> --- a/bfd/configure
> +++ b/bfd/configure
> @@ -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"
> diff --git a/bfd/configure.ac b/bfd/configure.ac
> index ee0c537..e90ea9f 100644
> --- a/bfd/configure.ac
> +++ b/bfd/configure.ac
> @@ -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"
> diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
> index 9e3d6f5..fd500c5 100644
> --- a/bfd/elf-bfd.h
> +++ b/bfd/elf-bfd.h
> @@ -766,6 +766,31 @@ 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
> + {
> + property_unknown = 0,
> + property_ignored,
> + property_corrupt,
> + property_value
> + };
> +
> +typedef struct elf_property
> +{
> + unsigned int type;
> + unsigned int datasz;
> + union
> + {
> + bfd_vma value;
> + } u;
> + enum elf_property_kind 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 +1414,15 @@ struct elf_backend_data
> or give an error and return FALSE. */
> bfd_boolean (*obj_attrs_handle_unknown) (bfd *, int);
>
> + /* Parse GNU properties. */
> + enum elf_property_kind (*parse_gnu_properties) (bfd *, unsigned int,
> + bfd_byte *,
> + unsigned int);
> +
> + /* Merge GNU properties. */
> + bfd_boolean (*merge_gnu_properties) (bfd *, elf_property *,
> + elf_property *);
> +
> /* Encoding used for compact EH tables. */
> int (*compact_eh_encoding) (struct bfd_link_info *);
>
> @@ -1798,6 +1832,8 @@ struct elf_obj_tdata
> /* Symbol buffer. */
> void *symbuf;
>
> + elf_property_list *properties;
> +
> obj_attribute known_obj_attributes[2][NUM_KNOWN_OBJ_ATTRIBUTES];
> obj_attribute_list *other_obj_attributes[2];
>
> @@ -1882,6 +1918,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)
>
> extern void _bfd_elf_swap_verdef_in
> (bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *);
> @@ -2538,6 +2575,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
> index 0000000..e849a43
> --- /dev/null
> +++ b/bfd/elf-properties.c
> @@ -0,0 +1,370 @@
> +/* 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. */
> +
> +#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;
> +
> + /* 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.type)
> + return &p->property;
> + else if (type < p->property.type)
> + break;
> + lastp = &p->next;
> + }
> + p = (elf_property_list *) bfd_alloc (abfd, sizeof (*p));
> + memset (p, 0, sizeof (*p));
> + p->property.type = type;
> + p->property.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.value = bfd_h_get_64 (abfd, ptr);
> + else
> + prop->u.value = bfd_h_get_32 (abfd, ptr);
> + prop->kind = property_value;
> + 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->kind = property_value;
> + 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. Return TRUE if property is updated. */
> +
> +static bfd_boolean
> +elf_merge_gnu_properties (bfd *abfd, elf_property *prop, elf_property *p)
> +{
> + const struct elf_backend_data *bed = get_elf_backend_data (abfd);
> +
> + if (prop->type >= GNU_PROPERTY_LOPROC
> + && prop->type < GNU_PROPERTY_LOUSER
> + && bed->merge_gnu_properties != NULL)
> + return bed->merge_gnu_properties (abfd, prop, p);
> +
> + switch (prop->type)
> + {
> + case GNU_PROPERTY_STACK_SIZE:
> + if (p->u.value > prop->u.value)
> + {
> + prop->u.value = p->u.value;
> + return TRUE;
> + }
> + break;
> +
> + case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
> + break;
> +
> + default:
> + /* Never should happen. */
> + abort ();
> + }
> +
> + return FALSE;
> +}
> +
> +/* Merge GNU property list. Return TRUE if property list is updated. */
> +
> +static bfd_boolean
> +elf_merge_gnu_property_list (bfd *abfd, elf_property_list *list)
> +{
> + bfd_boolean updated = FALSE;
> +
> + for (; list != NULL; list = list->next)
> + {
> + elf_property *p;
> + p = _bfd_elf_get_property (abfd, list->property.type,
> + list->property.datasz);
> + if (p->kind == property_unknown)
> + {
> + /* Add a new property. */
> + *p = list->property;
> + updated = TRUE;
> + }
> + else
> + updated |= elf_merge_gnu_properties (abfd, p, &list->property);
> + }
> +
> + return updated;
> +}
> +
> +/* 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 updated = FALSE;
> + const struct elf_backend_data *bed;
> + unsigned int align_size;
> +
> + 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)
> + {
> + /* Check .note.gnu.property section in relocatable ELF input. */
> + list = elf_properties (abfd);
> + if (list)
> + {
> + if (first_pbfd == NULL)
> + {
> + /* Keep .note.gnu.property section in FIRST_PBFD. */
> + first_pbfd = abfd;
> + continue;
> + }
> +
> + /* Merge properties with FIRST_PBFD. */
> + updated |= elf_merge_gnu_property_list (first_pbfd, list);
> +
> + /* Discard .note.gnu.property section in the rest inputs. */
> + sec = bfd_get_section_by_name (abfd, ".note.gnu.property");
> + sec->output_section = bfd_abs_section_ptr;
> + }
> + }
> +
> + /* Do nothing if there is no .note.gnu.property section. */
> + if (first_pbfd == NULL)
> + return;
> +
> + bed = get_elf_backend_data (first_pbfd);
> + align_size = bed->s->elfclass == ELFCLASS64 ? 8 : 4;
> +
> + /* Update stack size in .note.gnu.property with -z stack-size=N if
> + N > 0. */
> + if (info->stacksize && first_pbfd != NULL && 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->kind == property_unknown)
> + {
> + /* Create GNU_PROPERTY_STACK_SIZE. */
> + p->u.value = stacksize;
> + p->kind = property_value;
> + updated = TRUE;
> + }
> + else if (stacksize > p->u.value)
> + {
> + p->u.value = stacksize;
> + updated = TRUE;
> + }
> + }
> +
> + if (updated)
> + {
> + unsigned int size;
> + unsigned int descsz;
> + bfd_byte *contents;
> + Elf_External_Note *e_note;
> +
> + sec = bfd_get_section_by_name (first_pbfd, ".note.gnu.property");
> +
> + /* 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.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.type,
> + contents + size);
> + bfd_h_put_32 (first_pbfd, list->property.datasz,
> + contents + size + 4);
> + size += 4 + 4;
> +
> + /* Write out property value. */
> + switch (list->property.kind)
> + {
> + case property_value:
> + switch (list->property.datasz)
> + {
> + default:
> + /* Never should happen. */
> + abort ();
> +
> + case 0:
> + break;
> +
> + case 4:
> + bfd_h_put_32 (first_pbfd, list->property.u.value,
> + contents + size);
> + break;
> +
> + case 8:
> + bfd_h_put_64 (first_pbfd, list->property.u.value,
> + contents + size);
> + break;
> + }
> + break;
> +
> + default:
> + /* Never should happen. */
> + abort ();
> + }
> + size += list->property.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;
> + }
> +}
> diff --git a/bfd/elf.c b/bfd/elf.c
> index 9418e51..d4d91b6 100644
> --- 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);
> }
> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
> index 2784ef7..7e82b0d 100644
> --- a/bfd/elf32-i386.c
> +++ b/bfd/elf32-i386.c
> @@ -6131,6 +6131,66 @@ 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.value = bfd_h_get_32 (abfd, ptr);
> + prop->kind = property_value;
> + break;
> +
> + default:
> + return property_ignored;
> + }
> +
> + return property_value;
> +}
> +
> +/* Merge i386 GNU property. Return TRUE if property is updated. */
> +
> +static bfd_boolean
> +elf_i386_merge_gnu_properties (bfd *abfd ATTRIBUTE_UNUSED,
> + elf_property *prop,
> + elf_property *p)
> +{
> + unsigned int value;
> + bfd_boolean updated = FALSE;
> +
> + switch (prop->type)
> + {
> + case GNU_PROPERTY_X86_ISA_1_USED:
> + case GNU_PROPERTY_X86_ISA_1_NEEDED:
> + value = prop->u.value;
> + prop->u.value = value | p->u.value;
> + updated = value != (unsigned int) prop->u.value;
> + 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 +6242,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"
>
> diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
> index e0e6c16..717e087 100644
> --- a/bfd/elf64-x86-64.c
> +++ b/bfd/elf64-x86-64.c
> @@ -6896,8 +6896,68 @@ 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.value = bfd_h_get_32 (abfd, ptr);
> + prop->kind = property_value;
> + break;
> +
> + default:
> + return property_ignored;
> + }
> +
> + return property_value;
> +}
> +
> +/* Merge x86-64 GNU property. Return TRUE if property is updated. */
> +
> +static bfd_boolean
> +elf_x86_64_merge_gnu_properties (bfd *abfd ATTRIBUTE_UNUSED,
> + elf_property *prop,
> + elf_property *p)
> +{
> + unsigned int value;
> + bfd_boolean updated = FALSE;
> +
> + switch (prop->type)
> + {
> + case GNU_PROPERTY_X86_ISA_1_USED:
> + case GNU_PROPERTY_X86_ISA_1_NEEDED:
> + value = prop->u.value;
> + prop->u.value = value | p->u.value;
> + updated = value != (unsigned int) prop->u.value;
> + 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 +7048,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"
>
> diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
> index d063fb7..8aa2de5 100644
> --- a/bfd/elfxx-target.h
> +++ b/bfd/elfxx-target.h
> @@ -519,6 +519,12 @@
> #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_static_tls_alignment
> #define elf_backend_static_tls_alignment 1
> #endif
> @@ -838,6 +844,8 @@ 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_compact_eh_encoding,
> elf_backend_cant_unwind_opcode,
> elf_backend_static_tls_alignment,
> diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
> index d4837d0..1bd1265 100644
> --- a/ld/emultempl/elf32.em
> +++ b/ld/emultempl/elf32.em
> @@ -1258,6 +1258,8 @@ gld${EMULATION_NAME}_after_open (void)
> }
> }
>
> + _bfd_elf_link_setup_gnu_properties (&link_info);
> +
> if (bfd_link_relocatable (&link_info))
> {
> if (link_info.execstack == ! link_info.noexecstack)
> diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
> index c489227..2f6fe76 100644
> --- a/ld/testsuite/ld-i386/i386.exp
> +++ b/ld/testsuite/ld-i386/i386.exp
> @@ -736,6 +736,158 @@ 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" \
> + ] \
> ]
>
> run_ld_link_exec_tests [list \
> @@ -814,6 +966,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} \
> + "roperty-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} \
> + "roperty-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} \
> + "roperty-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} \
> + "roperty-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} \
> + "roperty-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
> index 0000000..8fb892c
> --- /dev/null
> +++ b/ld/testsuite/ld-i386/pass.c
> @@ -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
> index 0000000..d8f08c0
> --- /dev/null
> +++ b/ld/testsuite/ld-i386/property-1.r
> @@ -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
> index 0000000..5e3d156
> --- /dev/null
> +++ b/ld/testsuite/ld-i386/property-2.r
> @@ -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
> index 0000000..0ed91f5
> --- /dev/null
> +++ b/ld/testsuite/ld-i386/property-3.r
> @@ -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
> index 0000000..cb2bc15
> --- /dev/null
> +++ b/ld/testsuite/ld-i386/property-4.r
> @@ -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
> index 0000000..5529650
> --- /dev/null
> +++ b/ld/testsuite/ld-i386/property-5.r
> @@ -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
> index 0000000..97a479f
> --- /dev/null
> +++ b/ld/testsuite/ld-i386/property-6.r
> @@ -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
> index 0000000..c7cc10b
> --- /dev/null
> +++ b/ld/testsuite/ld-i386/property-6a.c
> @@ -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
> index 0000000..5336b0e
> --- /dev/null
> +++ b/ld/testsuite/ld-i386/property-6b.c
> @@ -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
> index 0000000..13f729d
> --- /dev/null
> +++ b/ld/testsuite/ld-i386/property-6c.S
> @@ -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-no-copy.S b/ld/testsuite/ld-i386/property-no-copy.S
> new file mode 100644
> index 0000000..3116911
> --- /dev/null
> +++ b/ld/testsuite/ld-i386/property-no-copy.S
> @@ -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
> index 0000000..5e9bcce
> --- /dev/null
> +++ b/ld/testsuite/ld-i386/property-stack.S
> @@ -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-x86-1.S b/ld/testsuite/ld-i386/property-x86-1.S
> new file mode 100644
> index 0000000..953ca87
> --- /dev/null
> +++ b/ld/testsuite/ld-i386/property-x86-1.S
> @@ -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
> index 0000000..f11e1fe
> --- /dev/null
> +++ b/ld/testsuite/ld-i386/property-x86-2.S
> @@ -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
> index 0000000..8fb892c
> --- /dev/null
> +++ b/ld/testsuite/ld-x86-64/pass.c
> @@ -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
> index 0000000..d8f08c0
> --- /dev/null
> +++ b/ld/testsuite/ld-x86-64/property-1.r
> @@ -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
> index 0000000..5e3d156
> --- /dev/null
> +++ b/ld/testsuite/ld-x86-64/property-2.r
> @@ -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
> index 0000000..0ed91f5
> --- /dev/null
> +++ b/ld/testsuite/ld-x86-64/property-3.r
> @@ -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
> index 0000000..cb2bc15
> --- /dev/null
> +++ b/ld/testsuite/ld-x86-64/property-4.r
> @@ -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
> index 0000000..5529650
> --- /dev/null
> +++ b/ld/testsuite/ld-x86-64/property-5.r
> @@ -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
> index 0000000..97a479f
> --- /dev/null
> +++ b/ld/testsuite/ld-x86-64/property-6.r
> @@ -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
> index 0000000..c7cc10b
> --- /dev/null
> +++ b/ld/testsuite/ld-x86-64/property-6a.c
> @@ -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
> index 0000000..5336b0e
> --- /dev/null
> +++ b/ld/testsuite/ld-x86-64/property-6b.c
> @@ -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
> index 0000000..fbe4713
> --- /dev/null
> +++ b/ld/testsuite/ld-x86-64/property-6c.S
> @@ -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 2
> + /* 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-no-copy.S b/ld/testsuite/ld-x86-64/property-no-copy.S
> new file mode 100644
> index 0000000..1b62f78
> --- /dev/null
> +++ b/ld/testsuite/ld-x86-64/property-no-copy.S
> @@ -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 2
> + /* 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
> index 0000000..ccf7820
> --- /dev/null
> +++ b/ld/testsuite/ld-x86-64/property-stack.S
> @@ -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 2
> + /* 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
> index 0000000..d2c1ff7
> --- /dev/null
> +++ b/ld/testsuite/ld-x86-64/property-x86-1.S
> @@ -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 2
> + /* 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
> index 0000000..a2f1b7a
> --- /dev/null
> +++ b/ld/testsuite/ld-x86-64/property-x86-2.S
> @@ -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 2
> + /* 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:
> diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
> index 8e4e422..070a2c2 100644
> --- a/ld/testsuite/ld-x86-64/x86-64.exp
> +++ b/ld/testsuite/ld-x86-64/x86-64.exp
> @@ -828,6 +828,158 @@ 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" \
> + ] \
> ]
>
> run_ld_link_exec_tests [list \
> @@ -898,6 +1050,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} \
> + "roperty-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} \
> + "roperty-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} \
> + "roperty-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} \
> + "roperty-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} \
> + "roperty-5-static" "pass.out" \
> + ] \
> ]
>
> # Run-time tests which require working ifunc attribute support.
> --
> 2.9.3
>
Any comments?
--
H.J.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: RFC: ld: Support ELF GNU program properties
2017-03-13 18:21 RFC: ld: Support ELF GNU program properties H.J. Lu
2017-03-23 15:25 ` H.J. Lu
@ 2017-03-24 12:23 ` Nick Clifton
2017-03-29 20:38 ` H.J. Lu
1 sibling, 1 reply; 6+ messages in thread
From: Nick Clifton @ 2017-03-24 12:23 UTC (permalink / raw)
To: H.J. Lu, binutils
Hi H.J.
Sorry for not responding to this earlier.
> Any comments?
Are the contents of the .note.gnu.property section documented somewhere ?
(Other than an email that is).
I think that you ought to add a ld/NEWS entry for this feature.
Did you check this patch with any non-x86 targets ? (Just to make sure...)
> +typedef struct elf_property
> +{
> + unsigned int type;
> + unsigned int datasz;
> + union
> + {
> + bfd_vma value;
> + } u;
> + enum elf_property_kind kind;
> +} elf_property;
I found it very confusing that you have the same 'type' and 'datasz' fields
as an Elf_Internal_Note structure, but with different sizes and different
meanings. Would it be possible to use different field names in this structure ?
Also why do you have a union with only one element ? I am guessing
that it is for future extensions, but it would be nice to know.
> +/* 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;
> +
> + /* Keep the property list in order of type. */
> + lastp = &elf_properties (abfd);
Paranoia - I would suggest checking that ABFD is an elf format bfd before
attempting to access the elf_properties list. (I know that you have already
checked the bfd type in _bfd_elf_link_setup_gnu_properties, but this function
can be called from elsewhere and the caller might not have been so vigilant).
> + for (p = *lastp; p; p = p->next)
> + {
> + /* Reuse the existing entry. */
> + if (type == p->property.type)
> + return &p->property;
Should you check that datasz == p->property.datasz as well ?
> + p = (elf_property_list *) bfd_alloc (abfd, sizeof (*p));
Paranoia again - bfd_alloc() can return NULL...
> + 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;
Presumably no error message is printed here because it is assumed that this
has been done in bed->parse_gnu_properties. The (very) brief comment in elf-bfd.h
however makes no mention of this requirement.
> +static bfd_boolean
> +elf_merge_gnu_properties (bfd *abfd, elf_property *prop, elf_property *p)
Slightly confusing parameter names. I would have gone with prop_1 and prop_2 or
propA and propB. Something like that.
> + /* Discard .note.gnu.property section in the rest inputs. */
> + sec = bfd_get_section_by_name (abfd, ".note.gnu.property");
Why not use NOTE_GNU_PROPERTY_SECTION_NAME here ? It is already defined in include/elf/common.h
That's all that I can see.
Cheers
Nick
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: RFC: ld: Support ELF GNU program properties
2017-03-24 12:23 ` Nick Clifton
@ 2017-03-29 20:38 ` H.J. Lu
2017-03-31 13:16 ` Nick Clifton
0 siblings, 1 reply; 6+ messages in thread
From: H.J. Lu @ 2017-03-29 20:38 UTC (permalink / raw)
To: Nick Clifton; +Cc: Binutils
[-- Attachment #1: Type: text/plain, Size: 4303 bytes --]
On Fri, Mar 24, 2017 at 5:22 AM, Nick Clifton <nickc@redhat.com> wrote:
> Hi H.J.
>
> Sorry for not responding to this earlier.
>
>> Any comments?
>
> Are the contents of the .note.gnu.property section documented somewhere ?
> (Other than an email that is).
Put my draft at
https://github.com/hjl-tools/linux-abi/wiki/property-draft.pdf
But it doesn't cover GNU_PROPERTY_X86_ISA_1_USED nor
GNU_PROPERTY_X86_ISA_1_NEEDED.
> I think that you ought to add a ld/NEWS entry for this feature.
Done.
> Did you check this patch with any non-x86 targets ? (Just to make sure...)
I tried cross arm-linux on x86-64. There is no regression.
>
>> +typedef struct elf_property
>> +{
>> + unsigned int type;
>> + unsigned int datasz;
>> + union
>> + {
>> + bfd_vma value;
>> + } u;
>> + enum elf_property_kind kind;
>> +} elf_property;
>
> I found it very confusing that you have the same 'type' and 'datasz' fields
> as an Elf_Internal_Note structure, but with different sizes and different
> meanings. Would it be possible to use different field names in this structure ?
Done.
> Also why do you have a union with only one element ? I am guessing
> that it is for future extensions, but it would be nice to know.
>
Done.
>> +/* 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;
>> +
>> + /* Keep the property list in order of type. */
>> + lastp = &elf_properties (abfd);
>
> Paranoia - I would suggest checking that ABFD is an elf format bfd before
> attempting to access the elf_properties list. (I know that you have already
> checked the bfd type in _bfd_elf_link_setup_gnu_properties, but this function
> can be called from elsewhere and the caller might not have been so vigilant).
I added a check:
if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
{
/* Never should happen. */
abort ();
}
>
>> + for (p = *lastp; p; p = p->next)
>> + {
>> + /* Reuse the existing entry. */
>> + if (type == p->property.type)
>> + return &p->property;
>
> Should you check that datasz == p->property.datasz as well ?
I added
if (datasz > p->property.pr_datasz)
{
/* This can happen when mixing 32-bit and 64-bit objects. */
p->property.pr_datasz = datasz;
}
>
>> + p = (elf_property_list *) bfd_alloc (abfd, sizeof (*p));
>
> Paranoia again - bfd_alloc() can return NULL...
I added
if (p == NULL)
{
_bfd_error_handler (_("%B: out of memory in _bfd_elf_get_property"),
abfd);
_exit (EXIT_FAILURE);
}
since we can't recover from this.
>
>> + 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;
>
> Presumably no error message is printed here because it is assumed that this
> has been done in bed->parse_gnu_properties. The (very) brief comment in elf-bfd.h
> however makes no mention of this requirement.
I added
/* 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);
>
>> +static bfd_boolean
>> +elf_merge_gnu_properties (bfd *abfd, elf_property *prop, elf_property *p)
>
> Slightly confusing parameter names. I would have gone with prop_1 and prop_2 or
> propA and propB. Something like that.
Done.
>
>> + /* Discard .note.gnu.property section in the rest inputs. */
>> + sec = bfd_get_section_by_name (abfd, ".note.gnu.property");
>
> Why not use NOTE_GNU_PROPERTY_SECTION_NAME here ? It is already defined in include/elf/common.h
Done.
>
> That's all that I can see.
>
Here is the updated patch.
Thanks.
--
H.J.
[-- Attachment #2: 0001-ld-Support-ELF-GNU-program-properties.patch --]
[-- Type: text/x-patch, Size: 61822 bytes --]
From eac06d689eb89f68ce6d20e5db4ed0accc859f6c Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Fri, 15 Apr 2016 16:55:08 -0700
Subject: [PATCH] ld: Support ELF GNU program properties
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-no-copy.S: Likewise.
* testsuite/ld-i386/property-stack.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-no-copy.S: Likewise.
* testsuite/ld-x86-64/property-stack.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.
---
bfd/Makefile.am | 2 +
bfd/Makefile.in | 3 +
bfd/configure | 2 +-
bfd/configure.ac | 2 +-
bfd/elf-bfd.h | 56 ++++
bfd/elf-properties.c | 486 ++++++++++++++++++++++++++++++
bfd/elf.c | 3 +
bfd/elf32-i386.c | 74 +++++
bfd/elf64-x86-64.c | 78 ++++-
bfd/elfxx-target.h | 12 +
ld/NEWS | 2 +
ld/emultempl/elf32.em | 2 +
ld/testsuite/ld-i386/i386.exp | 257 ++++++++++++++++
ld/testsuite/ld-i386/pass.c | 8 +
ld/testsuite/ld-i386/property-1.r | 7 +
ld/testsuite/ld-i386/property-2.r | 7 +
ld/testsuite/ld-i386/property-3.r | 8 +
ld/testsuite/ld-i386/property-4.r | 8 +
ld/testsuite/ld-i386/property-5.r | 8 +
ld/testsuite/ld-i386/property-6.r | 7 +
ld/testsuite/ld-i386/property-6a.c | 7 +
ld/testsuite/ld-i386/property-6b.c | 8 +
ld/testsuite/ld-i386/property-6c.S | 18 ++
ld/testsuite/ld-i386/property-no-copy.S | 15 +
ld/testsuite/ld-i386/property-stack.S | 18 ++
ld/testsuite/ld-i386/property-x86-1.S | 32 ++
ld/testsuite/ld-i386/property-x86-2.S | 25 ++
ld/testsuite/ld-x86-64/pass.c | 8 +
ld/testsuite/ld-x86-64/property-1.r | 7 +
ld/testsuite/ld-x86-64/property-2.r | 7 +
ld/testsuite/ld-x86-64/property-3.r | 8 +
ld/testsuite/ld-x86-64/property-4.r | 8 +
ld/testsuite/ld-x86-64/property-5.r | 8 +
ld/testsuite/ld-x86-64/property-6.r | 7 +
ld/testsuite/ld-x86-64/property-6a.c | 7 +
ld/testsuite/ld-x86-64/property-6b.c | 8 +
ld/testsuite/ld-x86-64/property-6c.S | 23 ++
ld/testsuite/ld-x86-64/property-no-copy.S | 20 ++
ld/testsuite/ld-x86-64/property-stack.S | 23 ++
ld/testsuite/ld-x86-64/property-x86-1.S | 37 +++
ld/testsuite/ld-x86-64/property-x86-2.S | 30 ++
ld/testsuite/ld-x86-64/x86-64.exp | 257 ++++++++++++++++
42 files changed, 1610 insertions(+), 3 deletions(-)
create mode 100644 bfd/elf-properties.c
create mode 100644 ld/testsuite/ld-i386/pass.c
create mode 100644 ld/testsuite/ld-i386/property-1.r
create mode 100644 ld/testsuite/ld-i386/property-2.r
create mode 100644 ld/testsuite/ld-i386/property-3.r
create mode 100644 ld/testsuite/ld-i386/property-4.r
create mode 100644 ld/testsuite/ld-i386/property-5.r
create mode 100644 ld/testsuite/ld-i386/property-6.r
create mode 100644 ld/testsuite/ld-i386/property-6a.c
create mode 100644 ld/testsuite/ld-i386/property-6b.c
create mode 100644 ld/testsuite/ld-i386/property-6c.S
create mode 100644 ld/testsuite/ld-i386/property-no-copy.S
create mode 100644 ld/testsuite/ld-i386/property-stack.S
create mode 100644 ld/testsuite/ld-i386/property-x86-1.S
create mode 100644 ld/testsuite/ld-i386/property-x86-2.S
create mode 100644 ld/testsuite/ld-x86-64/pass.c
create mode 100644 ld/testsuite/ld-x86-64/property-1.r
create mode 100644 ld/testsuite/ld-x86-64/property-2.r
create mode 100644 ld/testsuite/ld-x86-64/property-3.r
create mode 100644 ld/testsuite/ld-x86-64/property-4.r
create mode 100644 ld/testsuite/ld-x86-64/property-5.r
create mode 100644 ld/testsuite/ld-x86-64/property-6.r
create mode 100644 ld/testsuite/ld-x86-64/property-6a.c
create mode 100644 ld/testsuite/ld-x86-64/property-6b.c
create mode 100644 ld/testsuite/ld-x86-64/property-6c.S
create mode 100644 ld/testsuite/ld-x86-64/property-no-copy.S
create mode 100644 ld/testsuite/ld-x86-64/property-stack.S
create mode 100644 ld/testsuite/ld-x86-64/property-x86-1.S
create mode 100644 ld/testsuite/ld-x86-64/property-x86-2.S
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 49ab092..97b608c 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -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 \
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index fed5117..e48abaf 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -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@
diff --git a/bfd/configure b/bfd/configure
index 7cae4ae..24e3e2f 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -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"
diff --git a/bfd/configure.ac b/bfd/configure.ac
index feb1231..e568847 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -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"
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 9e3d6f5..fc3187b 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -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,8 @@ struct elf_obj_tdata
/* Symbol buffer. */
void *symbuf;
+ elf_property_list *properties;
+
obj_attribute known_obj_attributes[2][NUM_KNOWN_OBJ_ATTRIBUTES];
obj_attribute_list *other_obj_attributes[2];
@@ -1882,6 +1930,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 +2587,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
index 0000000..612d37b
--- /dev/null
+++ b/bfd/elf-properties.c
@@ -0,0 +1,486 @@
+/* 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. */
+
+#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 LIST. Return NULL if not found. */
+
+static elf_property *
+elf_find_property (elf_property_list *list, unsigned int type)
+{
+ for (; list; list = list->next)
+ {
+ if (type == list->property.pr_type)
+ return &list->property;
+ else if (type < list->property.pr_type)
+ break;
+ }
+
+ return NULL;
+}
+
+/* Merge GNU property list LIST with ABFD. Return TRUE if property list
+ in ABFD is updated. */
+
+static bfd_boolean
+elf_merge_gnu_property_list (bfd *abfd, elf_property_list *list)
+{
+ bfd_boolean updated = FALSE;
+ elf_property_list *p, **lastp;
+ elf_property *pr;
+
+ /* Merge each GNU property in ABFD with the one on LIST. */
+ lastp = &elf_properties (abfd);
+ for (p = *lastp; p; p = p->next)
+ {
+ pr = elf_find_property (list, p->property.pr_type);
+ /* Pass NULL to elf_merge_gnu_properties for the property which
+ isn't on LIST. */
+ updated |= 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 each GNU property on LIST with the one in ABFD. */
+ p = elf_properties (abfd);
+ for (; list != NULL; list = list->next)
+ {
+ pr = elf_find_property (p, list->property.pr_type);
+
+ /* Skip those also in ABFD since they have been merged. */
+ if (pr != NULL)
+ continue;
+
+ /* Merge the property which isn't in ABFD. */
+ if (elf_merge_gnu_properties (abfd, NULL, &list->property))
+ {
+ pr = _bfd_elf_get_property (abfd, list->property.pr_type,
+ list->property.pr_datasz);
+ /* It must be a new property. */
+ if (pr->pr_kind != property_unknown)
+ abort ();
+ /* Add a new property. */
+ *pr = list->property;
+ updated = TRUE;
+ }
+ }
+
+ return updated;
+}
+
+/* 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 updated = FALSE;
+ bfd_boolean has_properties = FALSE;
+ const struct elf_backend_data *bed
+ = get_elf_backend_data (info->output_bfd);
+ unsigned int align_size;
+ 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 which have 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 *p;
+
+ /* Merge .note.gnu.property section in relocatable ELF input. */
+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+ list = elf_properties (abfd);
+ else
+ list = NULL;
+
+ /* Ignore GNU properties from ELF objects which have different
+ machine code. */
+ if (list != NULL
+ && (elf_machine_code
+ == get_elf_backend_data (abfd)->elf_machine_code))
+ p = list;
+ else
+ p = NULL;
+
+ /* Merge properties with FIRST_PBFD. */
+ updated |= elf_merge_gnu_property_list (first_pbfd, p);
+
+ if (list)
+ {
+ /* 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;
+ }
+ }
+
+ align_size = bed->s->elfclass == ELFCLASS64 ? 8 : 4;
+
+ /* Update stack size in .note.gnu.property with -z stack-size=N if
+ N > 0. */
+ if (info->stacksize && first_pbfd != NULL && 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;
+ updated = TRUE;
+ }
+ else if (stacksize > p->u.number)
+ {
+ p->u.number = stacksize;
+ updated = TRUE;
+ }
+ }
+
+ if (updated)
+ {
+ unsigned int size;
+ unsigned int descsz;
+ bfd_byte *contents;
+ Elf_External_Note *e_note;
+
+ sec = bfd_get_section_by_name (first_pbfd,
+ NOTE_GNU_PROPERTY_SECTION_NAME);
+
+ 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;
+ }
+}
diff --git a/bfd/elf.c b/bfd/elf.c
index 9418e51..d4d91b6 100644
--- 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);
}
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 2784ef7..b1afb49 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -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"
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index e0e6c16..6d92c79 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -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"
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
index d063fb7..6cc9f3f 100644
--- a/bfd/elfxx-target.h
+++ b/bfd/elfxx-target.h
@@ -519,6 +519,15 @@
#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,
diff --git a/ld/NEWS b/ld/NEWS
index 972e7a8..039a90e 100644
--- 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
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index d4837d0..007e48d 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -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)
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index c489227..2f6fe76 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -736,6 +736,158 @@ 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" \
+ ] \
]
run_ld_link_exec_tests [list \
@@ -814,6 +966,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} \
+ "roperty-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} \
+ "roperty-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} \
+ "roperty-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} \
+ "roperty-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} \
+ "roperty-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
index 0000000..8fb892c
--- /dev/null
+++ b/ld/testsuite/ld-i386/pass.c
@@ -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
index 0000000..d8f08c0
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-1.r
@@ -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
index 0000000..5e3d156
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-2.r
@@ -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
index 0000000..0ed91f5
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-3.r
@@ -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
index 0000000..cb2bc15
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-4.r
@@ -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
index 0000000..5529650
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-5.r
@@ -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
index 0000000..97a479f
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-6.r
@@ -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
index 0000000..c7cc10b
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-6a.c
@@ -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
index 0000000..5336b0e
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-6b.c
@@ -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
index 0000000..13f729d
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-6c.S
@@ -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-no-copy.S b/ld/testsuite/ld-i386/property-no-copy.S
new file mode 100644
index 0000000..3116911
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-no-copy.S
@@ -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
index 0000000..5e9bcce
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-stack.S
@@ -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-x86-1.S b/ld/testsuite/ld-i386/property-x86-1.S
new file mode 100644
index 0000000..953ca87
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-x86-1.S
@@ -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
index 0000000..f11e1fe
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-x86-2.S
@@ -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
index 0000000..8fb892c
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pass.c
@@ -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
index 0000000..d8f08c0
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-1.r
@@ -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
index 0000000..5e3d156
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-2.r
@@ -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
index 0000000..0ed91f5
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-3.r
@@ -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
index 0000000..cb2bc15
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-4.r
@@ -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
index 0000000..5529650
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-5.r
@@ -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
index 0000000..97a479f
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-6.r
@@ -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
index 0000000..c7cc10b
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-6a.c
@@ -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
index 0000000..5336b0e
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-6b.c
@@ -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
index 0000000..41246d3
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-6c.S
@@ -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-no-copy.S b/ld/testsuite/ld-x86-64/property-no-copy.S
new file mode 100644
index 0000000..88cc252
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-no-copy.S
@@ -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
index 0000000..7f45654
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-stack.S
@@ -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-x86-1.S b/ld/testsuite/ld-x86-64/property-x86-1.S
new file mode 100644
index 0000000..33f2ccd
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-1.S
@@ -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
index 0000000..132e521
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-2.S
@@ -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:
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 8e4e422..070a2c2 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -828,6 +828,158 @@ 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" \
+ ] \
]
run_ld_link_exec_tests [list \
@@ -898,6 +1050,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} \
+ "roperty-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} \
+ "roperty-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} \
+ "roperty-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} \
+ "roperty-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} \
+ "roperty-5-static" "pass.out" \
+ ] \
]
# Run-time tests which require working ifunc attribute support.
--
2.9.3
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: RFC: ld: Support ELF GNU program properties
2017-03-29 20:38 ` H.J. Lu
@ 2017-03-31 13:16 ` Nick Clifton
2017-03-31 15:05 ` H.J. Lu
0 siblings, 1 reply; 6+ messages in thread
From: Nick Clifton @ 2017-03-31 13:16 UTC (permalink / raw)
To: H.J. Lu; +Cc: Binutils
Hi H.J.
> Put my draft at
> https://github.com/hjl-tools/linux-abi/wiki/property-draft.pdf
Just one request - could a link to this document be included in the
sources please, so that someone reviewing the code will know where
to find the spec.
> Here is the updated patch.
The patch is approved - please apply.
Cheers
Nick
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: RFC: ld: Support ELF GNU program properties
2017-03-31 13:16 ` Nick Clifton
@ 2017-03-31 15:05 ` H.J. Lu
0 siblings, 0 replies; 6+ messages in thread
From: H.J. Lu @ 2017-03-31 15:05 UTC (permalink / raw)
To: Nick Clifton; +Cc: Binutils
[-- Attachment #1: Type: text/plain, Size: 686 bytes --]
On Fri, Mar 31, 2017 at 6:16 AM, Nick Clifton <nickc@redhat.com> wrote:
> Hi H.J.
>
>> Put my draft at
>> https://github.com/hjl-tools/linux-abi/wiki/property-draft.pdf
>
> Just one request - could a link to this document be included in the
> sources please, so that someone reviewing the code will know where
> to find the spec.
Done.
>> Here is the updated patch.
>
> The patch is approved - please apply.
>
Here is the updated patch:
1. Speed up the property merge by removing the merged property in
the first pass.
2. Support unsorted properties n .o files.
3. Support more than one property array in .o files.
4. Fix typos in testcases.
I will check it in shortly.
--
H.J.
[-- Attachment #2: 0001-ld-Support-ELF-GNU-program-properties.patch --]
[-- Type: text/x-patch, Size: 68420 bytes --]
From 8d6626ef5f7569b13785e70ede19c096d335a1a6 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Fri, 15 Apr 2016 16:55:08 -0700
Subject: [PATCH] ld: Support ELF GNU program properties
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.
---
bfd/Makefile.am | 2 +
bfd/Makefile.in | 3 +
bfd/configure | 2 +-
bfd/configure.ac | 2 +-
bfd/elf-bfd.h | 58 ++++
bfd/elf-properties.c | 483 +++++++++++++++++++++++++++
bfd/elf.c | 3 +
bfd/elf32-i386.c | 74 ++++
bfd/elf64-x86-64.c | 78 ++++-
bfd/elfxx-target.h | 12 +
ld/NEWS | 2 +
ld/emultempl/elf32.em | 2 +
ld/testsuite/ld-i386/i386.exp | 273 +++++++++++++++
ld/testsuite/ld-i386/pass.c | 8 +
ld/testsuite/ld-i386/property-1.r | 7 +
ld/testsuite/ld-i386/property-2.r | 7 +
ld/testsuite/ld-i386/property-3.r | 8 +
ld/testsuite/ld-i386/property-4.r | 8 +
ld/testsuite/ld-i386/property-5.r | 8 +
ld/testsuite/ld-i386/property-6.r | 7 +
ld/testsuite/ld-i386/property-6a.c | 7 +
ld/testsuite/ld-i386/property-6b.c | 8 +
ld/testsuite/ld-i386/property-6c.S | 18 +
ld/testsuite/ld-i386/property-7.r | 6 +
ld/testsuite/ld-i386/property-no-copy.S | 15 +
ld/testsuite/ld-i386/property-stack.S | 18 +
ld/testsuite/ld-i386/property-unsorted-1.S | 34 ++
ld/testsuite/ld-i386/property-unsorted-2.S | 22 ++
ld/testsuite/ld-i386/property-x86-1.S | 32 ++
ld/testsuite/ld-i386/property-x86-2.S | 25 ++
ld/testsuite/ld-x86-64/pass.c | 8 +
ld/testsuite/ld-x86-64/property-1.r | 7 +
ld/testsuite/ld-x86-64/property-2.r | 7 +
ld/testsuite/ld-x86-64/property-3.r | 8 +
ld/testsuite/ld-x86-64/property-4.r | 8 +
ld/testsuite/ld-x86-64/property-5.r | 8 +
ld/testsuite/ld-x86-64/property-6.r | 7 +
ld/testsuite/ld-x86-64/property-6a.c | 7 +
ld/testsuite/ld-x86-64/property-6b.c | 8 +
ld/testsuite/ld-x86-64/property-6c.S | 23 ++
ld/testsuite/ld-x86-64/property-7.r | 6 +
ld/testsuite/ld-x86-64/property-no-copy.S | 20 ++
ld/testsuite/ld-x86-64/property-stack.S | 23 ++
ld/testsuite/ld-x86-64/property-unsorted-1.S | 39 +++
ld/testsuite/ld-x86-64/property-unsorted-2.S | 27 ++
ld/testsuite/ld-x86-64/property-x86-1.S | 37 ++
ld/testsuite/ld-x86-64/property-x86-2.S | 30 ++
ld/testsuite/ld-x86-64/x86-64.exp | 273 +++++++++++++++
48 files changed, 1775 insertions(+), 3 deletions(-)
create mode 100644 bfd/elf-properties.c
create mode 100644 ld/testsuite/ld-i386/pass.c
create mode 100644 ld/testsuite/ld-i386/property-1.r
create mode 100644 ld/testsuite/ld-i386/property-2.r
create mode 100644 ld/testsuite/ld-i386/property-3.r
create mode 100644 ld/testsuite/ld-i386/property-4.r
create mode 100644 ld/testsuite/ld-i386/property-5.r
create mode 100644 ld/testsuite/ld-i386/property-6.r
create mode 100644 ld/testsuite/ld-i386/property-6a.c
create mode 100644 ld/testsuite/ld-i386/property-6b.c
create mode 100644 ld/testsuite/ld-i386/property-6c.S
create mode 100644 ld/testsuite/ld-i386/property-7.r
create mode 100644 ld/testsuite/ld-i386/property-no-copy.S
create mode 100644 ld/testsuite/ld-i386/property-stack.S
create mode 100644 ld/testsuite/ld-i386/property-unsorted-1.S
create mode 100644 ld/testsuite/ld-i386/property-unsorted-2.S
create mode 100644 ld/testsuite/ld-i386/property-x86-1.S
create mode 100644 ld/testsuite/ld-i386/property-x86-2.S
create mode 100644 ld/testsuite/ld-x86-64/pass.c
create mode 100644 ld/testsuite/ld-x86-64/property-1.r
create mode 100644 ld/testsuite/ld-x86-64/property-2.r
create mode 100644 ld/testsuite/ld-x86-64/property-3.r
create mode 100644 ld/testsuite/ld-x86-64/property-4.r
create mode 100644 ld/testsuite/ld-x86-64/property-5.r
create mode 100644 ld/testsuite/ld-x86-64/property-6.r
create mode 100644 ld/testsuite/ld-x86-64/property-6a.c
create mode 100644 ld/testsuite/ld-x86-64/property-6b.c
create mode 100644 ld/testsuite/ld-x86-64/property-6c.S
create mode 100644 ld/testsuite/ld-x86-64/property-7.r
create mode 100644 ld/testsuite/ld-x86-64/property-no-copy.S
create mode 100644 ld/testsuite/ld-x86-64/property-stack.S
create mode 100644 ld/testsuite/ld-x86-64/property-unsorted-1.S
create mode 100644 ld/testsuite/ld-x86-64/property-unsorted-2.S
create mode 100644 ld/testsuite/ld-x86-64/property-x86-1.S
create mode 100644 ld/testsuite/ld-x86-64/property-x86-2.S
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 49ab092..97b608c 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -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 \
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index fed5117..e48abaf 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -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@
diff --git a/bfd/configure b/bfd/configure
index 7cae4ae..24e3e2f 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -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"
diff --git a/bfd/configure.ac b/bfd/configure.ac
index feb1231..e568847 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -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"
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 9e3d6f5..af377ee 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -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
index 0000000..a0456f8
--- /dev/null
+++ b/bfd/elf-properties.c
@@ -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;
+ }
+}
diff --git a/bfd/elf.c b/bfd/elf.c
index 9418e51..d4d91b6 100644
--- 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);
}
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 2784ef7..b1afb49 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -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"
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index e0e6c16..6d92c79 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -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"
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
index d063fb7..6cc9f3f 100644
--- a/bfd/elfxx-target.h
+++ b/bfd/elfxx-target.h
@@ -519,6 +519,15 @@
#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,
diff --git a/ld/NEWS b/ld/NEWS
index 972e7a8..039a90e 100644
--- 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
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index d4837d0..007e48d 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -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)
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index c489227..844b36f 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -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
index 0000000..8fb892c
--- /dev/null
+++ b/ld/testsuite/ld-i386/pass.c
@@ -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
index 0000000..d8f08c0
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-1.r
@@ -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
index 0000000..5e3d156
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-2.r
@@ -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
index 0000000..0ed91f5
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-3.r
@@ -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
index 0000000..cb2bc15
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-4.r
@@ -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
index 0000000..5529650
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-5.r
@@ -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
index 0000000..97a479f
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-6.r
@@ -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
index 0000000..c7cc10b
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-6a.c
@@ -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
index 0000000..5336b0e
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-6b.c
@@ -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
index 0000000..13f729d
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-6c.S
@@ -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
index 0000000..ad6af84
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-7.r
@@ -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
index 0000000..3116911
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-no-copy.S
@@ -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
index 0000000..5e9bcce
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-stack.S
@@ -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
index 0000000..1cbb272
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-unsorted-1.S
@@ -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
index 0000000..0289399
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-unsorted-2.S
@@ -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
index 0000000..953ca87
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-x86-1.S
@@ -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
index 0000000..f11e1fe
--- /dev/null
+++ b/ld/testsuite/ld-i386/property-x86-2.S
@@ -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
index 0000000..8fb892c
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pass.c
@@ -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
index 0000000..d8f08c0
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-1.r
@@ -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
index 0000000..5e3d156
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-2.r
@@ -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
index 0000000..0ed91f5
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-3.r
@@ -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
index 0000000..cb2bc15
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-4.r
@@ -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
index 0000000..5529650
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-5.r
@@ -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
index 0000000..97a479f
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-6.r
@@ -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
index 0000000..c7cc10b
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-6a.c
@@ -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
index 0000000..5336b0e
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-6b.c
@@ -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
index 0000000..41246d3
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-6c.S
@@ -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
index 0000000..ad6af84
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-7.r
@@ -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
index 0000000..88cc252
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-no-copy.S
@@ -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
index 0000000..7f45654
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-stack.S
@@ -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
index 0000000..de96e7a
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-unsorted-1.S
@@ -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
index 0000000..65d7fad
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-unsorted-2.S
@@ -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
index 0000000..33f2ccd
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-1.S
@@ -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
index 0000000..132e521
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/property-x86-2.S
@@ -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:
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 8e4e422..e7a7f80 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -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.
--
2.9.3
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2017-03-31 15:05 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-13 18:21 RFC: ld: Support ELF GNU program properties H.J. Lu
2017-03-23 15:25 ` H.J. Lu
2017-03-24 12:23 ` Nick Clifton
2017-03-29 20:38 ` H.J. Lu
2017-03-31 13:16 ` Nick Clifton
2017-03-31 15:05 ` H.J. Lu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).