aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorNelson Chu <nelson@rivosinc.com>2025-03-13 10:31:36 +0800
committerNelson Chu <nelson@rivosinc.com>2025-03-18 12:16:27 +0800
commite4c9f0e6c3a665c0a711dc6bf74e37dfc370e28c (patch)
treed9cbd3444c027067b7439d8e10b5a1453f032791 /bfd
parent433ccc440b51673ed3fce85a8dedca24f16ccab2 (diff)
downloadbinutils-e4c9f0e6c3a665c0a711dc6bf74e37dfc370e28c.zip
binutils-e4c9f0e6c3a665c0a711dc6bf74e37dfc370e28c.tar.gz
binutils-e4c9f0e6c3a665c0a711dc6bf74e37dfc370e28c.tar.bz2
RISC-V: Avoid parsing arch string repeatedly for dis-assembler
Since we now always generate $x+isa for now, these would increase the dis-assemble time by parsing the same architecture string repeatedly. We already have `arch_str' field into `subset_list' to record the current architecture stirng, but it's only useful for assembler, since dis-assembler and linker don't need it before. Now for dis-assembler, we just need to update the `arch_str' after parsing the architecture stirng, and then avoid parsing repeatedly if the strings are the same.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/elfnn-riscv.c3
-rw-r--r--bfd/elfxx-riscv.c9
-rw-r--r--bfd/elfxx-riscv.h2
3 files changed, 11 insertions, 3 deletions
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 873e268..1c494f5 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -4004,7 +4004,8 @@ riscv_merge_arch_attr_info (bfd *ibfd, char *in_arch, char *out_arch)
/* Free the previous merged_arch_str which called xmalloc. */
free (merged_arch_str);
- merged_arch_str = riscv_arch_str (ARCH_SIZE, &merged_subsets);
+ merged_arch_str = riscv_arch_str (ARCH_SIZE, &merged_subsets,
+ false/* update */);
/* Release the subset lists. */
riscv_release_subset_list (&in_subsets);
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index ffcf32b..72610dc 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -2328,7 +2328,7 @@ riscv_arch_str1 (riscv_subset_t *subset,
/* Convert subset information into string with explicit versions. */
char *
-riscv_arch_str (unsigned xlen, const riscv_subset_list_t *subset)
+riscv_arch_str (unsigned xlen, riscv_subset_list_t *subset, bool update)
{
size_t arch_str_len = riscv_estimate_arch_strlen (subset);
char *attr_str = xmalloc (arch_str_len);
@@ -2339,6 +2339,13 @@ riscv_arch_str (unsigned xlen, const riscv_subset_list_t *subset)
riscv_arch_str1 (subset->head, attr_str, buf, arch_str_len);
free (buf);
+ if (update)
+ {
+ if (subset->arch_str != NULL)
+ free ((void *) subset->arch_str);
+ subset->arch_str = attr_str;
+ }
+
return attr_str;
}
diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h
index 19e04ad..1ce682a 100644
--- a/bfd/elfxx-riscv.h
+++ b/bfd/elfxx-riscv.h
@@ -98,7 +98,7 @@ extern void
riscv_release_subset_list (riscv_subset_list_t *);
extern char *
-riscv_arch_str (unsigned, const riscv_subset_list_t *);
+riscv_arch_str (unsigned, riscv_subset_list_t *, bool);
extern size_t
riscv_estimate_digit (unsigned);