+2020-06-22 Nelson Chu <nelson.chu@sifive.com>
+
+ * elfxx-riscv.c (struct priv_spec_t priv_specs[]): Move them from
+ opcodes/riscv-opc.c to bfd/elfxx-riscv.c, since we need it in linker.
+ (riscv_get_priv_spec_class): Likewise.
+ (riscv_get_priv_spec_name): Likewise.
+ (riscv_get_priv_spec_class_from_numbers): New function, convert
+ the version numbers into string, then call riscv_get_priv_spec_class
+ to get the priv spec class.
+ * elfxx-riscv.h (riscv_get_priv_spec_class): Move forward declaration
+ from include/opcode/riscv.h to bfd/elfxx-riscv.h.
+ (riscv_get_priv_spec_name): Likewise.
+ (riscv_get_priv_spec_class_from_numbers): New forward declaration.
+ (opcode/riscv.h): Include it in the header rather than elfxx-riscv.c.
+ * elfnn-riscv.c (riscv_merge_attributes): Get the priv spec classes
+ of input and output objects form their priv spec attributes by
+ riscv_get_priv_spec_class_from_numbers. Report warning rather than
+ errors when linking objects with differnet priv spec versions. We do
+ know v1.9.1 may have conflicts to other versions, so report the
+ warning, too. After that, update the output priv spec version to the
+ newest one so far.
+
2020-06-22 Nelson Chu <nelson.chu@sifive.com>
* elfnn-riscv.c (riscv_merge_attributes): Once we meet one of the
unsigned int Tag_a = Tag_RISCV_priv_spec;
unsigned int Tag_b = Tag_RISCV_priv_spec_minor;
unsigned int Tag_c = Tag_RISCV_priv_spec_revision;
+ enum riscv_priv_spec_class in_priv_spec;
+ enum riscv_priv_spec_class out_priv_spec;
+
+ /* Get the priv spec class from elf attribute numbers. */
+ riscv_get_priv_spec_class_from_numbers (in_attr[Tag_a].i,
+ in_attr[Tag_b].i,
+ in_attr[Tag_c].i,
+ &in_priv_spec);
+ riscv_get_priv_spec_class_from_numbers (out_attr[Tag_a].i,
+ out_attr[Tag_b].i,
+ out_attr[Tag_c].i,
+ &out_priv_spec);
/* Allow to link the object without the priv specs. */
- if (out_attr[Tag_a].i == 0
- && out_attr[Tag_b].i == 0
- && out_attr[Tag_c].i == 0)
+ if (out_priv_spec == PRIV_SPEC_CLASS_NONE)
{
out_attr[Tag_a].i = in_attr[Tag_a].i;
out_attr[Tag_b].i = in_attr[Tag_b].i;
out_attr[Tag_c].i = in_attr[Tag_c].i;
}
- else if ((in_attr[Tag_a].i != 0
- || in_attr[Tag_b].i != 0
- || in_attr[Tag_c].i != 0)
- && (out_attr[Tag_a].i != in_attr[Tag_a].i
- || out_attr[Tag_b].i != in_attr[Tag_b].i
- || out_attr[Tag_c].i != in_attr[Tag_c].i))
+ else if (in_priv_spec != PRIV_SPEC_CLASS_NONE
+ && in_priv_spec != out_priv_spec)
{
_bfd_error_handler
- (_("error: %pB use privilege spec version %u.%u.%u but "
+ (_("warning: %pB use privilege spec version %u.%u.%u but "
"the output use version %u.%u.%u."),
ibfd,
in_attr[Tag_a].i,
out_attr[Tag_a].i,
out_attr[Tag_b].i,
out_attr[Tag_c].i);
- result = FALSE;
+
+ /* The priv spec v1.9.1 can be linked with other spec
+ versions since the conflicts. We plan to drop the
+ v1.9.1 in a year or two, so this confict should be
+ removed in the future. */
+ if (in_priv_spec == PRIV_SPEC_CLASS_1P9P1
+ || out_priv_spec == PRIV_SPEC_CLASS_1P9P1)
+ {
+ _bfd_error_handler
+ (_("warning: privilege spec version 1.9.1 can not be "
+ "linked with other spec versions."));
+ }
+
+ /* Update the output priv attributes to the newest. */
+ if (in_priv_spec > out_priv_spec)
+ {
+ out_attr[Tag_a].i = in_attr[Tag_a].i;
+ out_attr[Tag_b].i = in_attr[Tag_b].i;
+ out_attr[Tag_c].i = in_attr[Tag_c].i;
+ }
}
priv_attrs_merged = TRUE;
}
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/riscv.h"
-#include "opcode/riscv.h"
#include "libiberty.h"
#include "elfxx-riscv.h"
#include "safe-ctype.h"
return attr_str;
}
+
+/* Record the priv spec version string and the corresponding class. */
+
+struct priv_spec_t
+{
+ const char *name;
+ enum riscv_priv_spec_class class;
+};
+
+/* List for all supported privilege versions. */
+
+static const struct priv_spec_t priv_specs[] =
+{
+ {"1.9.1", PRIV_SPEC_CLASS_1P9P1},
+ {"1.10", PRIV_SPEC_CLASS_1P10},
+ {"1.11", PRIV_SPEC_CLASS_1P11},
+
+/* Terminate the list. */
+ {NULL, 0}
+};
+
+/* Get the corresponding CSR version class by giving a privilege
+ version string. */
+
+int
+riscv_get_priv_spec_class (const char *s,
+ enum riscv_priv_spec_class *class)
+{
+ const struct priv_spec_t *version;
+
+ if (s == NULL)
+ return 0;
+
+ for (version = &priv_specs[0]; version->name != NULL; ++version)
+ if (strcmp (version->name, s) == 0)
+ {
+ *class = version->class;
+ return 1;
+ }
+
+ /* Can not find the supported privilege version. */
+ return 0;
+}
+
+/* Get the corresponding CSR version class by giving privilege
+ version numbers. It is usually used to convert the priv
+ attribute numbers into the corresponding class. */
+
+int
+riscv_get_priv_spec_class_from_numbers (unsigned int major,
+ unsigned int minor,
+ unsigned int revision,
+ enum riscv_priv_spec_class *class)
+{
+ size_t buf_size;
+ char *buf;
+ int result = 1;
+
+ if (major == 0 && minor == 0 && revision == 0)
+ {
+ *class = PRIV_SPEC_CLASS_NONE;
+ return result;
+ }
+
+ buf_size = riscv_estimate_digit (major)
+ + 1 /* '.' */
+ + riscv_estimate_digit (minor)
+ + 1; /* string terminator */
+ if (revision != 0)
+ {
+ buf_size += 1 /* '.' */
+ + riscv_estimate_digit (revision);
+ buf = xmalloc (buf_size);
+ snprintf (buf, buf_size, "%d.%d.%d", major, minor, revision);
+ }
+ else
+ {
+ buf = xmalloc (buf_size);
+ snprintf (buf, buf_size, "%d.%d", major, minor);
+ }
+
+ result = riscv_get_priv_spec_class (buf, class);
+ free (buf);
+ return result;
+}
+
+/* Get the corresponding privilege version string by giving a CSR
+ version class. */
+
+const char *
+riscv_get_priv_spec_name (enum riscv_priv_spec_class class)
+{
+ /* The first enum is PRIV_SPEC_CLASS_NONE. */
+ return priv_specs[class - 1].name;
+}
#include "elf/common.h"
#include "elf/internal.h"
+#include "opcode/riscv.h"
extern reloc_howto_type *
riscv_reloc_name_lookup (bfd *, const char *);
riscv_isa_ext_class_t
riscv_get_prefix_class (const char *);
+
+extern int
+riscv_get_priv_spec_class (const char *, enum riscv_priv_spec_class *);
+
+extern int
+riscv_get_priv_spec_class_from_numbers (unsigned int,
+ unsigned int,
+ unsigned int,
+ enum riscv_priv_spec_class *);
+
+extern const char *
+riscv_get_priv_spec_name (enum riscv_priv_spec_class);
+2020-06-22 Nelson Chu <nelson.chu@sifive.com>
+
+ * config/tc-riscv.c (buf_size, buf): Remove the unused variables.
+ (riscv_set_default_priv_spec): Get the priv spec version from the
+ priv spec attributes by riscv_get_priv_spec_class_from_numbers.
+
2020-06-20 Alan Modra <amodra@gmail.com>
* configure.tgt: Set bfd_gas for all SH targets.
enum riscv_priv_spec_class class;
unsigned major, minor, revision;
obj_attribute *attr;
- size_t buf_size;
- char *buf;
/* Find the corresponding priv spec class. */
if (riscv_get_priv_spec_class (s, &class))
minor = (unsigned) attr[Tag_RISCV_priv_spec_minor].i;
revision = (unsigned) attr[Tag_RISCV_priv_spec_revision].i;
- /* The priv attributes setting 0.0.0 is meaningless. We should have set
- the default_priv_spec by md_parse_option and riscv_after_parse_args,
- so just skip the following setting. */
- if (major == 0 && minor == 0 && revision == 0)
- return 1;
-
- buf_size = riscv_estimate_digit (major)
- + 1 /* '.' */
- + riscv_estimate_digit (minor)
- + 1; /* string terminator */
- if (revision != 0)
+ if (riscv_get_priv_spec_class_from_numbers (major,
+ minor,
+ revision,
+ &class))
{
- buf_size += 1 /* '.' */
- + riscv_estimate_digit (revision);
- buf = xmalloc (buf_size);
- snprintf (buf, buf_size, "%d.%d.%d", major, minor, revision);
- }
- else
- {
- buf = xmalloc (buf_size);
- snprintf (buf, buf_size, "%d.%d", major, minor);
- }
+ /* The priv attributes setting 0.0.0 is meaningless. We should have set
+ the default_priv_spec by md_parse_option and riscv_after_parse_args,
+ so just skip the following setting. */
+ if (class == PRIV_SPEC_CLASS_NONE)
+ return 1;
- if (riscv_get_priv_spec_class (buf, &class))
- {
default_priv_spec = class;
- free (buf);
return 1;
}
/* Still can not find the priv spec class. */
as_bad (_("Unknown default privilege spec `%d.%d.%d' set by "
"privilege attributes"), major, minor, revision);
- free (buf);
return 0;
}
+2020-06-22 Nelson Chu <nelson.chu@sifive.com>
+
+ * opcode/riscv.h (riscv_get_priv_spec_class): Move the function
+ forward declarations to bfd/elfxx-riscv.h.
+ (riscv_get_priv_spec_name): Likewise.
+
2020-06-15 Max Filippov <jcmvbkbc@gmail.com>
* elf/xtensa.h (xtensa_abi_choice): New declaration.
extern int
riscv_get_isa_spec_class (const char *, enum riscv_isa_spec_class *);
-extern int
-riscv_get_priv_spec_class (const char *, enum riscv_priv_spec_class *);
-extern const char *
-riscv_get_priv_spec_name (enum riscv_priv_spec_class);
#endif /* _RISCV_H_ */
+2020-06-22 Nelson Chu <nelson.chu@sifive.com>
+
+ * testsuite/ld-riscv-elf/attr-merge-priv-spec-failed-01.d: Updated.
+ * testsuite/ld-riscv-elf/attr-merge-priv-spec-failed-02.d: Updated.
+ * testsuite/ld-riscv-elf/attr-merge-priv-spec-failed-03.d: Updated.
+ * testsuite/ld-riscv-elf/attr-merge-priv-spec-failed-04.d: Updated.
+ * testsuite/ld-riscv-elf/attr-merge-priv-spec-failed-05.d: Updated.
+ * testsuite/ld-riscv-elf/attr-merge-priv-spec-failed-06.d: Updated.
+
2020-06-21 Alan Modra <amodra@gmail.com>
* ldfile.c: Replace uses of ENABLE_PLUGINS with BFD_SUPPORTS_PLUGINS.
#source: attr-merge-priv-spec-c.s
#as:
#ld: -r
-#error: .*use privilege spec version 1.11.0 but the output use version 1.9.1.
+#warning: .*warning: .*use privilege spec version 1.11.0 but the output use version 1.9.1.
+#warning: .*warning: .*privilege spec version 1.9.1 can not be linked with other spec versions.
+#readelf: -A
+
+Attribute Section: riscv
+File Attributes
+ Tag_RISCV_arch: [a-zA-Z0-9_\"].*
+ Tag_RISCV_priv_spec: 1
+ Tag_RISCV_priv_spec_minor: 11
#source: attr-merge-priv-spec-a.s
#as:
#ld: -r
-#error: .*use privilege spec version 1.9.1 but the output use version 1.11.0.
+#warning: .*warning: .*use privilege spec version 1.9.1 but the output use version 1.11.0.
+#warning: .*warning: .*privilege spec version 1.9.1 can not be linked with other spec versions.
+#readelf: -A
+
+Attribute Section: riscv
+File Attributes
+ Tag_RISCV_arch: [a-zA-Z0-9_\"].*
+ Tag_RISCV_priv_spec: 1
+ Tag_RISCV_priv_spec_minor: 11
#source: attr-merge-priv-spec-c.s
#as:
#ld: -r
-#error: .*use privilege spec version 1.11.0 but the output use version 1.9.1.
+#warning: .*warning: .*use privilege spec version 1.11.0 but the output use version 1.9.1.
+#warning: .*warning: .*privilege spec version 1.9.1 can not be linked with other spec versions.
+#readelf: -A
+
+Attribute Section: riscv
+File Attributes
+ Tag_RISCV_arch: [a-zA-Z0-9_\"].*
+ Tag_RISCV_priv_spec: 1
+ Tag_RISCV_priv_spec_minor: 11
#source: attr-merge-priv-spec-c.s
#as:
#ld: -r
-#error: .*use privilege spec version 1.11.0 but the output use version 1.9.1.
+#warning: .*warning: .*use privilege spec version 1.11.0 but the output use version 1.9.1.
+#warning: .*warning: .*privilege spec version 1.9.1 can not be linked with other spec versions.
+#readelf: -A
+
+Attribute Section: riscv
+File Attributes
+ Tag_RISCV_arch: [a-zA-Z0-9_\"].*
+ Tag_RISCV_priv_spec: 1
+ Tag_RISCV_priv_spec_minor: 11
#source: attr-merge-priv-spec-a.s
#as:
#ld: -r
-#error: .*use privilege spec version 1.9.1 but the output use version 1.11.0.
+#warning: .*warning: .*use privilege spec version 1.9.1 but the output use version 1.11.0.
+#warning: .*warning: .*privilege spec version 1.9.1 can not be linked with other spec versions.
+#readelf: -A
+
+Attribute Section: riscv
+File Attributes
+ Tag_RISCV_arch: [a-zA-Z0-9_\"].*
+ Tag_RISCV_priv_spec: 1
+ Tag_RISCV_priv_spec_minor: 11
#source: attr-merge-priv-spec-a.s
#as:
#ld: -r
-#error: .*use privilege spec version 1.9.1 but the output use version 1.11.0.
+#warning: .*warning: .*use privilege spec version 1.9.1 but the output use version 1.11.0.
+#warning: .*warning: .*privilege spec version 1.9.1 can not be linked with other spec versions.
+#readelf: -A
+
+Attribute Section: riscv
+File Attributes
+ Tag_RISCV_arch: [a-zA-Z0-9_\"].*
+ Tag_RISCV_priv_spec: 1
+ Tag_RISCV_priv_spec_minor: 11
+2020-06-22 Nelson Chu <nelson.chu@sifive.com>
+
+ * riscv-opc.c: Move the structures and functions to bfd/elfxx-riscv.c.
+ * riscv-dis.c: Include elfxx-riscv.h.
+
2020-06-18 H.J. Lu <hongjiu.lu@intel.com>
* i386-dis.c (prefix_table): Revert the last vmgexit change.
#include "opintl.h"
#include "elf-bfd.h"
#include "elf/riscv.h"
+#include "elfxx-riscv.h"
#include "bfd_stdint.h"
#include <ctype.h>
/* Can not find the supported ISA spec. */
return 0;
}
-
-struct priv_spec_t
-{
- const char *name;
- enum riscv_priv_spec_class class;
-};
-
-/* List for all supported privilege versions. */
-static const struct priv_spec_t priv_specs[] =
-{
- {"1.9.1", PRIV_SPEC_CLASS_1P9P1},
- {"1.10", PRIV_SPEC_CLASS_1P10},
- {"1.11", PRIV_SPEC_CLASS_1P11},
-
-/* Terminate the list. */
- {NULL, 0}
-};
-
-/* Get the corresponding CSR version class by giving a privilege
- version string. */
-
-int
-riscv_get_priv_spec_class (const char *s,
- enum riscv_priv_spec_class *class)
-{
- const struct priv_spec_t *version;
-
- if (s == NULL)
- return 0;
-
- for (version = &priv_specs[0]; version->name != NULL; ++version)
- if (strcmp (version->name, s) == 0)
- {
- *class = version->class;
- return 1;
- }
-
- /* Can not find the supported privilege version. */
- return 0;
-}
-
-/* Get the corresponding privilege version string by giving a CSR
- version class. */
-
-const char *
-riscv_get_priv_spec_name (enum riscv_priv_spec_class class)
-{
- /* The first enum is PRIV_SPEC_CLASS_NONE. */
- return priv_specs[class - 1].name;
-}