aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorNelson Chu <nelson.chu@sifive.com>2020-05-29 16:56:36 +0800
committerNelson Chu <nelson.chu@sifive.com>2020-06-05 12:20:53 +0800
commit412857647fecd41c45fab0d9c45198a0d2cbf6d5 (patch)
tree6d7dac8aa992b1ece6b59ad0be9a95929f73d41f /bfd
parent3fc6c3dc2af2283bd89f1b1278b39922416e8d1b (diff)
downloadbinutils-412857647fecd41c45fab0d9c45198a0d2cbf6d5.zip
binutils-412857647fecd41c45fab0d9c45198a0d2cbf6d5.tar.gz
binutils-412857647fecd41c45fab0d9c45198a0d2cbf6d5.tar.bz2
RISC-V: The object without priv spec attributes can be linked with any object.
bfd/ * elfnn-riscv.c (riscv_merge_attributes): Add new boolean priv_may_conflict, in_priv_zero and out_priv_zero to decide whether the object can be linked according to it's priv attributes. The object without any priv spec attributes can be linked with others. If the first input object doesn't contain any priv attributes, then we need to copy the setting from the next input one. Also report more detailed error messages to user. ld/ * testsuite/ld-riscv-elf/attr-merge-priv-spec.d: Rename to attr-merge-priv-spec-01.d. * testsuite/ld-riscv-elf/attr-merge-priv-spec-c.s: Set priv spec to 1.11. * testsuite/ld-riscv-elf/attr-merge-priv-spec-d.s: Empty priv spec setting. * testsuite/ld-riscv-elf/attr-merge-priv-spec-02.d: New testcase. * testsuite/ld-riscv-elf/attr-merge-priv-spec-03.d: Likewise. * testsuite/ld-riscv-elf/attr-merge-priv-spec-failed-01.d: Likewise. * testsuite/ld-riscv-elf/attr-merge-priv-spec-failed-02.d: Likewise. * testsuite/ld-riscv-elf/attr-merge-priv-spec-failed-03.d: Likewise. * testsuite/ld-riscv-elf/attr-merge-priv-spec-failed-04.d: Likewise. * testsuite/ld-riscv-elf/attr-merge-priv-spec-failed-05.d: Likewise. * testsuite/ld-riscv-elf/attr-merge-priv-spec-failed-06.d: Likewise. * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog10
-rw-r--r--bfd/elfnn-riscv.c40
2 files changed, 48 insertions, 2 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index e99de6d..0a34054 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,13 @@
+2020-06-05 Nelson Chu <nelson.chu@sifive.com>
+
+ * elfnn-riscv.c (riscv_merge_attributes): Add new boolean
+ priv_may_conflict, in_priv_zero and out_priv_zero to decide
+ whether the object can be linked according to it's priv
+ attributes. The object without any priv spec attributes can
+ be linked with others. If the first input object doesn't contain
+ any priv attributes, then we need to copy the setting from the
+ next input one. Also report more detailed error messages to user.
+
2020-06-04 Stephen Casner <casner@acm.org>
Extend pdp11-aout symbol table format to accommodate .stab
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 163c4d9..986e717 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -2987,6 +2987,9 @@ riscv_merge_attributes (bfd *ibfd, struct bfd_link_info *info)
obj_attribute *in_attr;
obj_attribute *out_attr;
bfd_boolean result = TRUE;
+ bfd_boolean priv_may_conflict = FALSE;
+ bfd_boolean in_priv_zero = TRUE;
+ bfd_boolean out_priv_zero = TRUE;
const char *sec_name = get_elf_backend_data (ibfd)->obj_attrs_section;
unsigned int i;
@@ -3041,20 +3044,52 @@ riscv_merge_attributes (bfd *ibfd, struct bfd_link_info *info)
out_attr[Tag_RISCV_arch].s = merged_arch;
}
break;
+
case Tag_RISCV_priv_spec:
case Tag_RISCV_priv_spec_minor:
case Tag_RISCV_priv_spec_revision:
+ if (in_attr[i].i != 0)
+ in_priv_zero = FALSE;
+ if (out_attr[i].i != 0)
+ out_priv_zero = FALSE;
if (out_attr[i].i != in_attr[i].i)
+ priv_may_conflict = TRUE;
+
+ /* We check the priv version conflict when parsing the
+ revision version. */
+ if (i != Tag_RISCV_priv_spec_revision)
+ break;
+
+ /* Allow to link the object without the priv setting. */
+ if (out_priv_zero)
+ {
+ out_attr[i].i = in_attr[i].i;
+ out_attr[Tag_RISCV_priv_spec].i =
+ in_attr[Tag_RISCV_priv_spec].i;
+ out_attr[Tag_RISCV_priv_spec_minor].i =
+ in_attr[Tag_RISCV_priv_spec_minor].i;
+ }
+ else if (!in_priv_zero
+ && priv_may_conflict)
{
_bfd_error_handler
- (_("error: %pB: conflicting priv spec version "
- "(major/minor/revision)."), ibfd);
+ (_("error: %pB use privilege spec version %u.%u.%u but "
+ "the output use version %u.%u.%u."),
+ ibfd,
+ in_attr[Tag_RISCV_priv_spec].i,
+ in_attr[Tag_RISCV_priv_spec_minor].i,
+ in_attr[i].i,
+ out_attr[Tag_RISCV_priv_spec].i,
+ out_attr[Tag_RISCV_priv_spec_minor].i,
+ out_attr[i].i);
result = FALSE;
}
break;
+
case Tag_RISCV_unaligned_access:
out_attr[i].i |= in_attr[i].i;
break;
+
case Tag_RISCV_stack_align:
if (out_attr[i].i == 0)
out_attr[i].i = in_attr[i].i;
@@ -3069,6 +3104,7 @@ riscv_merge_attributes (bfd *ibfd, struct bfd_link_info *info)
result = FALSE;
}
break;
+
default:
result &= _bfd_elf_merge_unknown_attribute_low (ibfd, obfd, i);
}