Browse Source

RISC-V: Fix the merged orders of Z* extension for linker.

Similar to the commit 6729e2c2af,
we have to check the first char of the Z* extensions, to make
sure that they follow the order of the standard extensions.

bfd/
    * elfxx-riscv.c (riscv_compare_subsets): Removed static.
    * elfxx-riscv.h: Add declaration.
    * elfnn-riscv.c (riscv_merge_multi_letter_ext): Use
    riscv_compare_subsets to check the orders.
    (riscv_skip_prefix): Removed.
    (riscv_prefix_cmp): Removed.
binutils-2_36-branch
Nelson Chu 5 years ago
parent
commit
4c0e540e47
  1. 9
      bfd/ChangeLog
  2. 35
      bfd/elfnn-riscv.c
  3. 2
      bfd/elfxx-riscv.c
  4. 3
      bfd/elfxx-riscv.h

9
bfd/ChangeLog

@ -1,3 +1,12 @@
2021-01-04 Nelson Chu <nelson.chu@sifive.com>
* elfxx-riscv.c (riscv_compare_subsets): Removed static.
* elfxx-riscv.h: Add declaration.
* elfnn-riscv.c (riscv_merge_multi_letter_ext): Use
riscv_compare_subsets to check the orders.
(riscv_skip_prefix): Removed.
(riscv_prefix_cmp): Removed.
2021-01-04 Alan Modra <amodra@gmail.com>
PR 26741

35
bfd/elfnn-riscv.c

@ -3410,39 +3410,6 @@ riscv_merge_std_ext (bfd *ibfd,
return TRUE;
}
/* If C is a prefix class, then return the EXT string without the prefix.
Otherwise return the entire EXT string. */
static const char *
riscv_skip_prefix (const char *ext, riscv_isa_ext_class_t c)
{
switch (c)
{
case RV_ISA_CLASS_X: return &ext[1];
case RV_ISA_CLASS_S: return &ext[1];
case RV_ISA_CLASS_Z: return &ext[1];
default: return ext;
}
}
/* Compare prefixed extension names canonically. */
static int
riscv_prefix_cmp (const char *a, const char *b)
{
riscv_isa_ext_class_t ca = riscv_get_prefix_class (a);
riscv_isa_ext_class_t cb = riscv_get_prefix_class (b);
/* Extension name without prefix */
const char *anp = riscv_skip_prefix (a, ca);
const char *bnp = riscv_skip_prefix (b, cb);
if (ca == cb)
return strcasecmp (anp, bnp);
return (int)ca - (int)cb;
}
/* Merge multi letter extensions. PIN is a pointer to the head of the input
object subset list. Likewise for POUT and the output object. Return TRUE
on success and FALSE when a conflict is found. */
@ -3460,7 +3427,7 @@ riscv_merge_multi_letter_ext (bfd *ibfd,
while (in && out)
{
cmp = riscv_prefix_cmp (in->name, out->name);
cmp = riscv_compare_subsets (in->name, out->name);
if (cmp < 0)
{

2
bfd/elfxx-riscv.c

@ -1037,7 +1037,7 @@ static int riscv_ext_order[26] = {0};
or greater than zero if `subset2` is found, respectively, to be less
than, to match, or be greater than `subset1`. */
static int
int
riscv_compare_subsets (const char *subset1, const char *subset2)
{
int order1 = riscv_ext_order[(*subset1 - 'a')];

3
bfd/elfxx-riscv.h

@ -116,3 +116,6 @@ riscv_get_priv_spec_class_from_numbers (unsigned int,
extern const char *
riscv_get_priv_spec_name (enum riscv_priv_spec_class);
extern int
riscv_compare_subsets (const char *, const char *);

Loading…
Cancel
Save