aboutsummaryrefslogtreecommitdiff
path: root/gdb/prologue-value.h
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2017-10-07 18:23:36 -0600
committerTom Tromey <tom@tromey.com>2017-10-12 15:39:24 -0600
commitf7b7ed97a23e2bf4a2ec27bef0fe0af55a080a94 (patch)
treeacc18cc6b1f6d80ac75fa05c72204683b2940b03 /gdb/prologue-value.h
parent04ec7890fccfa5ddd9cc92961a4df58957ca181b (diff)
downloadgdb-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.h183
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 */