/** * Return info about the SPU's function to the PPU / main memory. * The PPU needs to know the address of some SPU-side functions so * that we can generate shader code with function calls. */ void return_function_info(void) { struct cell_spu_function_info funcs ALIGN16_ATTRIB; int tag = TAG_MISC; ASSERT(sizeof(funcs) == 256); /* must be multiple of 16 bytes */ funcs.num = 0; export_func(&funcs, "spu_cos", &spu_cos); export_func(&funcs, "spu_sin", &spu_sin); export_func(&funcs, "spu_pow", &spu_pow); export_func(&funcs, "spu_exp2", &spu_exp2); export_func(&funcs, "spu_log2", &spu_log2); export_func(&funcs, "spu_tex_2d", &spu_tex_2d); export_func(&funcs, "spu_tex_3d", &spu_tex_3d); export_func(&funcs, "spu_tex_cube", &spu_tex_cube); /* Send the function info back to the PPU / main memory */ mfc_put((void *) &funcs, /* src in local store */ (unsigned int) spu.init.spu_functions, /* dst in main memory */ sizeof(funcs), /* bytes */ tag, 0, /* tid */ 0 /* rid */); wait_on_mask(1 << tag); }
static void update_export_array_if_necessary(bool recalc) { ASSERT_IS_MAIN_THREAD(); if (recalc && !get_proc_had_barrier()) { set_proc_had_barrier(true); env_universal_barrier(); } if (has_changed_exported) { std::map<wcstring, wcstring> vals; debug(4, L"env_export_arr() recalc"); get_exported(top, &vals); if (uvars()) { const wcstring_list_t uni = uvars()->get_names(true, false); for (size_t i = 0; i < uni.size(); i++) { const wcstring &key = uni.at(i); const env_var_t val = uvars()->get(key); if (!val.missing() && val != ENV_NULL) { // Note that std::map::insert does NOT overwrite a value already in the map, // which we depend on here. vals.insert(std::pair<wcstring, wcstring>(key, val)); } } } std::vector<std::string> local_export_buffer; export_func(vals, local_export_buffer); export_array.set(local_export_buffer); has_changed_exported = false; } }
int rt_obj_export(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip, struct resource *resp) { int id; const struct rt_functab *ft; int (*export_func)(struct bu_external *, const struct rt_db_internal *, double, const struct db_i *, struct resource *); if (!ep || !ip || !dbip || local2mm < 0.0) return -1; BU_CK_EXTERNAL(ep); RT_CK_DB_INTERNAL(ip); RT_CK_DBI(dbip); if (resp) RT_CK_RESOURCE(resp); id = ip->idb_minor_type; if (id < 0) return -2; ft = &OBJ[id]; if (!ft) return -3; if (dbip->dbi_version < 5) { export_func = ft->ft_export4; } else { export_func = ft->ft_export5; } if (!export_func) return -4; return export_func(ep, ip, local2mm, dbip, resp); }
static int id_conf_export(void (*export_func)(char *name, char *val), enum conf_export_tgt tgt) { uint8_t src_buf[BSP_MAX_ID_LEN]; char str[sizeof(src_buf) * 2]; int len; if (tgt == CONF_EXPORT_SHOW) { len = bsp_hw_id(src_buf, sizeof(src_buf)); if (len > 0) { conf_str_from_bytes(src_buf, len, str, sizeof(str)); } export_func("id/hwid", str); export_func("id/bsp", (char *)bsp_str); export_func("id/app", (char *)app_str); } export_func("id/serial", serial); return 0; }
static void update_export_array_if_necessary(bool recalc) { ASSERT_IS_MAIN_THREAD(); if (recalc && ! get_proc_had_barrier()) { set_proc_had_barrier(true); env_universal_barrier(); } if (has_changed_exported) { std::map<wcstring, wcstring> vals; size_t i; debug(4, L"env_export_arr() recalc"); get_exported(top, vals); wcstring_list_t uni; env_universal_get_names2(uni, 1, 0); for (i=0; i<uni.size(); i++) { const wcstring &key = uni.at(i); const wchar_t *val = env_universal_get(key.c_str()); if (wcscmp(val, ENV_NULL)) { // Note that std::map::insert does NOT overwrite a value already in the map, // which we depend on here vals.insert(std::pair<wcstring, wcstring>(key, val)); } } std::vector<std::string> local_export_buffer; export_func(vals, local_export_buffer); export_array.set(local_export_buffer); has_changed_exported=false; } }
int main( void ) { unsigned int (*orig_fp)(); orig_fp = some_func; // call some_func printf( "some_func = %08x\n", orig_fp() ); // export some_func to file, comment as needed export_func( (void (*)()) orig_fp, "some_func.bin" ); unsigned int (*fp)(); unsigned char *cb = NULL; int cb_sz = 0; // import imp_func from file, comment as needed fp = (unsigned int (*)()) import_func( "some_func.bin", &cb, &cb_sz ); // DEBUG: print addresses printf( "main: ofp @ %08x\n", ( unsigned int ) ((unsigned int *)orig_fp) ); printf( "main: fp @ %08x\n", ( unsigned int ) ((unsigned int *)fp) ); // DEBUG: print imp_func size + contents int i=0; printf( "imp_func size = %d\nimp_func:\n", cb_sz ); for( i=0; i<cb_sz; i+=4 ) printf( " %02x %02x %02x %02x\n", (unsigned int) cb[i], (unsigned int) cb[i+1], (unsigned int) cb[i+2], (unsigned int) cb[i+3] ); // call imp_func // <- runs on older kernels <= 2.6.x // <- fails on more recent kernels (>= 3.x) printf( "imp_func = %d\n", fp() ); free( cb ); return 0; }