1
0
Files
irix-657m-src/irix/cmd/icrash/lib/libeval/variable.c
2022-09-29 17:59:04 +03:00

295 lines
6.3 KiB
C

#ident "$Header: /proj/irix6.5.7m/isms/irix/cmd/icrash/lib/libeval/RCS/variable.c,v 1.8 1999/05/25 19:21:38 tjm Exp $"
#define _KERNEL 1
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/param.h>
#include <libelf.h>
#include <dwarf.h>
#include <libdwarf.h>
#include <syms.h>
#include <sym.h>
#include <klib/klib.h>
#include "icrash.h"
/*
* make_variable()
*/
variable_t *
make_variable(char *name, char *exp, node_t *np, int flags)
{
variable_t *vp;
char *typestr;
k_uint_t value;
vp = (variable_t *)kl_alloc_block(sizeof(*vp), K_PERM);
vp->v_name = (char *)kl_alloc_block((strlen(name) + 1), K_PERM);
strcpy(vp->v_name, name);
vp->v_exp = (char *)kl_alloc_block((strlen(exp) + 1), K_PERM);
strcpy(vp->v_exp, exp);
vp->v_flags = flags;
if (np) {
typestr = node_to_typestr(np, 0);
if (np->flags & POINTER_FLAG) {
vp->v_typestr =
(char *)kl_alloc_block(strlen(typestr) + 19, K_PERM);
sprintf(vp->v_typestr, "%s0x%llx", typestr, np->value);
kl_free_block((k_ptr_t)typestr);
}
else if (np->flags & DWARF_TYPE_FLAG) {
int size, shft;
type_t *tp;
dw_type_info_t *t;
dw_die_t *d;
/* Get the type information
*/
t = (dw_type_info_t *)np->type->t_ptr;
if (t->t_type->d_tag == DW_TAG_typedef) {
d = t->t_actual_type;
}
else {
d = t->t_type;
}
size = t->t_byte_size;
if (d->d_tag == DW_TAG_base_type) {
vp->v_typestr =
(char *)kl_alloc_block(strlen(typestr) + 19, K_PERM);
if (np->flags & ADDRESS_FLAG) {
kl_get_block(np->address, size, &value, "value");
}
else {
switch (size) {
case 1:
*(unsigned char *)&value = np->value;
break;
case 2:
*(unsigned short *)&value = np->value;
break;
case 4:
*(unsigned int *)&value = np->value;
break;
case 8:
*(unsigned long long *)&value = np->value;
break;
}
}
if (shft = (8 - size)) {
value = value >> (shft * 8);
}
sprintf(vp->v_typestr, "%s%lld", typestr, value);
kl_free_block((k_ptr_t)typestr);
}
else {
/* We have a more complex type (e.g., struct, union, etc.).
* We need to be able to assign a variable to a complex
* type. For now though lets just convert it to a pointer
* to the type (using the address of the type as the pointer
* value).
*/
if (np->flags & ADDRESS_FLAG) {
char *c;
if (c = strchr(typestr, ')')) {
*c++ = '*';
*c++ = ')';
*c = 0;
value = np->address;
if (!(flags & V_PERM_NODE)) {
free_nodes(np);
np = (node_t*)NULL;
}
vp->v_node = np;
vp->v_typestr = (char *)kl_alloc_block(strlen(typestr)
+ 19, K_PERM);
vp->v_flags |= V_REC_STRUCT;
sprintf(vp->v_typestr, "%s0x%llx", typestr, value);
return(vp);
}
}
/* We have to return an error if there is no address
*/
kl_free_block((k_ptr_t)typestr);
if (!(flags & V_PERM_NODE)) {
free_nodes(np);
np = (node_t*)NULL;
}
free_variable(vp);
return((variable_t*)NULL);
}
}
else {
value = np->value;
vp->v_typestr =
(char *)kl_alloc_block(strlen(typestr) + 19, K_PERM);
sprintf(vp->v_typestr, "%s%lld", typestr, value);
}
if (!(flags & V_PERM_NODE)) {
free_nodes(np);
np = (node_t*)NULL;
}
vp->v_node = np;
}
return(vp);
}
/*
* clean_variable()
*/
void
clean_variable(variable_t *vp)
{
if (vp->v_name) {
kl_free_block((k_ptr_t)vp->v_name);
vp->v_name = 0;
}
if (vp->v_exp) {
kl_free_block((k_ptr_t)vp->v_exp);
vp->v_exp = 0;
}
if (vp->v_typestr) {
kl_free_block((k_ptr_t)vp->v_typestr);
vp->v_typestr = 0;
}
if (vp->v_node) {
free_nodes(vp->v_node);
vp->v_node = 0;
}
}
/*
* free_variable()
*/
void
free_variable(variable_t *vp)
{
if (vp->v_name) {
kl_free_block((k_ptr_t)vp->v_name);
}
if (vp->v_exp) {
kl_free_block((k_ptr_t)vp->v_exp);
}
if (vp->v_typestr) {
kl_free_block((k_ptr_t)vp->v_typestr);
}
if (vp->v_node) {
free_nodes(vp->v_node);
}
kl_free_block((k_ptr_t)vp);
}
/*
* init_variables()
*/
void
init_variables(vtab_t *vtab)
{
/* Setup default variables */
}
/*
* set_variable()
*/
int
set_variable(vtab_t *vtab, char *name, char *exp, node_t *np, int flags)
{
int e, ret;
variable_t *vp;
/* Check to see if there is already a variable for name.
* If there is, free it and make a new one.
*/
if (vp = find_variable(vtab, name, 0)) {
if (unset_variable(vtab, vp)) {
/* You can't unset V_PERM varialbes.
* XXX - There needs to be a way to reset the values of
* V_PERM variables. The key is to replace the value
* without changing the type (and testing to make sure
* the type is not changed).
*/
return(1);
}
}
vp = make_variable(name, exp, np, flags);
/* If we don't have a root node, make this node the root. Otherwis
* add it to the tree.
*/
if (!vtab->vt_root) {
vtab->vt_root = vp;
vtab->vt_count++;
return(0);
}
ret = insert_btnode((btnode_t **)&vtab->vt_root, (btnode_t *)vp, 0);
if (ret != -1) {
vtab->vt_count++;
return(0);
}
/* Free memory blocks?
*/
return(1);
}
/*
* unset_variable()
*/
int
unset_variable(vtab_t *vtab, variable_t *vp)
{
int ret;
if (vp->v_flags & V_PERM) {
/*ERROR*/
return(1);
}
ret = delete_btnode((btnode_t **)&vtab->vt_root, (btnode_t *)vp,
free_variable, 0);
if (ret != -1) {
vtab->vt_count--;
return(0);
}
return(1);
}
/*
* find_variable()
*/
variable_t *
find_variable(vtab_t *vtab, char *name, int type)
{
int max_depth;
variable_t *vp;
/* Search for name in the variable tree
*/
if (DEBUG(DC_EVAL, 3)) {
vp = (variable_t *)find_btnode((btnode_t *)vtab->vt_root,
name, &max_depth);
fprintf(KL_ERRORFP, "find_variable: varlist: name=%s (%s), "
"max_count=%d\n", name, (vp ? "FOUND" : "NOT FOUND"), max_depth);
}
else {
vp = (variable_t *)find_btnode((btnode_t *)vtab->vt_root,
name, (int *)NULL);
}
/* If we are looking for a specific type of variable (V_TYPEDEF,
* V_STRING, or V_COMMAND) check to make sure the variable we
* found matches the type flag.
*/
if (vp && type && !(vp->v_flags & type)) {
return((variable_t*)NULL);
}
return(vp);
}