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.
This commit is contained in:
parent
e9cf3691bf
commit
4c0e540e47
@ -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
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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')];
|
||||
|
||||
@ -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…
Reference in New Issue
Block a user