|  | /* GDB-specific functions for operating on agent expressions | 
|  | Copyright (C) 1998-2023 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_GDB_H | 
|  | #define AX_GDB_H | 
|  |  | 
|  | #include "ax.h"  /* For agent_expr_up.  */ | 
|  |  | 
|  | struct expression; | 
|  |  | 
|  | /* Types and enums */ | 
|  |  | 
|  | /* GDB stores expressions in the form of a flattened tree (struct | 
|  | expression), so we just walk that tree and generate agent bytecodes | 
|  | as we go along. | 
|  |  | 
|  | GDB's normal evaluation uses struct value, which contains the | 
|  | expression's value as well as its address or the register it came | 
|  | from.  The `+' operator uses the value, whereas the unary `&' | 
|  | operator will use the address portion.  The `=' operator will use | 
|  | the address or register number of its left hand side. | 
|  |  | 
|  | The issues are different when generating agent bytecode.  Given a | 
|  | variable reference expression, we should not necessarily generate | 
|  | code to fetch its value, because the next operator may be `=' or | 
|  | unary `&'.  Instead, when we recurse on a subexpression, we | 
|  | indicate whether we want that expression to produce an lvalue or an | 
|  | rvalue.  If we requested an lvalue, then the recursive call tells | 
|  | us whether it generated code to compute an address on the stack, or | 
|  | whether the lvalue lives in a register. | 
|  |  | 
|  | The `axs' prefix here means `agent expression, static', because | 
|  | this is all static analysis of the expression, i.e. analysis which | 
|  | doesn't depend on the contents of memory and registers.  */ | 
|  |  | 
|  |  | 
|  | /* Different kinds of agent expression static values.  */ | 
|  | enum axs_lvalue_kind | 
|  | { | 
|  | /* We generated code to compute the subexpression's value. | 
|  | Constants and arithmetic operators yield this.  */ | 
|  | axs_rvalue, | 
|  |  | 
|  | /* We generated code to yield the subexpression's value's address on | 
|  | the top of the stack.  If the caller needs an rvalue, it should | 
|  | call require_rvalue to produce the rvalue from this address.  */ | 
|  | axs_lvalue_memory, | 
|  |  | 
|  | /* We didn't generate any code, and the stack is undisturbed, | 
|  | because the subexpression's value lives in a register; u.reg is | 
|  | the register number.  If the caller needs an rvalue, it should | 
|  | call require_rvalue to produce the rvalue from this register | 
|  | number.  */ | 
|  | axs_lvalue_register | 
|  | }; | 
|  |  | 
|  | /* Structure describing what we got from a subexpression.  Think of | 
|  | this as parallel to value.h's enum lval_type, except that we're | 
|  | describing a value which will exist when the expression is | 
|  | evaluated in the future, not a value we have in our hand.  */ | 
|  | struct axs_value | 
|  | { | 
|  | enum axs_lvalue_kind kind;	/* see above */ | 
|  |  | 
|  | /* The type of the subexpression.  Even if lvalue == axs_lvalue_memory, | 
|  | this is the type of the value itself; the value on the stack is a | 
|  | "pointer to" an object of this type.  */ | 
|  | struct type *type; | 
|  |  | 
|  | /* If nonzero, this is a variable which does not actually exist in | 
|  | the program.  */ | 
|  | char optimized_out; | 
|  |  | 
|  | union | 
|  | { | 
|  | /* if kind == axs_lvalue_register, this is the register number */ | 
|  | int reg; | 
|  | } | 
|  | u; | 
|  | }; | 
|  |  | 
|  |  | 
|  | /* Translating GDB expressions into agent expressions.  */ | 
|  |  | 
|  | /* Given a GDB expression EXPR, return bytecode to trace its value. | 
|  | The result will use the `trace' and `trace_quick' bytecodes to | 
|  | record the value of all memory touched by the expression, and leave | 
|  | no values on the stack.  The caller can then use the ax_reqs | 
|  | function to discover which registers the expression uses.  */ | 
|  | extern agent_expr_up gen_trace_for_expr (CORE_ADDR, struct expression *, | 
|  | int); | 
|  |  | 
|  | extern agent_expr_up gen_trace_for_var (CORE_ADDR, struct gdbarch *, | 
|  | struct symbol *, int); | 
|  |  | 
|  | extern agent_expr_up gen_trace_for_return_address (CORE_ADDR, | 
|  | struct gdbarch *, | 
|  | int); | 
|  |  | 
|  | extern agent_expr_up gen_eval_for_expr (CORE_ADDR, struct expression *); | 
|  |  | 
|  | extern void gen_expr (struct expression *exp, union exp_element **pc, | 
|  | struct agent_expr *ax, struct axs_value *value); | 
|  |  | 
|  | extern void require_rvalue (struct agent_expr *ax, struct axs_value *value); | 
|  |  | 
|  | extern agent_expr_up gen_printf (CORE_ADDR, struct gdbarch *, | 
|  | CORE_ADDR, LONGEST, const char *, int, | 
|  | int, struct expression **); | 
|  |  | 
|  | #endif /* AX_GDB_H */ |