diff options
author | Tom Tromey <tom@tromey.com> | 2017-10-07 18:23:36 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2017-10-12 15:39:24 -0600 |
commit | f7b7ed97a23e2bf4a2ec27bef0fe0af55a080a94 (patch) | |
tree | acc18cc6b1f6d80ac75fa05c72204683b2940b03 /gdb/prologue-value.h | |
parent | 04ec7890fccfa5ddd9cc92961a4df58957ca181b (diff) | |
download | gdb-f7b7ed97a23e2bf4a2ec27bef0fe0af55a080a94.zip gdb-f7b7ed97a23e2bf4a2ec27bef0fe0af55a080a94.tar.gz gdb-f7b7ed97a23e2bf4a2ec27bef0fe0af55a080a94.tar.bz2 |
C++-ify prologue-value's pv_area
This patch is an initial C++-ification of pv_area, from
prologue-value. It turns pv_area into a class with a constructor and
destructor; renames the data members; and changes various functions to
be member functions. This allows the removal of
make_cleanup_free_pv_area.
gdb/ChangeLog
2017-10-12 Tom Tromey <tom@tromey.com>
* s390-linux-tdep.c (s390_store, s390_load)
(s390_check_for_saved, s390_analyze_prologue): Update.
* rx-tdep.c (check_for_saved, rx_analyze_prologue): Update.
* rl78-tdep.c (rl78_analyze_prologue, check_for_saved): Update.
* prologue-value.h (class pv_area): Move from prologue-value.c.
Change names of members. Add constructor, destructor, member
functions.
(make_pv_area, free_pv_area, make_cleanup_free_pv_area)
(pv_area_store, pv_area_fetch, pv_area_store_would_trash)
(pv_area_fetch, pv_area_scan): Don't declare.
* prologue-value.c (struct pv_area::area_entry): Now member of
pv_area.
(struct pv_area): Move to prologue-value.h.
(pv_area::pv_area): Rename from make_pv_area.
(pv_area::~pv_area): Rename from free_pv_area.
(do_free_pv_area_cleanup, make_cleanup_free_pv_area): Remove.
(clear_entries, find_entry, overlaps, store_would_trash, store)
(fetch, find_reg, scan): Now member of pv_area.
Remove "area" argument. Update.
* msp430-tdep.c (check_for_saved, msp430_analyze_prologue):
Update.
* mn10300-tdep.c (push_reg, check_for_saved)
(mn10300_analyze_prologue): Update.
* mep-tdep.c (is_arg_spill, check_for_saved)
(mep_analyze_prologue): Update.
* m32c-tdep.c (m32c_pv_push, m32c_srcdest_fetch)
(m32c_srcdest_store, m32c_pv_enter, m32c_is_arg_spill)
(m32c_is_struct_return, m32c_analyze_prologue): Update.
* arm-tdep.c (thumb_analyze_prologue, arm_analyze_prologue):
Update.
* arc-tdep.c (arc_is_in_prologue, arc_analyze_prologue): Update.
* aarch64-tdep.c (aarch64_analyze_prologue): Update.
Diffstat (limited to 'gdb/prologue-value.h')
-rw-r--r-- | gdb/prologue-value.h | 183 |
1 files changed, 105 insertions, 78 deletions
diff --git a/gdb/prologue-value.h b/gdb/prologue-value.h index e09c886..e3004aa 100644 --- a/gdb/prologue-value.h +++ b/gdb/prologue-value.h @@ -221,83 +221,110 @@ enum pv_boolean pv_is_array_ref (pv_t addr, CORE_ADDR size, int *i); -/* A 'struct pv_area' keeps track of values stored in a particular - region of memory. */ -struct pv_area; - -/* Create a new area, tracking stores relative to the original value - of BASE_REG. If BASE_REG is SP, then this effectively records the - contents of the stack frame: the original value of the SP is the - frame's CFA, or some constant offset from it. - - Stores to constant addresses, unknown addresses, or to addresses - relative to registers other than BASE_REG will trash this area; see - pv_area_store_would_trash. - - To check whether a pointer refers to this area, only the low - ADDR_BIT bits will be compared. */ -struct pv_area *make_pv_area (int base_reg, int addr_bit); - -/* Free AREA. */ -void free_pv_area (struct pv_area *area); - - -/* Register a cleanup to free AREA. */ -struct cleanup *make_cleanup_free_pv_area (struct pv_area *area); - - -/* Store the SIZE-byte value VALUE at ADDR in AREA. - - If ADDR is not relative to the same base register we used in - creating AREA, then we can't tell which values here the stored - value might overlap, and we'll have to mark everything as - unknown. */ -void pv_area_store (struct pv_area *area, - pv_t addr, - CORE_ADDR size, - pv_t value); - -/* Return the SIZE-byte value at ADDR in AREA. This may return - pv_unknown (). */ -pv_t pv_area_fetch (struct pv_area *area, pv_t addr, CORE_ADDR size); - -/* Return true if storing to address ADDR in AREA would force us to - mark the contents of the entire area as unknown. This could happen - if, say, ADDR is unknown, since we could be storing anywhere. Or, - it could happen if ADDR is relative to a different register than - the other stores base register, since we don't know the relative - values of the two registers. - - If you've reached such a store, it may be better to simply stop the - prologue analysis, and return the information you've gathered, - instead of losing all that information, most of which is probably - okay. */ -int pv_area_store_would_trash (struct pv_area *area, pv_t addr); - - -/* Search AREA for the original value of REGISTER. If we can't find - it, return zero; if we can find it, return a non-zero value, and if - OFFSET_P is non-zero, set *OFFSET_P to the register's offset within - AREA. GDBARCH is the architecture of which REGISTER is a member. - - In the worst case, this takes time proportional to the number of - items stored in AREA. If you plan to gather a lot of information - about registers saved in AREA, consider calling pv_area_scan - instead, and collecting all your information in one pass. */ -int pv_area_find_reg (struct pv_area *area, - struct gdbarch *gdbarch, - int reg, - CORE_ADDR *offset_p); - - -/* For every part of AREA whose value we know, apply FUNC to CLOSURE, - the value's address, its size, and the value itself. */ -void pv_area_scan (struct pv_area *area, - void (*func) (void *closure, - pv_t addr, - CORE_ADDR size, - pv_t value), - void *closure); - +/* A 'pv_area' keeps track of values stored in a particular region of + memory. */ +class pv_area +{ +public: + + /* Create a new area, tracking stores relative to the original value + of BASE_REG. If BASE_REG is SP, then this effectively records the + contents of the stack frame: the original value of the SP is the + frame's CFA, or some constant offset from it. + + Stores to constant addresses, unknown addresses, or to addresses + relative to registers other than BASE_REG will trash this area; see + pv_area::store_would_trash. + + To check whether a pointer refers to this area, only the low + ADDR_BIT bits will be compared. */ + pv_area (int base_reg, int addr_bit); + + ~pv_area (); + + DISABLE_COPY_AND_ASSIGN (pv_area); + + /* Store the SIZE-byte value VALUE at ADDR in AREA. + + If ADDR is not relative to the same base register we used in + creating AREA, then we can't tell which values here the stored + value might overlap, and we'll have to mark everything as + unknown. */ + void store (pv_t addr, + CORE_ADDR size, + pv_t value); + + /* Return the SIZE-byte value at ADDR in AREA. This may return + pv_unknown (). */ + pv_t fetch (pv_t addr, CORE_ADDR size); + + /* Return true if storing to address ADDR in AREA would force us to + mark the contents of the entire area as unknown. This could happen + if, say, ADDR is unknown, since we could be storing anywhere. Or, + it could happen if ADDR is relative to a different register than + the other stores base register, since we don't know the relative + values of the two registers. + + If you've reached such a store, it may be better to simply stop the + prologue analysis, and return the information you've gathered, + instead of losing all that information, most of which is probably + okay. */ + int store_would_trash (pv_t addr); + + /* Search AREA for the original value of REGISTER. If we can't find + it, return zero; if we can find it, return a non-zero value, and if + OFFSET_P is non-zero, set *OFFSET_P to the register's offset within + AREA. GDBARCH is the architecture of which REGISTER is a member. + + In the worst case, this takes time proportional to the number of + items stored in AREA. If you plan to gather a lot of information + about registers saved in AREA, consider calling pv_area::scan + instead, and collecting all your information in one pass. */ + int find_reg (struct gdbarch *gdbarch, int reg, CORE_ADDR *offset_p); + + + /* For every part of AREA whose value we know, apply FUNC to CLOSURE, + the value's address, its size, and the value itself. */ + void scan (void (*func) (void *closure, + pv_t addr, + CORE_ADDR size, + pv_t value), + void *closure); + +private: + + struct area_entry; + + /* Delete all entries from AREA. */ + void clear_entries (); + + /* Return a pointer to the first entry we hit in AREA starting at + OFFSET and going forward. + + This may return zero, if AREA has no entries. + + And since the entries are a ring, this may return an entry that + entirely precedes OFFSET. This is the correct behavior: depending + on the sizes involved, we could still overlap such an area, with + wrap-around. */ + struct area_entry *find_entry (CORE_ADDR offset); + + /* Return non-zero if the SIZE bytes at OFFSET would overlap ENTRY; + return zero otherwise. AREA is the area to which ENTRY belongs. */ + int overlaps (struct area_entry *entry, + CORE_ADDR offset, + CORE_ADDR size); + + /* This area's base register. */ + int m_base_reg; + + /* The mask to apply to addresses, to make the wrap-around happen at + the right place. */ + CORE_ADDR m_addr_mask; + + /* An element of the doubly-linked ring of entries, or zero if we + have none. */ + struct area_entry *m_entry; +}; #endif /* PROLOGUE_VALUE_H */ |