diff options
-rw-r--r-- | gdb/ChangeLog | 27 | ||||
-rw-r--r-- | gdb/arch/riscv.c | 69 | ||||
-rw-r--r-- | gdb/arch/riscv.h | 26 | ||||
-rw-r--r-- | gdb/nat/riscv-linux-tdesc.c | 8 | ||||
-rw-r--r-- | gdb/nat/riscv-linux-tdesc.h | 7 | ||||
-rw-r--r-- | gdb/riscv-linux-nat.c | 4 | ||||
-rw-r--r-- | gdb/riscv-tdep.c | 2 |
7 files changed, 103 insertions, 40 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9d29568..144fd4f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,30 @@ +2020-02-19 Andrew Burgess <andrew.burgess@embecosm.com> + + * arch/riscv.c (struct riscv_gdbarch_features_hasher): Only define + if GDBSERVER is not defined. + (riscv_tdesc_cache): Likewise, also store const target_desc. + (STATIC_IN_GDB): Define. + (riscv_create_target_description): Update declaration with + STATIC_IN_GDB. + (riscv_lookup_target_description): New function, only define if + GDBSERVER is not defined. + * arch/riscv.h (riscv_create_target_description): Declare only + when GDBSERVER is defined. + (riscv_lookup_target_description): New declaration when GDBSERVER + is not defined. + * nat/riscv-linux-tdesc.c (riscv_linux_read_description): Rename to... + (riscv_linux_read_features): ...this, and return + riscv_gdbarch_features instead of target_desc. + * nat/riscv-linux-tdesc.h: Include 'arch/riscv.h'. + (riscv_linux_read_description): Rename to... + (riscv_linux_read_features): ...this. + * riscv-linux-nat.c (riscv_linux_nat_target::read_description): + Update to use riscv_gdbarch_features and + riscv_lookup_target_description. + * riscv-tdep.c (riscv_find_default_target_description): Use + riscv_lookup_target_description instead of + riscv_create_target_description. + 2020-02-18 Simon Marchi <simon.marchi@efficios.com> * valprint.c (generic_val_print_enum_1): When printing a flag diff --git a/gdb/arch/riscv.c b/gdb/arch/riscv.c index a3ab8a9..a02c18b 100644 --- a/gdb/arch/riscv.c +++ b/gdb/arch/riscv.c @@ -25,37 +25,17 @@ #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; +#ifndef GDBSERVER +#define STATIC_IN_GDB static +#else +#define STATIC_IN_GDB +#endif /* See arch/riscv.h. */ -const target_desc * -riscv_create_target_description (struct riscv_gdbarch_features features) +STATIC_IN_GDB target_desc * +riscv_create_target_description (const 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 (); @@ -93,8 +73,43 @@ riscv_create_target_description (struct riscv_gdbarch_features features) else if (features.flen == 8) regnum = create_feature_riscv_64bit_fpu (tdesc, regnum); + return tdesc; +} + +#ifndef GDBSERVER + +/* 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, + const target_desc *, + riscv_gdbarch_features_hasher> riscv_tdesc_cache; + +/* See arch/riscv.h. */ + +const target_desc * +riscv_lookup_target_description (const struct riscv_gdbarch_features features) +{ + /* Lookup in the cache. */ + const auto it = riscv_tdesc_cache.find (features); + if (it != riscv_tdesc_cache.end ()) + return it->second; + + target_desc *tdesc = riscv_create_target_description (features); + /* Add to the cache. */ riscv_tdesc_cache.emplace (features, tdesc); return tdesc; } + +#endif /* !GDBSERVER */ diff --git a/gdb/arch/riscv.h b/gdb/arch/riscv.h index 016a5fc..d40862c 100644 --- a/gdb/arch/riscv.h +++ b/gdb/arch/riscv.h @@ -66,10 +66,28 @@ struct riscv_gdbarch_features } }; -/* Create and return a target description that is compatible with - FEATURES. */ +#ifdef GDBSERVER + +/* Create and return a target description that is compatible with FEATURES. + This is only used directly from the gdbserver where the created target + description is modified after it is return. */ + +target_desc *riscv_create_target_description + (const struct riscv_gdbarch_features features); + +#else + +/* Lookup an already existing target description matching FEATURES, or + create a new target description if this is the first time we have seen + FEATURES. For the same FEATURES the same target_desc is always + returned. 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 target_desc *riscv_lookup_target_description + (const struct riscv_gdbarch_features features); + +#endif /* GDBSERVER */ -const target_desc *riscv_create_target_description - (struct riscv_gdbarch_features features); #endif /* ARCH_RISCV_H */ diff --git a/gdb/nat/riscv-linux-tdesc.c b/gdb/nat/riscv-linux-tdesc.c index 1b625cf..3220725 100644 --- a/gdb/nat/riscv-linux-tdesc.c +++ b/gdb/nat/riscv-linux-tdesc.c @@ -31,10 +31,10 @@ # define NFPREG 33 #endif -/* Determine XLEN and FLEN and return a corresponding target description. */ +/* See nat/riscv-linux-tdesc.h. */ -const struct target_desc * -riscv_linux_read_description (int tid) +struct riscv_gdbarch_features +riscv_linux_read_features (int tid) { struct riscv_gdbarch_features features; elf_fpregset_t regs; @@ -79,5 +79,5 @@ riscv_linux_read_description (int tid) break; } - return riscv_create_target_description (features); + return features; } diff --git a/gdb/nat/riscv-linux-tdesc.h b/gdb/nat/riscv-linux-tdesc.h index 9b57a9e..e9ee64a 100644 --- a/gdb/nat/riscv-linux-tdesc.h +++ b/gdb/nat/riscv-linux-tdesc.h @@ -19,9 +19,10 @@ #ifndef NAT_RISCV_LINUX_TDESC_H #define NAT_RISCV_LINUX_TDESC_H -struct target_desc; +#include "arch/riscv.h" -/* Return a target description for the LWP identified by TID. */ -const struct target_desc *riscv_linux_read_description (int tid); +/* Determine XLEN and FLEN for the LWP identified by TID, and return a + corresponding features object. */ +struct riscv_gdbarch_features riscv_linux_read_features (int tid); #endif /* NAT_RISCV_LINUX_TDESC_H */ diff --git a/gdb/riscv-linux-nat.c b/gdb/riscv-linux-nat.c index 2622f1b..4f78dfd 100644 --- a/gdb/riscv-linux-nat.c +++ b/gdb/riscv-linux-nat.c @@ -201,7 +201,9 @@ fill_fpregset (const struct regcache *regcache, prfpregset_t *fpregs, const struct target_desc * riscv_linux_nat_target::read_description () { - return riscv_linux_read_description (inferior_ptid.lwp ()); + const struct riscv_gdbarch_features features + = riscv_linux_read_features (inferior_ptid.lwp ()); + return riscv_lookup_target_description (features); } /* Fetch REGNUM (or all registers if REGNUM == -1) from the target diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c index a14ef4d..0515729 100644 --- a/gdb/riscv-tdep.c +++ b/gdb/riscv-tdep.c @@ -2973,7 +2973,7 @@ riscv_find_default_target_description (const struct gdbarch_info info) features.xlen = 8; /* Now build a target description based on the feature set. */ - return riscv_create_target_description (features); + return riscv_lookup_target_description (features); } /* All of the registers in REG_SET are checked for in FEATURE, TDESC_DATA |