Example #1
0
static int
apigetctype(int ctype, char *name, type_t *tout)
{
	long size = 0;
	unsigned long long die = 0;

	switch (ctype) {
	case V_TYPEDEF:
		size = GET_DOMAIN(name, DWARF_INFO_GET_DOMAIN_TYPEDEF, &die);
		break;
	case V_STRUCT:
		size = GET_DOMAIN(name, DWARF_INFO_GET_DOMAIN_STRUCT, &die);
		break;
	case V_UNION:
		size = GET_DOMAIN(name, DWARF_INFO_GET_DOMAIN_UNION, &die);
		break;
	/* TODO
	 * Implement for all the domains
	 */
	}

	if (size <= 0 || !die)
		return 0;

	/* populate */
	eppic_type_settype(tout, ctype);
	eppic_type_setsize(tout, size);
	eppic_type_setidx(tout, (ull)(unsigned long)die);
	eppic_pushref(tout, 0);
	return 1;
}
Example #2
0
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;
}
Example #3
0
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("}");
}
Example #4
0
int
apigetval(char *name, ull *val, VALUE_S *value)
{
	ull ptr = 0;

	ptr = GET_SYMBOL_ADDR_ALL(name);

	if (!ptr)
		return 0;

	*val = ptr;

	if (!value)
		return 1;

	/* Support for fully typed symbol access */
	ull type;
	TYPE_S *stype;

	type = GET_DIE_OFFSET(name);
	stype = eppic_gettype(value);

	apigetrtype(type, stype);

	eppic_pushref(stype, 1);
	eppic_setmemaddr(value, *val);
	eppic_do_deref(1, value, value);

	*val = eppic_getval(value);

	if (!eppic_typeislocal(stype) && eppic_type_getidx(stype) > 100) {
		char *tname = GET_DIE_NAME(eppic_type_getidx(stype));
		if (tname) {
			eppic_chktype(stype, tname);
			/* Free the memory allocated by makedumpfile. */
			free(tname);
		}
	}
	return 1;
}
Example #5
0
/*
 * 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;
}
Example #6
0
/*
    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");
}
Example #7
0
/*
    this is the main variable declaration function.
    We support the global scope attribute that make the declared
    variable accessible to all function from all scripts.

    By default the scope of a variable either the statement block
    where it was declared (or first used):
    {
    int var;
     ...
    }
    Then it's scope is the block itself.

    Or the file, if it was declared outside of a function.

    Storage is by default 'automatic' and can be made permanent
    by using the 'static' keywork in the declaration.
    'Volatile' and 'register' storage classes are supported but 
    have no effect.
*/
var_t*
eppic_vardecl(dvar_t*dv, type_t*t)
{
var_t*vlist=eppic_newvlist();
var_t*var;

    /* type *and* dv can have ref counts. First comes from typedef parsing
       second comes from the declaration itself */
    dv->ref += t->ref;
    
    /* add one level of ref for arrays */
    if(dv->idx) dv->ref++;

    /* reset ref level for tests below */
    eppic_popref(t, t->ref);

    TAG(vlist);

    if(!t->type) {

        int sto=eppic_isstor(t->typattr);

        eppic_freetype(t);
        t=eppic_newbtype(0);
        t->typattr |= sto;
    }
    else if(t->type==V_BASE && !dv->ref) {

        eppic_chksign(t);
        eppic_chksize(t);
    }

    /* is this a new typedef declaration ? */
    /* typedef is considered just like any other storage class */
    if(eppic_istdef(t->typattr)) {

        eppic_tdef_decl(dv, t);
        return 0;
    }

    while(dv) {
        
        /* disalow var names that match against already defined vars */
        if(dv->name[0]) {
            type_t *t=eppic_getctype(V_TYPEDEF, dv->name, 1);
            if(t) {

                eppic_freetype(t);
                eppic_warning("Variable '%s' already defined as typedef.\n");
            }
        }

        /* 
           some sanity checks here that apply to both var and struct 
           declarations 
        */
        if(is_ctype(t->type) && !dv->ref) {

            if(dv->name[0]) {

                if(!instruct) {

                    if(!eppic_isxtern(t->typattr)) {

                        eppic_freesvs(vlist);
                        eppic_error("struct/union instances not supported, please use pointers");
                    }

                } else if(eppic_ispartial(t)) {

                    eppic_freesvs(vlist);
                    eppic_error("Reference to incomplete type");
                }
            }
        }
        if(dv->nbits) { 

            if(t->type != V_BASE) {

                eppic_freesvs(vlist);
                eppic_error("Bit fields can only be of integer type");

            }
            if(dv->idx) {

                eppic_freesvs(vlist);
                eppic_error("An array of bits ? Come on...");
            }
        }

        var=eppic_newvar(dv->name);

        t->fct=dv->fct;
        eppic_duptype(&var->v->type, t);
        eppic_pushref(&var->v->type, dv->ref);

        var->dv=dv;

        TAG(var);

        if(t->type == V_STRING) {

            eppic_setstrval(var->v, "");

        } 

        eppic_setpos(&dv->pos);

        /* toff */
        /* add to parsing list */  
        if(var->name[0]) {
           var_t *plist=eppic_newvlist();
           eppic_enqueue(plist, var);
           eppic_addsvs(S_PARSE, eppic_dupvlist(plist));
        }
        eppic_enqueue(vlist, var);
next:
        dv=dv->next;
    }
    eppic_free(t);
    TAG(vlist);
    return vlist;
}