RISC-V: Fix the merged orders of Z* extension for linker.
authorNelson Chu <nelson.chu@sifive.com>
Mon, 4 Jan 2021 02:12:45 +0000 (10:12 +0800)
committerNelson Chu <nelson.chu@sifive.com>
Mon, 4 Jan 2021 03:17:33 +0000 (11:17 +0800)
Similar to the commit 6729e2c2af2bd94408430734316597843718a484,
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.

bfd/ChangeLog
bfd/elfnn-riscv.c
bfd/elfxx-riscv.c
bfd/elfxx-riscv.h

index a72e811b1c9be2cf803ece69a6e4e0647d6c6179..a7cc3c8af3e40d483ae3b8197eb89b0d1c320acd 100644 (file)
@@ -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
index dff0d4da443c35e9ab0e1125247207ee36fb8f2c..047f31b4eac4c9b3b95ec69d7ec2ad6b3e576747 100644 (file)
@@ -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)
        {
index 101e27f8202b61b7a1d3c47b9a583ea7899c9f3b..d3b64720a5dc314d61f644270c8d514e66044d0b 100644 (file)
@@ -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')];
index 3a7c7b7f3ac84af402f9c4896851f0c934d1ef19..4d7a6dcf096b68e053c34dfd75e85abd384fe5f9 100644 (file)
@@ -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 *);