Logo Search packages:      
Sourcecode: lcrash version File versions  Download package

sial_member.c

/*
 * Copyright 2001 Silicon Graphics, Inc. All rights reserved.
 */
#include <string.h>
#include "sial.h"
#include "sial.tab.h"

/* these function are used to access and set members in structs */

/* define a member access */
typedef struct mem {
      char *name; /* member name */
      int dir;    /* direct/indirect access */
      node_t*expr;      /* expression node_t*/
      stmember_t*stm;   /* associated member information */
      char *local;      /* local memory or ... */
      ull mem;    /* ... system memory access */
      srcpos_t p;
} mem;

void *
sial_adrval(value_t *v)
{
      switch(v->type.size) {

            case 1: return &v->v.uc;
            case 2: return &v->v.us;
            case 4: return &v->v.ul;
            case 8: return &v->v.ull;
      }
      sial_error("Oops sial_adrval");
      return 0;
}

/* some API secondary entry points */
void sial_member_soffset(member_t*m, int offset) { m->offset=offset; }
void sial_member_ssize(member_t*m, int size) { m->size=size; }
void sial_member_sfbit(member_t*m, int fbit) { m->fbit=fbit; }
void sial_member_snbits(member_t*m, int nbits) { m->nbits=nbits; }
void sial_member_sname(member_t*m, char *name) { m->name=sial_strdup(name); }


void
sial_setmem(mem *m, value_t *v)
{
stmember_t*stm=m->stm;

      /* check type compatibility. Ctypes should point to the same stinfo...*/
      if(stm->type.type != v->type.type
         /* pointer most point to the same type of object */
         || (v->type.type==V_REF && v->type.rtype != stm->type.rtype)
         /* ctypes should point to the same stinfo */
         || (is_ctype(v->type.type) && v->type.idx != stm->type.idx)) {

            sial_error("Incompatible types for assignment");

      }

      if(stm->m.nbits) {

            ull dvalue_t=0;

            if(v->type.type!=V_BASE) {

                  sial_error("Invalid assignment to bit field");

            }

            /* do the bit gymnastic */
            /* we need to create a ull that contain the current
               bit of teh destination */
            if(m->local) {

                  memmove(m->local+stm->m.offset, ((char*)(&dvalue_t))+8-stm->m.size, stm->m.size);
                  dvalue_t=set_bit_value_t(dvalue_t, v->v.ull, stm->m.nbits, stm->m.fbit);
                  memmove(((char*)(&dvalue_t))+8-stm->m.size, m->local+stm->m.offset, stm->m.size);

            }

            if(m->mem) {

                  API_GETMEM(m->mem+stm->m.offset, ((char*)(&dvalue_t))+8-stm->m.size, stm->m.size);
                  dvalue_t=set_bit_value_t(dvalue_t, v->v.ull, stm->m.nbits, stm->m.fbit);
                  API_PUTMEM(m->mem+stm->m.offset, ((char*)(&dvalue_t))+8-stm->m.size, stm->m.size);

            }
            

      } else {

            /* move the data */
            if(is_ctype(v->type.type)) {

                  if(m->local) {

                        memmove(m->local+stm->m.offset, v->v.data, stm->m.size);

                  } 
                  if(m->mem) {

                        API_PUTMEM(m->mem+stm->m.offset, v->v.data, stm->m.size);
                  }

            } else {

                  sial_transval(v->type.size, stm->m.size, v, sial_issigned(v->type.typattr));

                  if(m->local) {

                        memmove(m->local+stm->m.offset, sial_adrval(v), stm->m.size);

                  }

                  if(m->mem) {

                        API_PUTMEM(m->mem+stm->m.offset, sial_adrval(v), stm->m.size);
                  }
            }
      }
}

#define vdata(p, t) ((t*)(p->v.data))

void
sial_exememlocal(value_t *vp, stmember_t* stm, value_t *v)
{
      /* expression should be a ctype_t*/
      if(!is_ctype(vp->type.type)) {

            sial_error("Invalid type for '.' expression");
      }
      /* get that value_t from the application memory */
      if(is_ctype(stm->type.type) && !stm->type.idxlst) {

            void *data=sial_alloc(stm->m.size);

            memmove(data, vdata(vp, char)+stm->m.offset, stm->m.size);
            if(vp->mem) v->mem=vp->mem+stm->m.offset;
            v->v.data=data;

      }
      /* bit field gymnastic */
      else if(stm->m.nbits) {

            ull value=0;

            memmove(vdata(vp, char)+stm->m.offset, ((char*)&value)+(sizeof(value)-stm->m.size), stm->m.size);
            get_bit_value(value, stm->m.nbits, stm->m.fbit, stm->m.size, v);

      } 
      /* check if this is an array, if so then create a reference to it */
      else if(stm->type.idxlst) {

            ull mempos=vp->mem+stm->m.offset;
            if(sial_defbsize()==8) v->v.ull=mempos;
            else v->v.ul=mempos;
            v->mem=mempos;

      } else {

            switch(TYPE_SIZE(&stm->type)) {
                  case 1:
                        memmove(&v->v.uc, vdata(vp, char)+stm->m.offset, 1);
                        v->v.uc = API_GET_UINT8(&v->v.uc);
                  break;
                  case 2:
                        memmove(&v->v.us, vdata(vp, char)+stm->m.offset, 2);
                        v->v.us = API_GET_UINT16(&v->v.us);
                  break;
                  case 4:
                        memmove(&v->v.ul, vdata(vp, char)+stm->m.offset, 4);
                        v->v.ul = API_GET_UINT32(&v->v.ul);
                  break;
                  case 8:
                        memmove(&v->v.ull, vdata(vp, char)+stm->m.offset, 8);
                        v->v.ull = API_GET_UINT64(&v->v.ull);
                  break;
                  default:
                        sial_error("Oops exemem2[%d]", TYPE_SIZE(&stm->type));
                  break;
            }
            if(vp->mem) v->mem=vp->mem+stm->m.offset;
      }
}

value_t *
sial_exemem(mem *m)
{
value_t *v=sial_newval();
value_t *vp=NODE_EXE(m->expr);
stmember_t*stm;
srcpos_t p;

      sial_curpos(&m->p, &p);

      if(vp->type.type == V_REF) {

            if(vp->type.ref > 1) {

                  sial_error("Too many levels of indirection for access to [%s]", m->name);

            }
      }

      /* get the member information and attach it */
      stm=m->stm=(stmember_t*)sial_member(m->name, &vp->type);
      if(!stm) {

            sial_freeval(v);
            sial_freeval(vp);
            sial_error("Invalid member name specified : %s", m->name);

      }

      /* get a copy of the type of thise member and put it in v */
      sial_duptype(&v->type, &stm->type);

      /* indirect i.e. (struct*)->member *most* be relative to the 
         system image. This is a restriction of this language */
      if(m->dir==INDIRECT) {

            ull mempos;

            if(vp->type.type != V_REF  || !is_ctype(vp->type.rtype)) {

                  sial_error("Invalid type for '->' expression");
            }

            m->local=0;
            m->mem=sial_defbsize()==8?vp->v.ull:vp->v.ul;
            mempos=m->mem+stm->m.offset;

            /* get that value_t from the system image */
            if(is_ctype(v->type.type) && !stm->type.idxlst) {

                  v->v.data=sial_alloc(stm->m.size);
                  API_GETMEM(mempos, v->v.data, stm->m.size);
                  v->mem=mempos;

            }
            /* bit field gymnastic */
            else if(stm->m.nbits) {

                  ull value=0;

                  API_GETMEM(m->mem+stm->m.offset, ((char*)&value)+(sizeof(value)-stm->m.size), stm->m.size);
                  get_bit_value(value, stm->m.nbits, stm->m.fbit, stm->m.size, v);
                  /* no mempos for bit fields ... */

            } 
            /* check if this is an array, if so then create a reference to it */
            else if(stm->type.idxlst) {

                  if(sial_defbsize()==8) v->v.ull=mempos;
                  else v->v.ul=mempos;
                  v->mem=mempos;

            } else {

                  v->mem=mempos;

                  // XXX switch(TYPE_SIZE(&stm->type)) {
                  switch(stm->m.size){
                        case 1:
                              API_GETMEM(mempos, &v->v.uc, 1);
                              v->v.uc = API_GET_UINT8(&v->v.uc);
                        break;
                        case 2:
                              API_GETMEM(mempos, &v->v.us, 2);
                              v->v.us = API_GET_UINT16(&v->v.us);
                        break;
                        case 4:
                              if(sizeof(long) == 8){ /* XXX */ 
                                    API_GETMEM(mempos, &v->v.ull, 8);
                                    v->v.ul = API_GET_UINT32(((char*)&(v-> v.ul)) + 4);
                              } else {
                                    API_GETMEM(mempos, &v->v.ul, 4);
                                    v->v.ul = API_GET_UINT32(&v->v.ul);
                              }
                        break;
                        case 8:
                              API_GETMEM(mempos, &v->v.ull, 8);
                              v->v.ull = API_GET_UINT64(&v->v.ull);
                        break;
                        default:
                              sial_error("Oops exemem[%d]", TYPE_SIZE(&stm->type));
                        break;
                  }

            }
      }
      /* direct i.e. (struct).member *most* be in referance to a local 
         structure. */
      else {

            m->mem=vp->mem;
            m->local=vp->v.data;

            /* extract the value from a local copy */
            sial_exememlocal(vp, stm, v);
      }
      sial_curpos(&p, 0);
      sial_freeval(vp);
      v->setfct=(setfct_t)sial_setmem;
      v->setval=(value_t*)m;
      v->set=1;
      return v;
}

void
sial_freemem(mem *m)
{
      NODE_FREE(m->expr);
      sial_free(m->name);
      sial_free(m);
}

node_t*
sial_newmem(int dir, node_t*expr, node_t*name)
{
char *nstr=NODE_NAME(name);
node_t*n=sial_newnode();
mem *m=sial_alloc(sizeof(mem));

      /* dicard nam  node_t*/
      NODE_FREE(name);
      m->name=nstr;
      m->dir=dir;
      m->expr=expr;
      sial_setpos(&m->p);
      n->data=m;
      n->exe=(xfct_t)sial_exemem;
      n->free=(ffct_t)sial_freemem;
      return n;
}

Generated by  Doxygen 1.6.0   Back to index