/* $Header$ */ #include #include "position.h" #include "scope.h" #include "symbol.h" #include "type.h" #include "message.h" int stack_offset; /* for up and down commands */ extern long pointer_size; extern t_addr *get_EM_regs(); /* Get the value of the symbol indicated by sym. Return 0 on failure, 1 on success. On success, 'buf' contains the value, and 'AB' may contain the parameters of the procedure invocation containing sym. For both of these, storage is allocated by Malloc; this storage must be freed by caller (I don't like this any more than you do, but caller does not know sizes). */ int get_value(sym, buf, AB) register p_symbol sym; char **buf, **AB; { p_type tp = sym->sy_type; long size = tp->ty_size; int retval = 0; t_addr *EM_regs; int i; p_scope sc, symsc; *buf = 0; *AB = 0; switch(sym->sy_class) { case VAR: /* exists if child exists; nm_value contains addres */ *buf = Malloc((unsigned) size); if (get_bytes(size, (t_addr) sym->sy_name.nm_value, *buf)) { retval = 1; } break; case VARPAR: case LOCVAR: /* first find the stack frame in which it resides */ symsc = base_scope(sym->sy_scope); /* now symsc contains the scope where the storage for sym is allocated. Now find it on the stack of child. */ i = stack_offset; for (;;) { sc = 0; if (! (EM_regs = get_EM_regs(i++))) { /* no child? */ break; } if (! EM_regs[AB_OFF]) { /* no more frames */ break; } sc = base_scope(get_scope_from_addr(EM_regs[PC_OFF])); if (! sc || sc->sc_start > EM_regs[PC_OFF]) { sc = 0; break; } if (sc == symsc) break; /* found it */ } if (! sc) break; /* not found */ if (sym->sy_class == LOCVAR) { /* Either local variable or value parameter */ *buf = Malloc((unsigned) size); if (get_bytes(size, EM_regs[sym->sy_name.nm_value < 0 ? LB_OFF : AB_OFF ] + (t_addr) sym->sy_name.nm_value, *buf)) { retval = 1; } break; } /* If we get here, we have a var parameter. Get the parameters of the current procedure invocation. */ { p_type proctype = sc->sc_definedby->sy_type; size = proctype->ty_nbparams; if (has_static_link(sc)) size += pointer_size; *AB = Malloc((unsigned) size); if (! get_bytes(size, EM_regs[AB_OFF], *AB)) { break; } if ((size = tp->ty_size) == 0) { size = compute_size(tp, *AB); } } *buf = Malloc((unsigned) size); if (get_bytes(size, (t_addr) BUFTOA(*AB+sym->sy_name.nm_value), *buf)) { retval = 1; } break; } if (retval == 0) { if (*buf) free(*buf); if (*AB) free(*AB); *buf = 0; *AB = 0; } return retval; }