forked from pool/binutils
290 lines
8.1 KiB
Diff
290 lines
8.1 KiB
Diff
|
From d77ae458893b48e4e4ad5aa74a94023dff4ec4e1 Mon Sep 17 00:00:00 2001
|
||
|
From: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
|
||
|
Date: Mon, 27 Apr 2015 10:32:23 +0200
|
||
|
Subject: [PATCH 5/5] S/390: z13 use GNU attribute to indicate vector ABI
|
||
|
|
||
|
bfd/
|
||
|
* elf-s390-common.c (elf_s390_merge_obj_attributes): New function.
|
||
|
* elf32-s390.c (elf32_s390_merge_private_bfd_data): Call
|
||
|
elf_s390_merge_obj_attributes.
|
||
|
* elf64-s390.c (elf64_s390_merge_private_bfd_data): New function.
|
||
|
|
||
|
binutils/
|
||
|
* readelf.c (display_s390_gnu_attribute): New function.
|
||
|
(process_s390_specific): New function.
|
||
|
(process_arch_specific): Call process_s390_specific.
|
||
|
|
||
|
gas/
|
||
|
* doc/as.texinfo: Document Tag_GNU_S390_ABI_Vector.
|
||
|
|
||
|
include/elf/
|
||
|
* s390.h: Define Tag_GNU_S390_ABI_Vector.
|
||
|
|
||
|
# Conflicts:
|
||
|
# bfd/ChangeLog
|
||
|
# binutils/ChangeLog
|
||
|
# gas/testsuite/ChangeLog
|
||
|
# include/elf/ChangeLog
|
||
|
|
||
|
# Conflicts:
|
||
|
# bfd/elf-s390-common.c
|
||
|
---
|
||
|
bfd/elf-s390-common.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
bfd/elf32-s390.c | 9 ++++++++
|
||
|
bfd/elf64-s390.c | 18 +++++++++++++++-
|
||
|
binutils/readelf.c | 46 ++++++++++++++++++++++++++++++++++++++++
|
||
|
gas/doc/as.texinfo | 16 ++++++++++++++
|
||
|
include/elf/s390.h | 15 +++++++++++--
|
||
|
6 files changed, 159 insertions(+), 3 deletions(-)
|
||
|
|
||
|
diff --git a/bfd/elf-s390-common.c b/bfd/elf-s390-common.c
|
||
|
index c74883c..de87ff8 100644
|
||
|
--- a/bfd/elf-s390-common.c
|
||
|
+++ b/bfd/elf-s390-common.c
|
||
|
@@ -242,3 +242,61 @@ elf_s390_add_symbol_hook (bfd *abfd,
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
+
|
||
|
+/* Merge object attributes from IBFD into OBFD. Raise an error if
|
||
|
+ there are conflicting attributes. */
|
||
|
+static bfd_boolean
|
||
|
+elf_s390_merge_obj_attributes (bfd *ibfd, bfd *obfd)
|
||
|
+{
|
||
|
+ obj_attribute *in_attr, *in_attrs;
|
||
|
+ obj_attribute *out_attr, *out_attrs;
|
||
|
+
|
||
|
+ if (!elf_known_obj_attributes_proc (obfd)[0].i)
|
||
|
+ {
|
||
|
+ /* This is the first object. Copy the attributes. */
|
||
|
+ _bfd_elf_copy_obj_attributes (ibfd, obfd);
|
||
|
+
|
||
|
+ /* Use the Tag_null value to indicate the attributes have been
|
||
|
+ initialized. */
|
||
|
+ elf_known_obj_attributes_proc (obfd)[0].i = 1;
|
||
|
+
|
||
|
+ return TRUE;
|
||
|
+ }
|
||
|
+
|
||
|
+ in_attrs = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
|
||
|
+ out_attrs = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU];
|
||
|
+
|
||
|
+ /* Check for conflicting Tag_GNU_S390_ABI_Vector attributes and
|
||
|
+ merge non-conflicting ones. */
|
||
|
+ in_attr = &in_attrs[Tag_GNU_S390_ABI_Vector];
|
||
|
+ out_attr = &out_attrs[Tag_GNU_S390_ABI_Vector];
|
||
|
+
|
||
|
+ if (in_attr->i > 2)
|
||
|
+ _bfd_error_handler
|
||
|
+ (_("Warning: %B uses unknown vector ABI %d"), ibfd,
|
||
|
+ in_attr->i);
|
||
|
+ else if (out_attr->i > 2)
|
||
|
+ _bfd_error_handler
|
||
|
+ (_("Warning: %B uses unknown vector ABI %d"), obfd,
|
||
|
+ out_attr->i);
|
||
|
+ else if (in_attr->i != out_attr->i)
|
||
|
+ {
|
||
|
+ out_attr->type = ATTR_TYPE_FLAG_INT_VAL;
|
||
|
+
|
||
|
+ if (in_attr->i && out_attr->i)
|
||
|
+ {
|
||
|
+ const char abi_str[3][9] = { "none", "software", "hardware" };
|
||
|
+
|
||
|
+ _bfd_error_handler
|
||
|
+ (_("Warning: %B uses vector %s ABI, %B uses %s ABI"),
|
||
|
+ ibfd, obfd, abi_str[in_attr->i], abi_str[out_attr->i]);
|
||
|
+ }
|
||
|
+ if (in_attr->i > out_attr->i)
|
||
|
+ out_attr->i = in_attr->i;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Merge Tag_compatibility attributes and any common GNU ones. */
|
||
|
+ _bfd_elf_merge_object_attributes (ibfd, obfd);
|
||
|
+
|
||
|
+ return TRUE;
|
||
|
+}
|
||
|
diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c
|
||
|
index ebcb028..64819b9 100644
|
||
|
--- a/bfd/elf32-s390.c
|
||
|
+++ b/bfd/elf32-s390.c
|
||
|
@@ -3980,9 +3980,18 @@ elf_s390_plt_sym_val (bfd_vma i, const asection *plt,
|
||
|
return plt->vma + PLT_FIRST_ENTRY_SIZE + i * PLT_ENTRY_SIZE;
|
||
|
}
|
||
|
|
||
|
+/* Merge backend specific data from an object file to the output
|
||
|
+ object file when linking. */
|
||
|
+
|
||
|
static bfd_boolean
|
||
|
elf32_s390_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
|
||
|
{
|
||
|
+ if (!is_s390_elf (ibfd) || !is_s390_elf (obfd))
|
||
|
+ return TRUE;
|
||
|
+
|
||
|
+ if (!elf_s390_merge_obj_attributes (ibfd, obfd))
|
||
|
+ return FALSE;
|
||
|
+
|
||
|
elf_elfheader (obfd)->e_flags |= elf_elfheader (ibfd)->e_flags;
|
||
|
return TRUE;
|
||
|
}
|
||
|
diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c
|
||
|
index b2f1aa5..bbdee31 100644
|
||
|
--- a/bfd/elf64-s390.c
|
||
|
+++ b/bfd/elf64-s390.c
|
||
|
@@ -3766,6 +3766,21 @@ elf_s390_plt_sym_val (bfd_vma i, const asection *plt,
|
||
|
return plt->vma + PLT_FIRST_ENTRY_SIZE + i * PLT_ENTRY_SIZE;
|
||
|
}
|
||
|
|
||
|
+/* Merge backend specific data from an object file to the output
|
||
|
+ object file when linking. */
|
||
|
+
|
||
|
+static bfd_boolean
|
||
|
+elf64_s390_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
|
||
|
+{
|
||
|
+ if (!is_s390_elf (ibfd) || !is_s390_elf (obfd))
|
||
|
+ return TRUE;
|
||
|
+
|
||
|
+ if (!elf_s390_merge_obj_attributes (ibfd, obfd))
|
||
|
+ return FALSE;
|
||
|
+
|
||
|
+ return TRUE;
|
||
|
+}
|
||
|
+
|
||
|
/* Why was the hash table entry size definition changed from
|
||
|
ARCH_SIZE/8 to 4? This breaks the 64 bit dynamic linker and
|
||
|
this is the only reason for the s390_elf64_size_info structure. */
|
||
|
@@ -3824,7 +3839,8 @@ const struct elf_size_info s390_elf64_size_info =
|
||
|
#define bfd_elf64_bfd_is_local_label_name elf_s390_is_local_label_name
|
||
|
#define bfd_elf64_bfd_link_hash_table_create elf_s390_link_hash_table_create
|
||
|
#define bfd_elf64_bfd_reloc_type_lookup elf_s390_reloc_type_lookup
|
||
|
-#define bfd_elf64_bfd_reloc_name_lookup elf_s390_reloc_name_lookup
|
||
|
+#define bfd_elf64_bfd_reloc_name_lookup elf_s390_reloc_name_lookup
|
||
|
+#define bfd_elf64_bfd_merge_private_bfd_data elf64_s390_merge_private_bfd_data
|
||
|
|
||
|
#define elf_backend_adjust_dynamic_symbol elf_s390_adjust_dynamic_symbol
|
||
|
#define elf_backend_check_relocs elf_s390_check_relocs
|
||
|
diff --git a/binutils/readelf.c b/binutils/readelf.c
|
||
|
index 0c00b2f..9ae3cc6 100644
|
||
|
--- a/binutils/readelf.c
|
||
|
+++ b/binutils/readelf.c
|
||
|
@@ -12273,6 +12273,41 @@ display_power_gnu_attribute (unsigned char * p,
|
||
|
return display_tag_value (tag & 1, p, end);
|
||
|
}
|
||
|
|
||
|
+static unsigned char *
|
||
|
+display_s390_gnu_attribute (unsigned char * p,
|
||
|
+ int tag,
|
||
|
+ const unsigned char * const end)
|
||
|
+{
|
||
|
+ unsigned int len;
|
||
|
+ int val;
|
||
|
+
|
||
|
+ if (tag == Tag_GNU_S390_ABI_Vector)
|
||
|
+ {
|
||
|
+ val = read_uleb128 (p, &len, end);
|
||
|
+ p += len;
|
||
|
+ printf (" Tag_GNU_S390_ABI_Vector: ");
|
||
|
+
|
||
|
+ switch (val)
|
||
|
+ {
|
||
|
+ case 0:
|
||
|
+ printf (_("any\n"));
|
||
|
+ break;
|
||
|
+ case 1:
|
||
|
+ printf (_("software\n"));
|
||
|
+ break;
|
||
|
+ case 2:
|
||
|
+ printf (_("hardware\n"));
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ printf ("??? (%d)\n", val);
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ return p;
|
||
|
+ }
|
||
|
+
|
||
|
+ return display_tag_value (tag & 1, p, end);
|
||
|
+}
|
||
|
+
|
||
|
static void
|
||
|
display_sparc_hwcaps (int mask)
|
||
|
{
|
||
|
@@ -13044,6 +13079,13 @@ process_power_specific (FILE * file)
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
+process_s390_specific (FILE * file)
|
||
|
+{
|
||
|
+ return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
|
||
|
+ display_s390_gnu_attribute);
|
||
|
+}
|
||
|
+
|
||
|
+static int
|
||
|
process_sparc_specific (FILE * file)
|
||
|
{
|
||
|
return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
|
||
|
@@ -14803,6 +14845,10 @@ process_arch_specific (FILE * file)
|
||
|
case EM_PPC:
|
||
|
return process_power_specific (file);
|
||
|
break;
|
||
|
+ case EM_S390:
|
||
|
+ case EM_S390_OLD:
|
||
|
+ return process_s390_specific (file);
|
||
|
+ break;
|
||
|
case EM_SPARC:
|
||
|
case EM_SPARC32PLUS:
|
||
|
case EM_SPARCV9:
|
||
|
diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo
|
||
|
index 2c7d71e..21e11c4 100644
|
||
|
--- a/gas/doc/as.texinfo
|
||
|
+++ b/gas/doc/as.texinfo
|
||
|
@@ -7086,6 +7086,22 @@ The vector ABI used by this object file. The value will be:
|
||
|
@end itemize
|
||
|
@end table
|
||
|
|
||
|
+@subsection IBM z Systems Attributes
|
||
|
+
|
||
|
+@table @r
|
||
|
+@item Tag_GNU_S390_ABI_Vector (8)
|
||
|
+The vector ABI used by this object file. The value will be:
|
||
|
+
|
||
|
+@itemize @bullet
|
||
|
+@item
|
||
|
+0 for files not affected by the vector ABI.
|
||
|
+@item
|
||
|
+1 for files using software vector ABI.
|
||
|
+@item
|
||
|
+2 for files using hardware vector ABI.
|
||
|
+@end itemize
|
||
|
+@end table
|
||
|
+
|
||
|
@node Defining New Object Attributes
|
||
|
@section Defining New Object Attributes
|
||
|
|
||
|
diff --git a/include/elf/s390.h b/include/elf/s390.h
|
||
|
index 02e1db2..2aea3bb 100644
|
||
|
--- a/include/elf/s390.h
|
||
|
+++ b/include/elf/s390.h
|
||
|
@@ -129,6 +129,17 @@ START_RELOC_NUMBERS (elf_s390_reloc_type)
|
||
|
RELOC_NUMBER (R_390_GNU_VTENTRY, 251)
|
||
|
END_RELOC_NUMBERS (R_390_max)
|
||
|
|
||
|
-#endif /* _ELF_390_H */
|
||
|
-
|
||
|
+/* Object attribute tags. */
|
||
|
+enum
|
||
|
+{
|
||
|
+ /* 0-3 are generic. */
|
||
|
+ /* 4 is reserved for the FP ABI. */
|
||
|
+
|
||
|
+ /* Vector ABI:
|
||
|
+ 0 = not affected by the vector ABI, or not tagged.
|
||
|
+ 1 = software vector ABI being used
|
||
|
+ 2 = hardware vector ABI being used. */
|
||
|
+ Tag_GNU_S390_ABI_Vector = 8,
|
||
|
+};
|
||
|
|
||
|
+#endif /* _ELF_390_H */
|
||
|
--
|
||
|
2.3.0
|
||
|
|