static void eppic_prtarray(type_t*t, ull mem, int level, int idx) { int i; int j, size=1; for(j=idx+1; t->idxlst[j]; j++) size *= t->idxlst[j]; size *= t->type==V_REF ? eppic_defbsize() : t->size; /* start printing */ eppic_msg("{"); eppic_msg("\n"); eppic_indent(level+1, 1); for(i=0; i<t->idxlst[idx]; i++, mem += size) { if(t->idxlst[idx+1]) { eppic_msg("[%d] = ", i); eppic_prtarray(t, mem, level+1, idx+1); } else { /* time to deref and print final type */ value_t *v=eppic_newval(), *vr=eppic_newval(); int *pi=t->idxlst; t->idxlst=0; eppic_duptype(&vr->type, t); eppic_pushref(&vr->type, 1); if(eppic_defbsize()==8) vr->v.ull=mem; else vr->v.ul=(ul)mem; eppic_do_deref(1, v, vr); if(is_ctype(v->type.type) || !(i%NBUNDLE)) eppic_msg("[%2d] ", i); eppic_ptype2(&v->type, v, level+1, 0, 0, 0, 1); eppic_msg(", "); /* anything else then struct/unions, print in buddles */ if(!is_ctype(v->type.type) && !((i+1)%NBUNDLE)) { eppic_msg("\n"); eppic_indent(level+1, 1); } eppic_freeval(v); eppic_freeval(vr); t->idxlst=pi; } } eppic_msg("\n"); eppic_indent(level, 1); eppic_msg("}"); }
static value_t * eppic_exeadrof(adrof *a) { value_t *rv, *v=NODE_EXE(a->expr); #if 0 /* we can only do this op on something that came from system image Must not allow creation of references to local variable */ if(!v->mem) { eppic_freeval(v); eppic_rerror(&a->pos, "Invalid operand to '&' operator"); } #endif /* create the reference */ rv=eppic_newval(); eppic_duptype(&rv->type, &v->type); eppic_pushref(&rv->type, 1); /* remmember position in image */ if(eppic_defbsize()==8) rv->v.ull=v->mem; else rv->v.ul=v->mem; rv->mem=0; eppic_freeval(v); return rv; }
/* scan the current array for a specific index and return value_t XXX should use some hashing tables here for speed and scalability */ array_t* eppic_getarrval(array_t**app, value_t *idx) { array_t*ap, *apr; /* eppic_setarray(app); AAA comment out */ apr=*app; for(ap=apr->next; ap != apr; ap=ap->next) { if(ap->idx->type.type == idx->type.type) { int b=0; switch(idx->type.type) { case V_STRING: b=(!strcmp(ap->idx->v.data, idx->v.data)); break; case V_BASE: b=(unival(ap->idx)==unival(idx)); break; case V_REF: if(eppic_defbsize()==4) b=(ap->idx->v.ul==idx->v.ul); else b=(ap->idx->v.ull==idx->v.ull); break; default: eppic_error("Invalid index type %d", idx->type.type); } if(b) { return ap; } } } /* we have not found this index, create one */ ap=(array_t*)eppic_calloc(sizeof(array_t)); ap->idx=eppic_makebtype(0); eppic_dupval(ap->idx, idx); /* just give it a int value_t of 0 for now */ ap->val=eppic_makebtype(0); /* we must set the same refenrence number as the upper level array_t*/ ap->val->arr->ref=apr->ref; /* link it in */ ap->prev=apr->prev; ap->next=apr; apr->prev->next=ap; apr->prev=ap; ap->ref=0; return ap; }
static int eppic_reftobase(value_t *v) { int idx= v->type.idx; if(v->type.type==V_REF) { if(eppic_defbsize()==4) v->type.idx=B_UL; else v->type.idx=B_ULL; } return idx; }
static int eppic_prtstr(value_t *v, int justv) { value_t *vs; char *s, *p; if(eppic_defbsize()==8) v->v.ull=v->mem; else v->v.ul=v->mem; vs=eppic_getstr(v); s=eppic_getptr(vs, char); for(p=s; *p; p++) if(!isprint(*p)) return 0; if(p==s) { eppic_freeval(vs); return 0; } if(!justv) eppic_msg("= "); eppic_msg("\"%s\"", s); eppic_freeval(vs); return 1; }
/* * This function is a copy of eppic_setupidx() function in * applications/crash/eppic.c file from eppic source code * repository. * * set idx value to actual array indexes from specified size */ static void eppic_setupidx(TYPE_S *t, int ref, int nidx, int *idxlst) { /* put the idxlst in index size format */ if (nidx) { int i; for (i = 0; i < nidx - 1; i++) { /* kludge for array dimensions of [1] */ if (idxlst[i + 1] == 0) idxlst[i + 1] = 1; idxlst[i] = idxlst[i] / idxlst[i + 1]; } /* divide by element size for last element bound */ if (ref) idxlst[i] /= eppic_defbsize(); else idxlst[i] /= eppic_type_getsize(t); eppic_type_setidxlst(t, idxlst); } }
ul eppic_bool(value_t *v) { switch(v->type.type) { case V_BASE: 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)); default: eppic_error("Oops eppic_bool()[%d]", v->type.size); break; } case V_STRING : return !(!(*((char*)(v->v.data)))); case V_REF: return eppic_defbsize()==8?(!(!(v->v.ull))):(!(!(v->v.ul))); default : eppic_error("Invalid operand for boolean expression"); return 0; } }
/* called by the 'var in array' bool expression. */ int eppic_lookuparray(node_t*vnode, node_t*arrnode) { value_t *varr=NODE_EXE(arrnode); array_t*ap, *apr=varr->arr; value_t *val; int b=0; val=NODE_EXE(vnode); if(apr) { for(ap=apr->next; ap != apr; ap=ap->next) { if(VAL_TYPE(ap->idx) == VAL_TYPE(val)) { switch(VAL_TYPE(val)) { case V_STRING: b=(!strcmp(ap->idx->v.data, val->v.data)); break; case V_BASE: b=(unival(ap->idx)==unival(val)); break; case V_REF: if(eppic_defbsize()==4) b=(ap->idx->v.ul==val->v.ul); else b=(ap->idx->v.ull==val->v.ull); break; default: eppic_rerror(&vnode->pos, "Invalid indexing type %d", VAL_TYPE(val)); } if(b) break; } } } eppic_freeval(val); eppic_freeval(varr); return b; }
void eppic_do_deref(int n, value_t *v, value_t *ref) { ull madr, new_madr; if(n > ref->type.ref) { eppic_error("Too many levels of dereference"); }else { if(eppic_defbsize()==4) madr=(ull)ref->v.ul; else madr=ref->v.ull; /* copy the target type to the returned value_t's type_t*/ eppic_duptype(&v->type, &ref->type); /* do a number of deferences according to PTR value_t */ while(n--) { eppic_popref(&v->type, 1); if(!v->type.ref) { /* make sure the pointer is pointing into the vmcore */ if(is_ctype(v->type.type)) { v->v.data=eppic_alloc(v->type.size); eppic_getmem(madr, v->v.data, v->type.size); } else { /* get the data from the system image */ switch(TYPE_SIZE(&v->type)) { case 1: eppic_getmem(madr, &v->v.uc, 1); break; case 2: eppic_getmem(madr, &v->v.us, 2); break; case 4: eppic_getmem(madr, &v->v.ul, 4); break; case 8: eppic_getmem(madr, &v->v.ull, 8); break; } } } else { /* get the pointer at this address */ if(eppic_defbsize()==4) { eppic_getmem(madr, &v->v.ul, 4); new_madr=v->v.ul; } else { eppic_getmem(madr, &v->v.ull, 8); new_madr=v->v.ull; } } /* remember this address. For the '&' operator */ v->mem=madr; madr=new_madr; } } /* we can always assign to a reference */ v->set=1; v->setval=v; v->setfct=eppic_setderef; }
static value_t * eppic_exeindex(index_t *i) { value_t *var; value_t *vi=NODE_EXE(i->index); value_t *v; srcpos_t p; eppic_curpos(&i->pos, &p); /* we need to make believe it's been initiazed */ eppic_setini(i->var); var=NODE_EXE(i->var); /* check the type of the variable */ /* if it's a pointer then index through the image */ if(var->type.type==V_REF) { int size; int n=eppic_getval(vi); value_t *ref; /* if this is an array and we're not at the rightmost index */ if(var->type.idxlst && var->type.idxlst[1]) { int i, size=var->type.size; v=eppic_cloneval(var); v->type.idxlst[0]=0; for(i=1; var->type.idxlst[i]; i++) { size *= var->type.idxlst[i]; v->type.idxlst[i]=var->type.idxlst[i+1]; } if(eppic_defbsize()==4) { v->v.ul+=size*n; v->mem=v->v.ul; } else { v->v.ull+=size*n; v->mem=v->v.ull; } } else { v=eppic_newval(); ref=eppic_cloneval(var); if(var->type.ref==1) size=var->type.size; else size=eppic_defbsize(); if(eppic_defbsize()==4) { ref->v.ul+=size*n; ref->mem=ref->v.ul; } else { ref->v.ull+=size*n; ref->mem=ref->v.ull; } eppic_do_deref(1, v, ref); eppic_freeval(ref); } } else { v=eppic_newval(); /* use dynamic indexing aka awk indexing */ eppic_valindex(var, vi, v); } /* discard expression results */ eppic_freeval(var); eppic_freeval(vi); eppic_curpos(&p, 0); return v; }
/* Print a type. Typical output of the 'whatis' command. */ static void eppic_ptype2(type_t*t, value_t*v, int level, int indent, char *name, int ref, int justv) { int type=t->type; eppic_indent(level, indent); switch(type) { case V_STRUCT: case V_UNION: /* make sure we have all the member info */ eppic_print_ctype(t, v, level, 0, name, ref, justv); break; case V_TYPEDEF: /* no typedef should get here */ eppic_warning("Typedef in print!"); break; case V_ENUM: /* no enum should get here */ eppic_warning("ENUM in print!"); break; case V_REF: { int refi=t->ref, ref=refi; /* decrement ref if this was declared as a array */ if(t->idxlst) ref--; /* print the referenced type */ eppic_popref(t, t->ref); eppic_ptype2(t, 0, level, 0, 0, 1, justv); eppic_pushref(t, refi); if(!justv) { char buf[100], buf2[100]; int pos=0, len=sizeof(buf); buf[0]='\0'; if(t->fct) buf[pos++]='('; if(pos < len) pos += snprintf(buf+pos, len-pos, "%s%s", eppic_getref(ref), name?name:""); if(pos < len) pos += snprintf(buf+pos, len-pos, "%s", eppic_getidx(t, buf2, sizeof(buf2))); if(pos < len && t->fct) pos += snprintf(buf+pos, len-pos, "%s", ")()"); eppic_msg("%*s ", NAMESPACE, buf); } /* arrays are ref with boundaries... */ if(t->idxlst && v) { if(t->idxlst[1] || t->rtype!=V_BASE || t->size!=1 || !eppic_prtstr(v, justv)) { if(!justv) eppic_msg("= "); eppic_popref(t, 1); eppic_prtarray(t, v->mem, level, 0); eppic_pushref(t, 1); } } else if(v) { if(!justv) eppic_msg("= "); if(!eppic_getval(v)) eppic_msg("(nil)"); else { if(eppic_defbsize()==8) eppic_msg("0x%016llx", eppic_getval(v)); else eppic_msg("0x%08x", eppic_getval(v)); } if(t->ref==1 && t->rtype==V_BASE && t->size==1) { (void)eppic_prtstr(v, justv); } } } break; case V_BASE: { if(eppic_isenum(t->typattr)) { stinfo_t *st=eppic_getstbyindex(t->rtype, V_ENUM); if(!justv) { char buf[200]; snprintf(buf, sizeof(buf), "enum %s", st->name?st->name:""); eppic_msg("%-*s ", SPACER, buf); eppic_msg("%*s ", NAMESPACE, (name&&v)?name:""); } if(v) { enum_t *e=st->enums; eppic_msg("= "); eppic_prbval(v); while(e) { if(e->value==eppic_getval(v)) { eppic_msg(" [%s]", e->name); break; } e=e->next; } if(!e) eppic_msg(" [???]"); }else{ enum_t *e=st->enums; int count=0; eppic_msg(" {"); while(e) { if(!(count%4)) { eppic_msg("\n"); eppic_indent(level+1, 1); } count ++; eppic_msg("%s = %d, ", e->name, e->value); e=e->next; } eppic_msg("\n"); eppic_indent(level, 1); eppic_msg("%-*s ", SPACER, "}"); if(ref) return; eppic_msg("%*s ", NAMESPACE, name?name:""); } } else { if(!justv) { eppic_msg("%-*s " , SPACER , eppic_getbtypename(t->typattr)); if(ref) return; eppic_msg("%s%*s ", eppic_getref(t->ref), NAMESPACE, name?name:""); } if(v) { if(!justv) eppic_msg("= "); eppic_prbval(v); } } } break; case V_STRING: if(!justv) { eppic_msg("%-*s " , SPACER , "string"); eppic_msg("%*s ", NAMESPACE, name?name:""); } if(v) { if(!justv) eppic_msg("= "); eppic_msg("\"%s\"", v->v.data); } break; } if(indent) eppic_msg("\n"); }