int orc_code_region_allocate_codemem_dual_map (OrcCodeRegion *region, const char *dir, int force_unlink) { int fd; int n; char *filename; mode_t mask; filename = malloc (strlen ("/orcexec..") + strlen (dir) + 6 + 1); sprintf(filename, "%s/orcexec.XXXXXX", dir); mask = umask (0066); fd = mkstemp (filename); umask (mask); if (fd == -1) { ORC_WARNING ("failed to create temp file"); free (filename); return FALSE; } if (force_unlink || !_orc_compiler_flag_debug) { unlink (filename); } free (filename); n = ftruncate (fd, SIZE); if (n < 0) { ORC_WARNING("failed to expand file to size"); close (fd); return FALSE; } region->exec_ptr = mmap (NULL, SIZE, PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0); if (region->exec_ptr == MAP_FAILED) { ORC_WARNING("failed to create exec map"); close (fd); return FALSE; } region->write_ptr = mmap (NULL, SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (region->write_ptr == MAP_FAILED) { ORC_WARNING ("failed to create write map"); munmap (region->exec_ptr, SIZE); close (fd); return FALSE; } region->size = SIZE; close (fd); return TRUE; }
int orc_code_region_allocate_codemem_anon_map (OrcCodeRegion *region) { region->exec_ptr = mmap (NULL, SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if (region->exec_ptr == MAP_FAILED) { ORC_WARNING("failed to create write/exec map"); return FALSE; } region->write_ptr = region->exec_ptr; region->size = SIZE; return TRUE; }
/** * orc_program_compile_full: * @program: the OrcProgram to compile * * Compiles an Orc program for the given target, using the * given target flags. * * Returns: an OrcCompileResult */ OrcCompileResult orc_program_compile_full (OrcProgram *program, OrcTarget *target, unsigned int flags) { OrcCompiler *compiler; int i; OrcCompileResult result; ORC_INFO("initializing compiler for program \"%s\"", program->name); compiler = malloc (sizeof(OrcCompiler)); memset (compiler, 0, sizeof(OrcCompiler)); if (program->backup_func) { program->code_exec = program->backup_func; } else { program->code_exec = (void *)orc_executor_emulate; } compiler->program = program; compiler->target = target; compiler->target_flags = flags; { ORC_LOG("variables"); for(i=0;i<ORC_N_VARIABLES;i++){ if (program->vars[i].size > 0) { ORC_LOG("%d: %s size %d type %d alloc %d", i, program->vars[i].name, program->vars[i].size, program->vars[i].vartype, program->vars[i].alloc); } } ORC_LOG("instructions"); for(i=0;i<program->n_insns;i++){ ORC_LOG("%d: %s %d %d %d %d", i, program->insns[i].opcode->name, program->insns[i].dest_args[0], program->insns[i].dest_args[1], program->insns[i].src_args[0], program->insns[i].src_args[1]); } } memcpy (compiler->insns, program->insns, program->n_insns * sizeof(OrcInstruction)); compiler->n_insns = program->n_insns; memcpy (compiler->vars, program->vars, ORC_N_VARIABLES * sizeof(OrcVariable)); memset (compiler->vars + ORC_N_VARIABLES, 0, (ORC_N_COMPILER_VARIABLES - ORC_N_VARIABLES) * sizeof(OrcVariable)); compiler->n_temp_vars = program->n_temp_vars; compiler->n_dup_vars = 0; for(i=0;i<32;i++) { compiler->valid_regs[i] = 1; } orc_compiler_check_sizes (compiler); if (compiler->error) goto error; if (compiler->target) { compiler->target->compiler_init (compiler); } orc_compiler_rewrite_insns (compiler); if (compiler->error) goto error; orc_compiler_rewrite_vars (compiler); if (compiler->error) goto error; if (compiler->target) { orc_compiler_global_reg_alloc (compiler); orc_compiler_rewrite_vars2 (compiler); } #if 0 { ORC_ERROR("variables"); for(i=0;i<ORC_N_VARIABLES;i++){ if (compiler->vars[i].size > 0) { ORC_ERROR("%d: %s size %d type %d alloc %d [%d,%d]", i, compiler->vars[i].name, compiler->vars[i].size, compiler->vars[i].vartype, compiler->vars[i].alloc, compiler->vars[i].first_use, compiler->vars[i].last_use); } } ORC_ERROR("instructions"); for(i=0;i<compiler->n_insns;i++){ ORC_ERROR("%d: %s %d %d %d %d", i, compiler->insns[i].opcode->name, compiler->insns[i].dest_args[0], compiler->insns[i].dest_args[1], compiler->insns[i].src_args[0], compiler->insns[i].src_args[1]); } } #endif if (compiler->error) goto error; program->orccode = orc_code_new (); program->orccode->is_2d = program->is_2d; program->orccode->constant_n = program->constant_n; program->orccode->constant_m = program->constant_m; program->orccode->exec = program->code_exec; program->orccode->n_insns = compiler->n_insns; program->orccode->insns = malloc(sizeof(OrcInstruction) * compiler->n_insns); memcpy (program->orccode->insns, compiler->insns, sizeof(OrcInstruction) * compiler->n_insns); program->orccode->vars = malloc (sizeof(OrcCodeVariable) * ORC_N_COMPILER_VARIABLES); memset (program->orccode->vars, 0, sizeof(OrcCodeVariable) * ORC_N_COMPILER_VARIABLES); for(i=0;i<ORC_N_COMPILER_VARIABLES;i++){ program->orccode->vars[i].vartype = compiler->vars[i].vartype; program->orccode->vars[i].size = compiler->vars[i].size; program->orccode->vars[i].value = compiler->vars[i].value; } if (program->backup_func && _orc_compiler_flag_backup) { orc_compiler_error (compiler, "Compilation disabled, using backup"); compiler->result = ORC_COMPILE_RESULT_UNKNOWN_COMPILE; goto error; } if (_orc_compiler_flag_emulate || target == NULL) { program->code_exec = (void *)orc_executor_emulate; program->orccode->exec = (void *)orc_executor_emulate; orc_compiler_error (compiler, "Compilation disabled, using emulation"); compiler->result = ORC_COMPILE_RESULT_UNKNOWN_COMPILE; goto error; } orc_compiler_assign_rules (compiler); if (compiler->error) goto error; ORC_INFO("allocating code memory"); compiler->code = malloc(65536); compiler->codeptr = compiler->code; if (compiler->error) goto error; ORC_INFO("compiling for target \"%s\"", compiler->target->name); compiler->target->compile (compiler); if (compiler->error) { compiler->result = ORC_COMPILE_RESULT_UNKNOWN_COMPILE; goto error; } program->orccode->code_size = compiler->codeptr - compiler->code; orc_code_allocate_codemem (program->orccode, program->orccode->code_size); memcpy (program->orccode->code, compiler->code, program->orccode->code_size); #ifdef VALGRIND_DISCARD_TRANSLATIONS VALGRIND_DISCARD_TRANSLATIONS (program->orccode->exec, program->orccode->code_size); #endif if (compiler->target->flush_cache) { compiler->target->flush_cache (program->orccode); } program->code_exec = program->orccode->exec; program->asm_code = compiler->asm_code; result = compiler->result; for (i=0;i<compiler->n_dup_vars;i++){ free(compiler->vars[ORC_VAR_T1 + compiler->n_temp_vars + i].name); compiler->vars[ORC_VAR_T1 + compiler->n_temp_vars + i].name = NULL; } free (compiler->code); compiler->code = NULL; if (compiler->output_insns) free (compiler->output_insns); free (compiler); ORC_INFO("finished compiling (success)"); return result; error: if (compiler->error_msg) { ORC_WARNING ("program %s failed to compile, reason: %s", program->name, compiler->error_msg); } else { ORC_WARNING("program %s failed to compile, reason %d", program->name, compiler->result); } result = compiler->result; if (program->error_msg) free (program->error_msg); program->error_msg = compiler->error_msg; if (result == 0) { result = ORC_COMPILE_RESULT_UNKNOWN_COMPILE; } if (compiler->asm_code) { free (compiler->asm_code); compiler->asm_code = NULL; } for (i=0;i<compiler->n_dup_vars;i++){ free(compiler->vars[ORC_VAR_T1 + compiler->n_temp_vars + i].name); compiler->vars[ORC_VAR_T1 + compiler->n_temp_vars + i].name = NULL; } free (compiler->code); compiler->code = NULL; if (compiler->output_insns) free (compiler->output_insns); free (compiler); ORC_INFO("finished compiling (fail)"); return result; }