aboutsummaryrefslogtreecommitdiff
path: root/gdb/arch
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/arch')
-rw-r--r--gdb/arch/riscv.c31
-rw-r--r--gdb/arch/riscv.h9
2 files changed, 40 insertions, 0 deletions
diff --git a/gdb/arch/riscv.c b/gdb/arch/riscv.c
index cb715fa..81fd2f2 100644
--- a/gdb/arch/riscv.c
+++ b/gdb/arch/riscv.c
@@ -18,17 +18,45 @@
#include "common-defs.h"
#include "riscv.h"
#include <stdlib.h>
+#include <unordered_map>
#include "../features/riscv/32bit-cpu.c"
#include "../features/riscv/64bit-cpu.c"
#include "../features/riscv/32bit-fpu.c"
#include "../features/riscv/64bit-fpu.c"
+/* Wrapper used by std::unordered_map to generate hash for feature set. */
+struct riscv_gdbarch_features_hasher
+{
+ std::size_t
+ operator() (const riscv_gdbarch_features &features) const noexcept
+ {
+ return features.hash ();
+ }
+};
+
+/* Cache of previously seen target descriptions, indexed by the feature set
+ that created them. */
+static std::unordered_map<riscv_gdbarch_features,
+ target_desc *,
+ riscv_gdbarch_features_hasher> riscv_tdesc_cache;
+
/* See arch/riscv.h. */
const target_desc *
riscv_create_target_description (struct riscv_gdbarch_features features)
{
+ /* Have we seen this feature set before? If we have return the same
+ target description. GDB expects that if two target descriptions are
+ the same (in content terms) then they will actually be the same
+ instance. This is important when trying to lookup gdbarch objects as
+ GDBARCH_LIST_LOOKUP_BY_INFO performs a pointer comparison on target
+ descriptions to find candidate gdbarch objects. */
+ const auto it = riscv_tdesc_cache.find (features);
+ if (it != riscv_tdesc_cache.end ())
+ return it->second;
+
+ /* Now we should create a new target description. */
target_desc *tdesc = allocate_target_description ();
#ifndef IN_PROCESS_AGENT
@@ -65,5 +93,8 @@ riscv_create_target_description (struct riscv_gdbarch_features features)
else if (features.flen == 8)
regnum = create_feature_riscv_64bit_fpu (tdesc, regnum);
+ /* Add to the cache. */
+ riscv_tdesc_cache.emplace (features, tdesc);
+
return tdesc;
}
diff --git a/gdb/arch/riscv.h b/gdb/arch/riscv.h
index be41828e..79f5ec6 100644
--- a/gdb/arch/riscv.h
+++ b/gdb/arch/riscv.h
@@ -66,6 +66,15 @@ struct riscv_gdbarch_features
{
return !((*this) == rhs);
}
+
+ /* Used by std::unordered_map to hash feature sets. */
+ std::size_t hash () const noexcept
+ {
+ std::size_t val = ((xlen & 0x1f) << 6
+ | (flen & 0x1f) << 1
+ | (hw_float_abi ? 1 : 0));
+ return val;
+ }
};
/* Create and return a target description that is compatible with