aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPat Bernardi <bernardi@adacore.com>2020-06-25 16:05:38 -0400
committerAlan Modra <amodra@gmail.com>2020-06-26 14:42:19 +0930
commit85f7484a3a1921649029c4a4fcf3247c3f3bc13c (patch)
treed8cec9b624c9984936c00c9f3389d0c3a757750d
parentba9b3ef5ee666467b67780e81f868c432f4fc56d (diff)
downloadgdb-85f7484a3a1921649029c4a4fcf3247c3f3bc13c.zip
gdb-85f7484a3a1921649029c4a4fcf3247c3f3bc13c.tar.gz
gdb-85f7484a3a1921649029c4a4fcf3247c3f3bc13c.tar.bz2
m68k: tag floating-point ABI used
This patch adds GNU attribute support to m68k and utilises it to tag the floating-point calling convention used (hard-float or soft-float). It enables the linker to ensure linked objects use a consistent floating-point ABI and allows tools like GDB to infer the ABI used from the ELF file. It is based on similar work done for PowerPC. bfd/ * elf32-m68k.c (m68k_elf_merge_obj_attributes): New function. (elf32_m68k_merge_private_bfd_data): Merge GNU attributes. binutils/ * readelf.c (display_m68k_gnu_attribute): New function. (process_arch_specific): Call display_m68k_gnu_attribute for EM_68K. gas/ * config/tc-m68k.c (m68k_elf_gnu_attribute): New function. (md_pseudo_table): Handle "gnu_attribute". * doc/as.texi: Document GNU attribute for M68K. include/ * elf/m68k.h: Add enum for GNU object attribute with floating point tag name and values. ld/ * testsuite/ld-m68k/attr-gnu-4-0.s: New file. * testsuite/ld-m68k/attr-gnu-4-1.s: Likewise. * testsuite/ld-m68k/attr-gnu-4-2.s: Likewise. * testsuite/ld-m68k/attr-gnu-4-00.d: Likewise. * testsuite/ld-m68k/attr-gnu-4-01.d: Likewise. * testsuite/ld-m68k/attr-gnu-4-02.d: Likewise. * testsuite/ld-m68k/attr-gnu-4-10.d: Likewise. * testsuite/ld-m68k/attr-gnu-4-11.d: Likewise. * testsuite/ld-m68k/attr-gnu-4-12.d: Likewise. * testsuite/ld-m68k/attr-gnu-4-20.d: Likewise. * testsuite/ld-m68k/attr-gnu-4-21.d: Likewise. * testsuite/ld-m68k/attr-gnu-4-22.d: Likewise. * testsuite/ld-m68k/m68k.exp: Run the new tests.
-rw-r--r--bfd/ChangeLog5
-rw-r--r--bfd/elf32-m68k.c62
-rw-r--r--binutils/ChangeLog5
-rw-r--r--binutils/readelf.c42
-rw-r--r--gas/ChangeLog6
-rw-r--r--gas/config/tc-m68k.c20
-rw-r--r--gas/doc/as.texi16
-rw-r--r--include/ChangeLog5
-rw-r--r--include/elf/m68k.h14
-rw-r--r--ld/ChangeLog16
-rw-r--r--ld/testsuite/ld-m68k/attr-gnu-4-0.s1
-rw-r--r--ld/testsuite/ld-m68k/attr-gnu-4-00.d4
-rw-r--r--ld/testsuite/ld-m68k/attr-gnu-4-01.d8
-rw-r--r--ld/testsuite/ld-m68k/attr-gnu-4-02.d8
-rw-r--r--ld/testsuite/ld-m68k/attr-gnu-4-1.s1
-rw-r--r--ld/testsuite/ld-m68k/attr-gnu-4-10.d8
-rw-r--r--ld/testsuite/ld-m68k/attr-gnu-4-11.d8
-rw-r--r--ld/testsuite/ld-m68k/attr-gnu-4-12.d4
-rw-r--r--ld/testsuite/ld-m68k/attr-gnu-4-2.s1
-rw-r--r--ld/testsuite/ld-m68k/attr-gnu-4-20.d8
-rw-r--r--ld/testsuite/ld-m68k/attr-gnu-4-21.d4
-rw-r--r--ld/testsuite/ld-m68k/attr-gnu-4-22.d8
-rw-r--r--ld/testsuite/ld-m68k/m68k.exp10
23 files changed, 263 insertions, 1 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 2d9f1ec..7b6375a 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,8 @@
+2020-06-26 Pat Bernardi <bernardi@adacore.com>
+
+ * elf32-m68k.c (m68k_elf_merge_obj_attributes): New function.
+ (elf32_m68k_merge_private_bfd_data): Merge GNU attributes.
+
2020-06-26 Alan Modra <amodra@gmail.com>
* elfxx-riscv.c (struct priv_spec_t, priv_specs),
diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c
index 39c5e1c..7ccdaab 100644
--- a/bfd/elf32-m68k.c
+++ b/bfd/elf32-m68k.c
@@ -1122,6 +1122,65 @@ elf32_m68k_set_private_flags (bfd *abfd, flagword flags)
return TRUE;
}
+/* Merge object attributes from IBFD into OBFD. Warn if
+ there are conflicting attributes. */
+static bfd_boolean
+m68k_elf_merge_obj_attributes (bfd *ibfd, struct bfd_link_info *info)
+{
+ bfd *obfd = info->output_bfd;
+ obj_attribute *in_attr, *in_attrs;
+ obj_attribute *out_attr, *out_attrs;
+ bfd_boolean ret = TRUE;
+
+ in_attrs = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
+ out_attrs = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU];
+
+ in_attr = &in_attrs[Tag_GNU_M68K_ABI_FP];
+ out_attr = &out_attrs[Tag_GNU_M68K_ABI_FP];
+
+ if (in_attr->i != out_attr->i)
+ {
+ int in_fp = in_attr->i & 3;
+ int out_fp = out_attr->i & 3;
+ static bfd *last_fp;
+
+ if (in_fp == 0)
+ ;
+ else if (out_fp == 0)
+ {
+ out_attr->type = ATTR_TYPE_FLAG_INT_VAL;
+ out_attr->i ^= in_fp;
+ last_fp = ibfd;
+ }
+ else if (out_fp == 1 && in_fp == 2)
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB uses hard float, %pB uses soft float"),
+ last_fp, ibfd);
+ ret = FALSE;
+ }
+ else if (out_fp == 2 && in_fp == 1)
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB uses hard float, %pB uses soft float"),
+ ibfd, last_fp);
+ ret = FALSE;
+ }
+ }
+
+ if (!ret)
+ {
+ out_attr->type = ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_ERROR;
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* Merge Tag_compatibility attributes and any common GNU ones. */
+ return _bfd_elf_merge_object_attributes (ibfd, info);
+}
+
/* Merge backend specific data from an object file to the output
object file when linking. */
static bfd_boolean
@@ -1149,6 +1208,9 @@ elf32_m68k_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
bfd_set_arch_mach (obfd, bfd_arch_m68k, arch_info->mach);
+ if (!m68k_elf_merge_obj_attributes (ibfd, info))
+ return FALSE;
+
in_flags = elf_elfheader (ibfd)->e_flags;
if (!elf_flags_init (obfd))
{
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 722e563..2009fc1 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,8 @@
+2020-06-26 Pat Bernardi <bernardi@adacore.com>
+
+ * readelf.c (display_m68k_gnu_attribute): New function.
+ (process_arch_specific): Call display_m68k_gnu_attribute for EM_68K.
+
2020-06-23 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/26160
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 9e4fa33..25f0e23 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -15368,6 +15368,44 @@ display_gnu_attribute (unsigned char * p,
}
static unsigned char *
+display_m68k_gnu_attribute (unsigned char * p,
+ unsigned int tag,
+ const unsigned char * const end)
+{
+ unsigned int val;
+
+ if (tag == Tag_GNU_M68K_ABI_FP)
+ {
+ printf (" Tag_GNU_M68K_ABI_FP: ");
+ if (p == end)
+ {
+ printf (_("<corrupt>\n"));
+ return p;
+ }
+ READ_ULEB (val, p, end);
+
+ if (val > 3)
+ printf ("(%#x), ", val);
+
+ switch (val & 3)
+ {
+ case 0:
+ printf (_("unspecified hard/soft float\n"));
+ break;
+ case 1:
+ printf (_("hard float\n"));
+ break;
+ case 2:
+ printf (_("soft float\n"));
+ break;
+ }
+ return p;
+ }
+
+ return display_tag_value (tag & 1, p, end);
+}
+
+static unsigned char *
display_power_gnu_attribute (unsigned char * p,
unsigned int tag,
const unsigned char * const end)
@@ -19928,6 +19966,10 @@ process_arch_specific (Filedata * filedata)
case EM_NDS32:
return process_nds32_specific (filedata);
+ case EM_68K:
+ return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
+ display_m68k_gnu_attribute);
+
case EM_PPC:
case EM_PPC64:
return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 038ae0c..f60fde6 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,9 @@
+2020-06-26 Pat Bernardi <bernardi@adacore.com>
+
+ * config/tc-m68k.c (m68k_elf_gnu_attribute): New function.
+ (md_pseudo_table): Handle "gnu_attribute".
+ * doc/as.texi: Document GNU attribute for M68K.
+
2020-06-25 Nick Clifton <nickc@redhat.com>
PR 26141
diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c
index cbb227a..6ffc943 100644
--- a/gas/config/tc-m68k.c
+++ b/gas/config/tc-m68k.c
@@ -30,6 +30,7 @@
#include "elf/m68k.h"
static void m68k_elf_cons (int);
+static void m68k_elf_gnu_attribute (int);
/* This string holds the chars that always start a comment. If the
pre-processor is disabled, these aren't very useful. The macro
@@ -889,6 +890,7 @@ const pseudo_typeS md_pseudo_table[] =
{"arch", s_m68k_arch, 0},
{"cpu", s_m68k_cpu, 0},
+ {"gnu_attribute", m68k_elf_gnu_attribute, 0},
/* The following pseudo-ops are supported for MRI compatibility. */
{"chip", s_chip, 0},
@@ -7951,6 +7953,24 @@ m68k_elf_cons (int nbytes /* 4=.long */)
demand_empty_rest_of_line ();
}
+/* Parse a .gnu_attribute directive. */
+static void
+m68k_elf_gnu_attribute (int ignored ATTRIBUTE_UNUSED)
+{
+ int tag = obj_elf_vendor_attribute (OBJ_ATTR_GNU);
+
+ /* Check validity of defined m68k tags. */
+ if (tag == Tag_GNU_M68K_ABI_FP)
+ {
+ unsigned int val;
+
+ val = bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_GNU, tag);
+
+ if (tag == Tag_GNU_M68K_ABI_FP && val > 2)
+ as_warn (_("unknown .gnu_attribute value"));
+ }
+}
+
int
tc_m68k_regname_to_dw2regnum (const char *regname)
{
diff --git a/gas/doc/as.texi b/gas/doc/as.texi
index f8d892e..ac4a073 100644
--- a/gas/doc/as.texi
+++ b/gas/doc/as.texi
@@ -7583,6 +7583,22 @@ than 1, the file can only be processed by other toolchains under some private
arrangement indicated by the flag value and the vendor name.
@end table
+@subsection M680x0 Attributes
+
+@table @r
+@item Tag_GNU_M68K_ABI_FP (4)
+The floating-point ABI used by this object file. The value will be:
+
+@itemize @bullet
+@item
+0 for files not affected by the floating-point ABI.
+@item
+1 for files using double-precision hardware floating-point ABI.
+@item
+2 for files using the software floating-point ABI.
+@end itemize
+@end table
+
@subsection MIPS Attributes
@table @r
diff --git a/include/ChangeLog b/include/ChangeLog
index 8e06abf..ab6d753 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,8 @@
+2020-06-26 Pat Bernardi <bernardi@adacore.com>
+
+ * elf/m68k.h: Add enum for GNU object attribute with floating point
+ tag name and values.
+
2020-06-25 Nick Clifton <nickc@redhat.com>
* libiberty.h (bsearch_r): Remove use of the register keyword from
diff --git a/include/elf/m68k.h b/include/elf/m68k.h
index 2d3c12e..e5b0592 100644
--- a/include/elf/m68k.h
+++ b/include/elf/m68k.h
@@ -97,5 +97,17 @@ END_RELOC_NUMBERS (R_68K_max)
#define EF_M68K_CF_EMAC_B 0x30 /* EMAC_B */
#define EF_M68K_CF_FLOAT 0x40 /* Has float insns */
#define EF_M68K_CF_MASK 0xFF
-
+
+/* GNU object attribute tags. */
+enum
+{
+ /* 0-3 are generic. */
+
+ /* FP ABI, low 2 bits:
+ 1 for double precision hard-float,
+ 2 for soft-float,
+ 0 for not tagged or not using any ABIs affected by the differences. */
+ Tag_GNU_M68K_ABI_FP = 4,
+};
+
#endif
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 6f58650..4a38fa8 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,19 @@
+2020-06-26 Pat Bernardi <bernardi@adacore.com>
+
+ * testsuite/ld-m68k/attr-gnu-4-0.s: New file.
+ * testsuite/ld-m68k/attr-gnu-4-1.s: Likewise.
+ * testsuite/ld-m68k/attr-gnu-4-2.s: Likewise.
+ * testsuite/ld-m68k/attr-gnu-4-00.d: Likewise.
+ * testsuite/ld-m68k/attr-gnu-4-01.d: Likewise.
+ * testsuite/ld-m68k/attr-gnu-4-02.d: Likewise.
+ * testsuite/ld-m68k/attr-gnu-4-10.d: Likewise.
+ * testsuite/ld-m68k/attr-gnu-4-11.d: Likewise.
+ * testsuite/ld-m68k/attr-gnu-4-12.d: Likewise.
+ * testsuite/ld-m68k/attr-gnu-4-20.d: Likewise.
+ * testsuite/ld-m68k/attr-gnu-4-21.d: Likewise.
+ * testsuite/ld-m68k/attr-gnu-4-22.d: Likewise.
+ * testsuite/ld-m68k/m68k.exp: Run the new tests.
+
2020-06-24 H.J. Lu <hongjiu.lu@intel.com>
PR ld/26165
diff --git a/ld/testsuite/ld-m68k/attr-gnu-4-0.s b/ld/testsuite/ld-m68k/attr-gnu-4-0.s
new file mode 100644
index 0000000..a143746
--- /dev/null
+++ b/ld/testsuite/ld-m68k/attr-gnu-4-0.s
@@ -0,0 +1 @@
+.gnu_attribute 4,0
diff --git a/ld/testsuite/ld-m68k/attr-gnu-4-00.d b/ld/testsuite/ld-m68k/attr-gnu-4-00.d
new file mode 100644
index 0000000..467ad60
--- /dev/null
+++ b/ld/testsuite/ld-m68k/attr-gnu-4-00.d
@@ -0,0 +1,4 @@
+#source: attr-gnu-4-0.s
+#source: attr-gnu-4-0.s
+#ld: -r
+#readelf: -A
diff --git a/ld/testsuite/ld-m68k/attr-gnu-4-01.d b/ld/testsuite/ld-m68k/attr-gnu-4-01.d
new file mode 100644
index 0000000..1e7fef0
--- /dev/null
+++ b/ld/testsuite/ld-m68k/attr-gnu-4-01.d
@@ -0,0 +1,8 @@
+#source: attr-gnu-4-0.s
+#source: attr-gnu-4-1.s
+#ld: -r
+#readelf: -A
+
+Attribute Section: gnu
+File Attributes
+ Tag_GNU_M68K_ABI_FP: hard float
diff --git a/ld/testsuite/ld-m68k/attr-gnu-4-02.d b/ld/testsuite/ld-m68k/attr-gnu-4-02.d
new file mode 100644
index 0000000..cc3945a
--- /dev/null
+++ b/ld/testsuite/ld-m68k/attr-gnu-4-02.d
@@ -0,0 +1,8 @@
+#source: attr-gnu-4-0.s
+#source: attr-gnu-4-2.s
+#ld: -r
+#readelf: -A
+
+Attribute Section: gnu
+File Attributes
+ Tag_GNU_M68K_ABI_FP: soft float
diff --git a/ld/testsuite/ld-m68k/attr-gnu-4-1.s b/ld/testsuite/ld-m68k/attr-gnu-4-1.s
new file mode 100644
index 0000000..e985a56
--- /dev/null
+++ b/ld/testsuite/ld-m68k/attr-gnu-4-1.s
@@ -0,0 +1 @@
+.gnu_attribute 4,1
diff --git a/ld/testsuite/ld-m68k/attr-gnu-4-10.d b/ld/testsuite/ld-m68k/attr-gnu-4-10.d
new file mode 100644
index 0000000..a6a798b
--- /dev/null
+++ b/ld/testsuite/ld-m68k/attr-gnu-4-10.d
@@ -0,0 +1,8 @@
+#source: attr-gnu-4-1.s
+#source: attr-gnu-4-0.s
+#ld: -r
+#readelf: -A
+
+Attribute Section: gnu
+File Attributes
+ Tag_GNU_M68K_ABI_FP: hard float
diff --git a/ld/testsuite/ld-m68k/attr-gnu-4-11.d b/ld/testsuite/ld-m68k/attr-gnu-4-11.d
new file mode 100644
index 0000000..ecc66a4
--- /dev/null
+++ b/ld/testsuite/ld-m68k/attr-gnu-4-11.d
@@ -0,0 +1,8 @@
+#source: attr-gnu-4-1.s
+#source: attr-gnu-4-1.s
+#ld: -r
+#readelf: -A
+
+Attribute Section: gnu
+File Attributes
+ Tag_GNU_M68K_ABI_FP: hard float
diff --git a/ld/testsuite/ld-m68k/attr-gnu-4-12.d b/ld/testsuite/ld-m68k/attr-gnu-4-12.d
new file mode 100644
index 0000000..49526b1
--- /dev/null
+++ b/ld/testsuite/ld-m68k/attr-gnu-4-12.d
@@ -0,0 +1,4 @@
+#source: attr-gnu-4-1.s
+#source: attr-gnu-4-2.s
+#ld: -r
+#error: .* uses hard float, .* uses soft float.*
diff --git a/ld/testsuite/ld-m68k/attr-gnu-4-2.s b/ld/testsuite/ld-m68k/attr-gnu-4-2.s
new file mode 100644
index 0000000..54ebf4e
--- /dev/null
+++ b/ld/testsuite/ld-m68k/attr-gnu-4-2.s
@@ -0,0 +1 @@
+.gnu_attribute 4,2
diff --git a/ld/testsuite/ld-m68k/attr-gnu-4-20.d b/ld/testsuite/ld-m68k/attr-gnu-4-20.d
new file mode 100644
index 0000000..92b410a
--- /dev/null
+++ b/ld/testsuite/ld-m68k/attr-gnu-4-20.d
@@ -0,0 +1,8 @@
+#source: attr-gnu-4-2.s
+#source: attr-gnu-4-0.s
+#ld: -r
+#readelf: -A
+
+Attribute Section: gnu
+File Attributes
+ Tag_GNU_M68K_ABI_FP: soft float
diff --git a/ld/testsuite/ld-m68k/attr-gnu-4-21.d b/ld/testsuite/ld-m68k/attr-gnu-4-21.d
new file mode 100644
index 0000000..390dada
--- /dev/null
+++ b/ld/testsuite/ld-m68k/attr-gnu-4-21.d
@@ -0,0 +1,4 @@
+#source: attr-gnu-4-2.s
+#source: attr-gnu-4-1.s
+#ld: -r
+#error: .* uses hard float, .* uses soft float.*
diff --git a/ld/testsuite/ld-m68k/attr-gnu-4-22.d b/ld/testsuite/ld-m68k/attr-gnu-4-22.d
new file mode 100644
index 0000000..cfa9b35
--- /dev/null
+++ b/ld/testsuite/ld-m68k/attr-gnu-4-22.d
@@ -0,0 +1,8 @@
+#source: attr-gnu-4-2.s
+#source: attr-gnu-4-2.s
+#ld: -r
+#readelf: -A
+
+Attribute Section: gnu
+File Attributes
+ Tag_GNU_M68K_ABI_FP: soft float
diff --git a/ld/testsuite/ld-m68k/m68k.exp b/ld/testsuite/ld-m68k/m68k.exp
index df859ba..610b435 100644
--- a/ld/testsuite/ld-m68k/m68k.exp
+++ b/ld/testsuite/ld-m68k/m68k.exp
@@ -92,3 +92,13 @@ if { [istarget m68k-*-linux*] } then {
run_ld_link_tests $m68k_tls_tests
}
+
+run_dump_test "attr-gnu-4-00"
+run_dump_test "attr-gnu-4-01"
+run_dump_test "attr-gnu-4-02"
+run_dump_test "attr-gnu-4-10"
+run_dump_test "attr-gnu-4-11"
+run_dump_test "attr-gnu-4-12"
+run_dump_test "attr-gnu-4-20"
+run_dump_test "attr-gnu-4-21"
+run_dump_test "attr-gnu-4-22"