/* Interface to prologue value handling for GDB.
   Copyright (C) 2003-2021 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef PROLOGUE_VALUE_H
#define PROLOGUE_VALUE_H

/* What sort of value is this?  This determines the interpretation
   of subsequent fields.  */
enum prologue_value_kind
{
  /* We don't know anything about the value.  This is also used for
     values we could have kept track of, when doing so would have
     been too complex and we don't want to bother.  The bottom of
     our lattice.  */
  pvk_unknown,

  /* A known constant.  K is its value.  */
  pvk_constant,

  /* The value that register REG originally had *UPON ENTRY TO THE
     FUNCTION*, plus K.  If K is zero, this means, obviously, just
     the value REG had upon entry to the function.  REG is a GDB
     register number.  Before we start interpreting, we initialize
     every register R to { pvk_register, R, 0 }.  */
  pvk_register,
};

/* When we analyze a prologue, we're really doing 'abstract
   interpretation' or 'pseudo-evaluation': running the function's code
   in simulation, but using conservative approximations of the values
   it would have when it actually runs.  For example, if our function
   starts with the instruction:

      addi r1, 42     # add 42 to r1

   we don't know exactly what value will be in r1 after executing this
   instruction, but we do know it'll be 42 greater than its original
   value.

   If we then see an instruction like:

      addi r1, 22     # add 22 to r1

   we still don't know what r1's value is, but again, we can say it is
   now 64 greater than its original value.

   If the next instruction were:

      mov r2, r1      # set r2 to r1's value

   then we can say that r2's value is now the original value of r1
   plus 64.

   It's common for prologues to save registers on the stack, so we'll
   need to track the values of stack frame slots, as well as the
   registers.  So after an instruction like this:

      mov (fp+4), r2

   then we'd know that the stack slot four bytes above the frame
   pointer holds the original value of r1 plus 64.

   And so on.

   Of course, this can only go so far before it gets unreasonable.  If
   we wanted to be able to say anything about the value of r1 after
   the instruction:

      xor r1, r3      # exclusive-or r1 and r3, place result in r1

   then things would get pretty complex.  But remember, we're just
   doing a conservative approximation; if exclusive-or instructions
   aren't relevant to prologues, we can just say r1's value is now
   'unknown'.  We can ignore things that are too complex, if that loss
   of information is acceptable for our application.

   So when I say "conservative approximation" here, what I mean is an
   approximation that is either accurate, or marked "unknown", but
   never inaccurate.

   Once you've reached the current PC, or an instruction that you
   don't know how to simulate, you stop.  Now you can examine the
   state of the registers and stack slots you've kept track of.

   - To see how large your stack frame is, just check the value of the
     stack pointer register; if it's the original value of the SP
     minus a constant, then that constant is the stack frame's size.
     If the SP's value has been marked as 'unknown', then that means
     the prologue has done something too complex for us to track, and
     we don't know the frame size.

   - To see where we've saved the previous frame's registers, we just
     search the values we've tracked --- stack slots, usually, but
     registers, too, if you want --- for something equal to the
     register's original value.  If the ABI suggests a standard place
     to save a given register, then we can check there first, but
     really, anything that will get us back the original value will
     probably work.

   Sure, this takes some work.  But prologue analyzers aren't
   quick-and-simple pattern patching to recognize a few fixed prologue
   forms any more; they're big, hairy functions.  Along with inferior
   function calls, prologue analysis accounts for a substantial
   portion of the time needed to stabilize a GDB port.  So I think
   it's worthwhile to look for an approach that will be easier to
   understand and maintain.  In the approach used here:

   - It's easier to see that the analyzer is correct: you just see
     whether the analyzer properly (albeit conservatively) simulates
     the effect of each instruction.

   - It's easier to extend the analyzer: you can add support for new
     instructions, and know that you haven't broken anything that
     wasn't already broken before.

   - It's orthogonal: to gather new information, you don't need to
     complicate the code for each instruction.  As long as your domain
     of conservative values is already detailed enough to tell you
     what you need, then all the existing instruction simulations are
     already gathering the right data for you.

   A 'struct prologue_value' is a conservative approximation of the
   real value the register or stack slot will have.  */

struct prologue_value {

  /* What sort of value is this?  This determines the interpretation
     of subsequent fields.  */
  enum prologue_value_kind kind;

  /* The meanings of the following fields depend on 'kind'; see the
     comments for the specific 'kind' values.  */
  int reg;
  CORE_ADDR k;
};

typedef struct prologue_value pv_t;


/* Return the unknown prologue value --- { pvk_unknown, ?, ? }.  */
pv_t pv_unknown (void);

/* Return the prologue value representing the constant K.  */
pv_t pv_constant (CORE_ADDR k);

/* Return the prologue value representing the original value of
   register REG, plus the constant K.  */
pv_t pv_register (int reg, CORE_ADDR k);


/* Return conservative approximations of the results of the following
   operations.  */
pv_t pv_add (pv_t a, pv_t b);               /* a + b */
pv_t pv_add_constant (pv_t v, CORE_ADDR k); /* a + k */
pv_t pv_subtract (pv_t a, pv_t b);          /* a - b */
pv_t pv_logical_and (pv_t a, pv_t b);       /* a & b */


/* Return non-zero iff A and B are identical expressions.

   This is not the same as asking if the two values are equal; the
   result of such a comparison would have to be a pv_boolean, and
   asking whether two 'unknown' values were equal would give you
   pv_maybe.  Same for comparing, say, { pvk_register, R1, 0 } and {
   pvk_register, R2, 0}.

   Instead, this function asks whether the two representations are the
   same.  */
int pv_is_identical (pv_t a, pv_t b);


/* Return non-zero if A is known to be a constant.  */
int pv_is_constant (pv_t a);

/* Return non-zero if A is the original value of register number R
   plus some constant, zero otherwise.  */
int pv_is_register (pv_t a, int r);


/* Return non-zero if A is the original value of register R plus the
   constant K.  */
int pv_is_register_k (pv_t a, int r, CORE_ADDR k);

/* A conservative boolean type, including "maybe", when we can't
   figure out whether something is true or not.  */
enum pv_boolean {
  pv_maybe,
  pv_definite_yes,
  pv_definite_no,
};


/* Decide whether a reference to SIZE bytes at ADDR refers exactly to
   an element of an array.  The array starts at ARRAY_ADDR, and has
   ARRAY_LEN values of ELT_SIZE bytes each.  If ADDR definitely does
   refer to an array element, set *I to the index of the referenced
   element in the array, and return pv_definite_yes.  If it definitely
   doesn't, return pv_definite_no.  If we can't tell, return pv_maybe.

   If the reference does touch the array, but doesn't fall exactly on
   an element boundary, or doesn't refer to the whole element, return
   pv_maybe.  */
enum pv_boolean pv_is_array_ref (pv_t addr, CORE_ADDR size,
				 pv_t array_addr, CORE_ADDR array_len,
				 CORE_ADDR elt_size,
				 int *i);


/* 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.  */
  bool 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.  */
  bool 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 */
