void eppic_cparrelems(array_t**to, array_t**frm) { array_t*ap; if(FRM) { eppic_setarray(to); for(ap=FRM->next; ap!=FRM; ap=ap->next) { array_t*na=eppic_calloc(sizeof(array_t)); /* copy value_ts */ eppic_dupval(na->idx, ap->idx); eppic_dupval(na->val, ap->val); /* link it in */ na->prev=TO->prev; na->next=TO; TO->prev->next=na; TO->prev=na; na->ref=1; /* copy that branch */ eppic_cparrelems(&na->val->arr, &ap->val->arr); } } }
/* 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; }
/* cheap realloc. we drop the original This function is only used ones in configmon(1) code */ void * eppic_realloc(void *p, int size) { int cursize=((blist*)(((char*)p)-SIZEBL))->size-SIZEBL; void *p2; p2=eppic_calloc(size); memcpy(p2, p, cursize<size?cursize:size); eppic_free(p); return p2; }
void eppic_setarray(array_t**arpp) { array_t*arp=*arpp; if(!arp) { arp=eppic_calloc(sizeof(array_t)); TAG(arp); arp->next=arp->prev=arp; arp->ref=1; *arpp=arp; } }
var_t* eppic_newvar(char *name) { var_t*v=eppic_calloc(sizeof(var_t)); char *myname=eppic_alloc(strlen(name)+1); TAG(myname); strcpy(myname,name); v->name=myname; v->v=eppic_makebtype(0); v->v->setval=v->v; v->next=v->prev=v; return v; }
/* * Drill down the type of the member and update eppic with information * about the member */ static char * drilldown(ull offset, type_t *t) { int type_flag, len = 0, t_len = 0, nidx = 0; int fctflg = 0, ref = 0, *idxlst = 0; ull die_off = offset, t_die_off; char *tstr = NULL, *tstr_dup = NULL; while (GET_DIE_ATTR_TYPE(die_off, &type_flag, &t_die_off)) { switch (type_flag) { /* typedef inserts a level of reference to the actual type */ case DW_TAG_pointer_type: ref++; die_off = t_die_off; /* * This could be a void *, in which case the drill * down stops here */ if (!GET_DIE_ATTR_TYPE(die_off, &type_flag, &t_die_off)) { /* make it a char* */ eppic_parsetype("char", t, ref); return eppic_strdup(""); } break; /* Handle pointer to function */ case DW_TAG_subroutine_type: fctflg = 1; die_off = t_die_off; break; /* Handle arrays */ case DW_TAG_array_type: if (!idxlst) { idxlst = eppic_calloc(sizeof(int) * \ (MAX_ARRAY_DIMENSION + 1)); if (!idxlst) { ERRMSG("Out of memory\n"); return NULL; } } if (nidx >= MAX_ARRAY_DIMENSION) { ERRMSG("Too many array indexes. Max=%d\n", MAX_ARRAY_DIMENSION); return NULL; } /* handle multi-dimensional array */ len = GET_DIE_LENGTH(die_off, FALSE); t_len = GET_DIE_LENGTH(t_die_off, FALSE); if (len > 0 && t_len > 0) idxlst[nidx++] = len / t_len; die_off = t_die_off; break; /* Handle typedef */ case DW_TAG_typedef: die_off = t_die_off; break; case DW_TAG_base_type: eppic_parsetype(tstr = GET_DIE_NAME(t_die_off), t, 0); goto out; case DW_TAG_union_type: eppic_type_mkunion(t); goto label; case DW_TAG_enumeration_type: eppic_type_mkenum(t); goto label; case DW_TAG_structure_type: eppic_type_mkstruct(t); goto label; /* Unknown TAG ? */ default: die_off = t_die_off; break; } } label: eppic_type_setsize(t, GET_DIE_LENGTH(t_die_off, TRUE)); eppic_type_setidx(t, (ull)t_die_off); tstr = GET_DIE_NAME(t_die_off); out: eppic_setupidx(t, ref, nidx, idxlst); if (fctflg) eppic_type_setfct(t, 1); eppic_pushref(t, ref + (nidx ? 1 : 0)); tstr_dup = (tstr) ? eppic_strdup(tstr) : eppic_strdup(""); /* Free the memory allocated by makedumpfile. */ free(tstr); return tstr_dup; }