| /* Definitions for expressions designed to be executed on the agent | 
 |    Copyright (C) 1998-2022 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 AX_H | 
 | #define AX_H | 
 |  | 
 | /* It's sometimes useful to be able to debug programs that you can't | 
 |    really stop for more than a fraction of a second.  To this end, the | 
 |    user can specify a tracepoint (like a breakpoint, but you don't | 
 |    stop at it), and specify a bunch of expressions to record the | 
 |    values of when that tracepoint is reached.  As the program runs, | 
 |    GDB collects the values.  At any point (possibly while values are | 
 |    still being collected), the user can display the collected values. | 
 |  | 
 |    This is used with remote debugging; we don't really support it on | 
 |    native configurations. | 
 |  | 
 |    This means that expressions are being evaluated by the remote agent, | 
 |    which doesn't have any access to the symbol table information, and | 
 |    needs to be small and simple. | 
 |  | 
 |    The agent_expr routines and datatypes are a bytecode language | 
 |    designed to be executed by the agent.  Agent expressions work in | 
 |    terms of fixed-width values, operators, memory references, and | 
 |    register references.  You can evaluate a agent expression just given | 
 |    a bunch of memory and register values to sniff at; you don't need | 
 |    any symbolic information like variable names, types, etc. | 
 |  | 
 |    GDB translates source expressions, whose meaning depends on | 
 |    symbolic information, into agent bytecode expressions, whose meaning | 
 |    is independent of symbolic information.  This means the agent can | 
 |    evaluate them on the fly without reference to data only available | 
 |    to the host GDB.  */ | 
 |  | 
 |  | 
 | /* Different kinds of flaws an agent expression might have, as | 
 |    detected by ax_reqs.  */ | 
 | enum agent_flaws | 
 |   { | 
 |     agent_flaw_none = 0,	/* code is good */ | 
 |  | 
 |     /* There is an invalid instruction in the stream.  */ | 
 |     agent_flaw_bad_instruction, | 
 |  | 
 |     /* There is an incomplete instruction at the end of the expression.  */ | 
 |     agent_flaw_incomplete_instruction, | 
 |  | 
 |     /* ax_reqs was unable to prove that every jump target is to a | 
 |        valid offset.  Valid offsets are within the bounds of the | 
 |        expression, and to a valid instruction boundary.  */ | 
 |     agent_flaw_bad_jump, | 
 |  | 
 |     /* ax_reqs was unable to prove to its satisfaction that, for each | 
 |        jump target location, the stack will have the same height whether | 
 |        that location is reached via a jump or by straight execution.  */ | 
 |     agent_flaw_height_mismatch, | 
 |  | 
 |     /* ax_reqs was unable to prove that every instruction following | 
 |        an unconditional jump was the target of some other jump.  */ | 
 |     agent_flaw_hole | 
 |   }; | 
 |  | 
 | /* Agent expression data structures.  */ | 
 |  | 
 | /* A buffer containing a agent expression.  */ | 
 | struct agent_expr | 
 |   { | 
 |     /* Construct an empty agent expression.  */ | 
 |     explicit agent_expr (struct gdbarch *gdbarch, CORE_ADDR scope); | 
 |  | 
 |     ~agent_expr (); | 
 |  | 
 |     /* The bytes of the expression.  */ | 
 |     unsigned char *buf; | 
 |  | 
 |     /* The number of bytecode in the expression.  */ | 
 |     int len; | 
 |  | 
 |     /* Allocated space available currently.  */ | 
 |     int size; | 
 |  | 
 |     /* The target architecture assumed to be in effect.  */ | 
 |     struct gdbarch *gdbarch; | 
 |  | 
 |     /* The address to which the expression applies.  */ | 
 |     CORE_ADDR scope; | 
 |  | 
 |     /* If the following is not equal to agent_flaw_none, the rest of the | 
 |        information in this structure is suspect.  */ | 
 |     enum agent_flaws flaw; | 
 |  | 
 |     /* Number of elements left on stack at end; may be negative if expr | 
 |        only consumes elements.  */ | 
 |     int final_height; | 
 |  | 
 |     /* Maximum and minimum stack height, relative to initial height.  */ | 
 |     int max_height, min_height; | 
 |  | 
 |     /* Largest `ref' or `const' opcode used, in bits.  Zero means the | 
 |        expression has no such instructions.  */ | 
 |     int max_data_size; | 
 |  | 
 |     /* Bit vector of registers needed.  Register R is needed iff | 
 |  | 
 |        reg_mask[R / 8] & (1 << (R % 8)) | 
 |  | 
 |        is non-zero.  Note!  You may not assume that this bitmask is long | 
 |        enough to hold bits for all the registers of the machine; the | 
 |        agent expression code has no idea how many registers the machine | 
 |        has.  However, the bitmask is reg_mask_len bytes long, so the | 
 |        valid register numbers run from 0 to reg_mask_len * 8 - 1. | 
 |  | 
 |        Also note that this mask may contain registers that are needed | 
 |        for the original collection expression to work, but that are | 
 |        not referenced by any bytecode.  This could, for example, occur | 
 |        when collecting a local variable allocated to a register; the | 
 |        compiler sets the mask bit and skips generating a bytecode whose | 
 |        result is going to be discarded anyway. | 
 |     */ | 
 |     int reg_mask_len; | 
 |     unsigned char *reg_mask; | 
 |  | 
 |     /* For the data tracing facility, we need to insert `trace' bytecodes | 
 |        before each data fetch; this records all the memory that the | 
 |        expression touches in the course of evaluation, so that memory will | 
 |        be available when the user later tries to evaluate the expression | 
 |        in GDB. | 
 |  | 
 |        Setting the flag 'tracing' to non-zero enables the code that | 
 |        emits the trace bytecodes at the appropriate points.  */ | 
 |  | 
 |     unsigned int tracing : 1; | 
 |  | 
 |     /* This indicates that pointers to chars should get an added | 
 |        tracenz bytecode to record nonzero bytes, up to a length that | 
 |        is the value of trace_string.  */ | 
 |  | 
 |     int trace_string; | 
 |   }; | 
 |  | 
 | /* An agent_expr owning pointer.  */ | 
 | typedef std::unique_ptr<agent_expr> agent_expr_up; | 
 |  | 
 | /* The actual values of the various bytecode operations.  */ | 
 |  | 
 | enum agent_op | 
 |   { | 
 | #define DEFOP(NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED, VALUE)  \ | 
 |     aop_ ## NAME = VALUE, | 
 | #include "gdbsupport/ax.def" | 
 | #undef DEFOP | 
 |     aop_last | 
 |   }; | 
 |  | 
 |  | 
 |  | 
 | /* Functions for building expressions.  */ | 
 |  | 
 | /* Append a raw byte to EXPR.  */ | 
 | extern void ax_raw_byte (struct agent_expr *expr, gdb_byte byte); | 
 |  | 
 | /* Append a simple operator OP to EXPR.  */ | 
 | extern void ax_simple (struct agent_expr *EXPR, enum agent_op OP); | 
 |  | 
 | /* Append a pick operator to EXPR.  DEPTH is the stack item to pick, | 
 |    with 0 being top of stack.  */ | 
 | extern void ax_pick (struct agent_expr *EXPR, int DEPTH); | 
 |  | 
 | /* Append the floating-point prefix, for the next bytecode.  */ | 
 | #define ax_float(EXPR) (ax_simple ((EXPR), aop_float)) | 
 |  | 
 | /* Append a sign-extension instruction to EXPR, to extend an N-bit value.  */ | 
 | extern void ax_ext (struct agent_expr *EXPR, int N); | 
 |  | 
 | /* Append a zero-extension instruction to EXPR, to extend an N-bit value.  */ | 
 | extern void ax_zero_ext (struct agent_expr *EXPR, int N); | 
 |  | 
 | /* Append a trace_quick instruction to EXPR, to record N bytes.  */ | 
 | extern void ax_trace_quick (struct agent_expr *EXPR, int N); | 
 |  | 
 | /* Append a goto op to EXPR.  OP is the actual op (must be aop_goto or | 
 |    aop_if_goto).  We assume we don't know the target offset yet, | 
 |    because it's probably a forward branch, so we leave space in EXPR | 
 |    for the target, and return the offset in EXPR of that space, so we | 
 |    can backpatch it once we do know the target offset.  Use ax_label | 
 |    to do the backpatching.  */ | 
 | extern int ax_goto (struct agent_expr *EXPR, enum agent_op OP); | 
 |  | 
 | /* Suppose a given call to ax_goto returns some value PATCH.  When you | 
 |    know the offset TARGET that goto should jump to, call | 
 |    ax_label (EXPR, PATCH, TARGET) | 
 |    to patch TARGET into the ax_goto instruction.  */ | 
 | extern void ax_label (struct agent_expr *EXPR, int patch, int target); | 
 |  | 
 | /* Assemble code to push a constant on the stack.  */ | 
 | extern void ax_const_l (struct agent_expr *EXPR, LONGEST l); | 
 | extern void ax_const_d (struct agent_expr *EXPR, LONGEST d); | 
 |  | 
 | /* Assemble code to push the value of register number REG on the | 
 |    stack.  */ | 
 | extern void ax_reg (struct agent_expr *EXPR, int REG); | 
 |  | 
 | /* Add the given register to the register mask of the expression.  */ | 
 | extern void ax_reg_mask (struct agent_expr *ax, int reg); | 
 |  | 
 | /* Assemble code to operate on a trace state variable.  */ | 
 | extern void ax_tsv (struct agent_expr *expr, enum agent_op op, int num); | 
 |  | 
 | /* Append a string to the bytecode stream.  */ | 
 | extern void ax_string (struct agent_expr *x, const char *str, int slen); | 
 |  | 
 |  | 
 | /* Functions for printing out expressions, and otherwise debugging | 
 |    things.  */ | 
 |  | 
 | /* Disassemble the expression EXPR, writing to F.  */ | 
 | extern void ax_print (struct ui_file *f, struct agent_expr * EXPR); | 
 |  | 
 | /* An entry in the opcode map.  */ | 
 | struct aop_map | 
 |   { | 
 |  | 
 |     /* The name of the opcode.  Null means that this entry is not a | 
 |        valid opcode --- a hole in the opcode space.  */ | 
 |     const char *name; | 
 |  | 
 |     /* All opcodes take no operands from the bytecode stream, or take | 
 |        unsigned integers of various sizes.  If this is a positive number | 
 |        n, then the opcode is followed by an n-byte operand, which should | 
 |        be printed as an unsigned integer.  If this is zero, then the | 
 |        opcode takes no operands from the bytecode stream. | 
 |  | 
 |        If we get more complicated opcodes in the future, don't add other | 
 |        magic values of this; that's a crock.  Add an `enum encoding' | 
 |        field to this, or something like that.  */ | 
 |     int op_size; | 
 |  | 
 |     /* The size of the data operated upon, in bits, for bytecodes that | 
 |        care about that (ref and const).  Zero for all others.  */ | 
 |     int data_size; | 
 |  | 
 |     /* Number of stack elements consumed, and number produced.  */ | 
 |     int consumed, produced; | 
 |   }; | 
 |  | 
 | /* Map of the bytecodes, indexed by bytecode number.  */ | 
 | extern struct aop_map aop_map[]; | 
 |  | 
 | /* Given an agent expression AX, analyze and update its requirements.  */ | 
 |  | 
 | extern void ax_reqs (struct agent_expr *ax); | 
 |  | 
 | #endif /* AX_H */ |