int cp_ctype_free() { int i; csymbol *cs; if (cts.stack) free(cts.stack); if (cs_arr) { for (i = 0; i < cs_nr; i++) { cs = &cs_arr[i]; if (csym_type(cs) == FFI_FUNC) { if (csym_func(cs)->arg_ids) free(csym_func(cs)->arg_ids); } else if (csym_type(cs) == FFI_STRUCT) { if (csym_struct(cs)->members) free(csym_struct(cs)->members); } } free(cs_arr); } if (cte_arr) { free(cte_arr); } return 0; }
static void DumpCSymbolFunc(csymbol *cs, DumpState *D) { csymbol_func *csf = csym_func(cs); DumpBlock(cs, sizeof(csymbol), D); /* dump csymbol index for argument types */ DumpBlock(csf->arg_ids, csf->arg_nr*sizeof(int), D); }
int cp_symbol_build_func(struct cp_ctype *type, const char *fname, int fn_size) { int i = 1, arg_nr, id; int *argsym_id_arr; csymbol nfcs; csymbol_func *fcs; if (cts.top == 0 || fn_size < 0 || !fname) { cp_error("invalid function definition.\n"); } argsym_id_arr = NULL; memset(&nfcs, 0, sizeof(csymbol)); csym_type(&nfcs) = FFI_FUNC; strncpy(csym_name(&nfcs), fname, fn_size); fcs = csym_func(&nfcs); fcs->has_var_arg = type->has_var_arg; /* Type needed for handling variable args handle */ if (fcs->has_var_arg && !ctype_lookup_type("void *")) cp_symbol_build_pointer(ctype_lookup_type("void")); /* Fetch start address of function */ fcs->addr = (void *)find_kernel_symbol(csym_name(&nfcs)); if (!fcs->addr) cp_error("wrong function address for %s\n", csym_name(&nfcs)); /* bottom of the stack is return type */ fcs->ret_id = ct_stack_ct(0)->ffi_cs_id; /* the rest is argument type */ if (cts.top == 1) { /* function takes no argument */ arg_nr = 0; } else { arg_nr = cts.top - 1; argsym_id_arr = malloc(arg_nr * sizeof(int)); if (!argsym_id_arr) cp_error("failed to allocate memory for function args.\n"); for (i = 0; i < arg_nr; i++) { argsym_id_arr[i] = ct_stack_ct(i+1)->ffi_cs_id; } } fcs->arg_nr = arg_nr; fcs->arg_ids = argsym_id_arr; id = cp_ctype_reg_csymbol(&nfcs); /* clear stack since we have consumed all the ctypes */ ctype_stack_reset(); return id; }
/* this is a debug function used for check csymbol array */ void ktapc_dump_csymbols() { int i, j, cs_nr; cp_csymbol_state *cs_state; csymbol *cs, *cs_arr; csymbol_func *csf; csymbol_struct *csst; cs_state = ctype_get_csym_state(); cs_arr = cs_state->cs_arr; cs_nr = cs_state->cs_nr; printf("\n----------------------------------------------------\n"); printf("Number of csymbols: %d\n", cs_nr); for (i = 0; i < cs_nr; i++) { cs = &cs_arr[i]; printf("%dth symbol", i); ktapc_dump_csymbol_id("", i); switch (cs->type) { case FFI_PTR: ktapc_dump_csymbol_id("\tDeref", csym_ptr_deref_id(cs)); break; case FFI_FUNC: csf = csym_func(cs); printf("\tAddress: 0x%p\n", csf->addr); ktapc_dump_csymbol_id("\tReturn", csf->ret_id); printf("\tArg number: %d\n", csf->arg_nr); for (j = 0; j < csf->arg_nr; j++) ktapc_dump_csymbol_id("\t\tArg", csf->arg_ids[j]); printf("\tHas variable arg: %d\n", csf->has_var_arg); break; case FFI_STRUCT: case FFI_UNION: csst = csym_struct(cs); printf("\tMember number: %d\n", csst->memb_nr); for (j = 0; j < csst->memb_nr; j++) { printf("\t\tMember %s", csst->members[j].name); if (csst->members[j].len >= 0) printf("(len %d)", csst->members[j].len); ktapc_dump_csymbol_id("", csst->members[j].id); } break; default: break; } } }
void __cp_symbol_dump_func(csymbol *cs) { int i; csymbol *ncs; csymbol_func *fcs = csym_func(cs); printf("=== [%s] function definition =============\n", csym_name(cs)); ncs = cp_csymf_ret(fcs); printf("address: %p\n", fcs->addr); printf("return type: \n"); printf("\tcsym_id: %d, ffi_ctype: %d, %s\n", fcs->ret_id, ncs->type, csym_name(ncs)); printf("args type (%d): \n", fcs->arg_nr); for (i = 0; i < csymf_arg_nr(fcs); i++) { printf("\t (%d) ", i); printf("csym_id: %d, ", fcs->arg_ids[i]); ncs = cp_csymf_arg(fcs, i); printf("ffi_ctype: %d, %s\n", ncs->type, csym_name(ncs)); } }