static int r_print_format_struct(RPrint* p, ut64 seek, const ut8* b, int len, char *name, int slide) { const char *fmt; int flag = (slide>=STRUCTFLAG)?SEEFLAG:-1; if ((slide%STRUCTPTR) > NESTDEPTH) { eprintf ("Too much nested struct, recursion too deep...\n"); return 0; } if (flag) p->printf = realprintf; fmt = r_strht_get (p->formats, name); if (!fmt || !*fmt) { eprintf ("Undefined struct '%s'.\n", name); return 0; } r_print_format (p, seek, b, len, fmt, flag, NULL); return computeStructSize(strdup(fmt)); }
int computeStructSize(FieldList var){ FieldList fp = var->tail; int size = 0; int array_size = 0; int struct_size = 0; while(fp != NULL){ switch(fp->type->kind){ case basic: size += 4; break; case array: array_size = (fp->type->u).array.size; size += array_size*4; break; case structure: struct_size = computeStructSize((fp->type->u).structure); size += struct_size; break; } fp = fp->tail; } return size; }
InterCodeNode translate_VarDec(treenode *VarDec_n, Operand place){ if(VarDec_n == NULL){ //deprintf("VarDec is NULL\n"); return NULL; } treenode *id = VarDec_n->node[0]; char *name = id->idval; if(VarDec_n->child_num == 1){ // vardec -> id FieldList var = fetchArg(name); if(var != NULL){ if(var->type->kind == basic){ struct Var_info *new_var = new_VarInfo(name,++g_var_count,BASIC,4); insertVarInfo(new_var); place->kind = VARIABLE; place->u.var_no = g_var_count; return NULL; }else{ assert(var->type->kind == structure); int size = computeStructSize((var->type->u).structure); struct Var_info *new_var = new_VarInfo(name,++g_var_count,STRUCT,size); insertVarInfo(new_var); Operand var_op = new_Operand(); Operand size_op = new_Operand(); var_op->kind = VARIABLE; var_op->u.var_no = g_var_count; size_op->kind = SIZE; size_op->u.value = size; InterCode dec_code = new_InterCode(); dec_code->kind = DEC; dec_code->u.dec.var = var_op; dec_code->u.dec.size = size_op; return produceNodeByCode(dec_code); } } } assert(VarDec_n->child_num == 4); //vardec -> vardec [int] //vardec -> id treenode *num_node = VarDec_n->node[2]; treenode *check_multi = VarDec_n->node[0]; int size = num_node->ival; if(check_multi->child_num != 1){ printf("Can not translate the code: contain multidimensional array and function parameters of array type\n"); exit(1); } treenode *array_id = check_multi->node[0]; FieldList array_var = fetchArg(array_id->idval); if(array_var != NULL){ int elem = 4; Type base_type = (array_var->type->u).array.elem; if(base_type->kind == basic){ struct Var_info *new_var = new_VarInfo(array_var->name,++g_var_count,ARRAY,size*elem); insertVarInfo(new_var); }else if(base_type->kind == structure){ elem = computeStructSize(base_type->u.structure); struct Var_info *new_var = new_VarInfo(array_var->name,++g_var_count,STRUCT,size*elem); insertVarInfo(new_var); } Operand var_op = new_Operand(); Operand size_op = new_Operand(); size_op->kind = SIZE; size_op->u.value = size*elem; var_op->kind = VARIABLE; var_op->u.var_no = g_var_count; //array size dec InterCode dec_code = new_InterCode(); dec_code->kind = DEC; dec_code->u.dec.var = var_op; dec_code->u.dec.size = size_op; return produceNodeByCode(dec_code); } //deprintf("Error NULL!\n"); return NULL; }
//maybe useless InterCodeNode translate_ExpDotExp(treenode *enode, Operand place){ //Exp -> Exp [Exp] // Exp -> Exp.id // // Exp -> Exp[Exp].id[Exp] treenode *exp1 = enode->node[0]; treenode *index_exp = enode->node[2]; treenode *exp2 = exp1->node[0]; treenode *field_id = exp1->node[2]; treenode *var_id = exp2->node[0]; Operand start = new_Operand(); FieldList if_para = fetchPara(var_id->idval); FieldList field = NULL; if(if_para != NULL){ struct Var_info *temp_var = fetchVarInfo(var_id->idval); start->kind = VARIABLE; start->u.var_no = temp_var->var_no; field = (if_para->type->u).structure->tail; }else{ struct Var_info *temp_var = fetchVarInfo(var_id->idval); start->kind = REFERENCE; start->u.var_no = temp_var->var_no; FieldList temp_var2 = fetchArg(var_id->idval); field = (temp_var2->type->u).structure->tail; } int count = 0; FieldList p = field; while(p != NULL){ if(strcmp(p->name,field_id->idval) == 0) break; switch(p->type->kind){ case basic: count += 4;break; case array: count += 4*((p->type->u).array.size);break; case structure: count += computeStructSize((p->type->u).structure); break; } p = p->tail; } Operand field_offset = new_Operand(); field_offset->kind = CONSTANT; field_offset->u.value = count; Operand array_start = new_Temp(); InterCode add_code = new_InterCode(); add_code->kind = ADD; add_code->u.binop.result = array_start; add_code->u.binop.op1 = start; add_code->u.binop.op2 = field_offset; InterCodeNode node1 = produceNodeByCode(add_code); Operand t1 = new_Temp(); InterCodeNode node2 = translate_Exp(index_exp,t1); Operand t2 = new_Temp(); Operand length4 = new_Operand(); length4->kind = CONSTANT; length4->u.value = 4; InterCode mul_code = new_InterCode(); mul_code->kind = MUL; mul_code->u.binop.result = t2; mul_code->u.binop.op1 = t1; mul_code->u.binop.op2 = length4; InterCodeNode node3 = produceNodeByCode(mul_code); Operand addr = new_Temp(); InterCode add_code1 = new_InterCode(); add_code1->kind = ADD; add_code1->u.binop.result = addr; add_code1->u.binop.op1 = array_start; if(t1->kind == CONSTANT){ t1->u.value = t1->u.value * 4; add_code1->u.binop.op2 = t1; node3 = NULL; }else{ add_code1->u.binop.op2 = t2; } InterCodeNode node4 = produceNodeByCode(add_code1); // Operand new_addr = new_Operand(); // new_addr->kind = ADDRESS; // new_addr->u.temp_no = addr->u.temp_no; // Operand data = new_Temp(); // InterCode assign_code = new_InterCode(); // assign_code->kind = ASSIGN; // assign_code->u.assign.left = data; // assign_code->u.assign.right = new_addr; // InterCodeNode node5 = produceNodeByCode(assign_code); //show(node4); place->kind = ADDRESS; place->u.temp_no = addr->u.temp_no; InterCodeNode temp12 = produceNodeByNode(node1,node2); InterCodeNode temp123 = produceNodeByNode(temp12,node3); InterCodeNode temp1234 = produceNodeByNode(temp123,node4); return temp1234; //return produceNodeByNode(temp1234,node5); }