Esempio n. 1
0
void
mono_arch_patch_callsite (guint8 *method_start, guint8 *orig_code, guint8 *addr)
{
	guint8 *code;
	guint8 buf [8];
	gboolean can_write = mono_breakpoint_clean_code (method_start, orig_code, 8, buf, sizeof (buf));

	code = buf + 8;

	/* go to the start of the call instruction
	 *
	 * address_byte = (m << 6) | (o << 3) | reg
	 * call opcode: 0xff address_byte displacement
	 * 0xff m=1,o=2 imm8
	 * 0xff m=2,o=2 imm32
	 */
	code -= 6;
	orig_code -= 6;
	if (code [1] == 0xe8) {
		if (can_write) {
			mono_atomic_xchg_i32 ((gint32*)(orig_code + 2), (guint)addr - ((guint)orig_code + 1) - 5);

			/* Tell valgrind to recompile the patched code */
			VALGRIND_DISCARD_TRANSLATIONS (orig_code + 2, 4);
		}
	} else if (code [1] == 0xe9) {
		/* A PLT entry: jmp <DISP> */
		if (can_write)
			mono_atomic_xchg_i32 ((gint32*)(orig_code + 2), (guint)addr - ((guint)orig_code + 1) - 5);
	} else {
		printf ("Invalid trampoline sequence: %x %x %x %x %x %x %x\n", code [0], code [1], code [2], code [3],
				code [4], code [5], code [6]);
		g_assert_not_reached ();
	}
}
Esempio n. 2
0
int main ( void )
{
  printf("fooble-1() = %d\n", fooble() );
  (void)VALGRIND_DISCARD_TRANSLATIONS( (char*)(&fooble), 
          ((char*)(&someother)) - ((char*)(&fooble)) );
  printf("fooble-2() = %d\n", fooble() );
  return 0;
}
Esempio n. 3
0
/* Synchronize data/instruction cache. */
void lj_mcode_sync(void *start, void *end)
{
#ifdef LUAJIT_USE_VALGRIND
  VALGRIND_DISCARD_TRANSLATIONS(start, (char *)end-(char *)start);
#endif
#if LJ_TARGET_X86ORX64
  UNUSED(start); UNUSED(end);
#elif LJ_TARGET_IOS
  sys_icache_invalidate(start, (char *)end-(char *)start);
#elif LJ_TARGET_PPC
  lj_vm_cachesync(start, end);
#elif defined(__GNUC__)
  __clear_cache(start, end);
#else
#error "Missing builtin to flush instruction cache"
#endif
}
Esempio n. 4
0
/**
 * 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;
}
Esempio n. 5
0
void llvm::sys::ValgrindDiscardTranslations(const void *Addr, size_t Len) {
  if (NotUnderValgrind)
    return;

  VALGRIND_DISCARD_TRANSLATIONS(Addr, Len);
}
Esempio n. 6
0
void Object::gcScavenge(ThreadState *ts) {
  switch (getTag()) {
    case RawObject::kPairTag:
      ts->gcScavenge(&raw()->car());
      ts->gcScavenge(&raw()->cdr());
      break;

    case RawObject::kSymbolTag:
      break;

    case RawObject::kSingletonTag:
    case RawObject::kFixnumTag:
      assert(0 && "Object::gcScavenge: not heap allocated");

    case RawObject::kClosureTag:
    {
      RawObject *info = raw()->cloInfo();
      if (!info) {
        // info is NULL? happens when a supercombinator
        // is just being compiled in the codegen.
        break;
      }
      Object **payload = raw()->cloPayload();
      for (intptr_t i = 0; i < info->funcNumPayload(); ++i) {
        ts->gcScavenge(payload + i);
      }
      ts->gcScavenge(&info->funcName());
      ts->gcScavenge(&info->funcConstOffset());

      // Scavenge const ptrs in code
      // @See codegen2.cpp
      //Util::logObj("scavenge code", info->funcConstOffset());
      intptr_t len = info->funcConstOffset()->raw()->vectorSize();
      for (intptr_t i = 0; i < len; ++i) {
        intptr_t offset = info->funcConstOffset()->
                          raw()->vectorAt(i)->fromFixnum();
        intptr_t ptrLoc = info->funcCodeAs<intptr_t>() + offset;

        //Object *oldPtrVal = *(Object **) ptrLoc;

        ts->gcScavenge(reinterpret_cast<Object **>(ptrLoc));

        //dprintf(2, "[ScavCodeReloc] %s[%ld] (which is %p) %p => %p ",
        //        info->funcName()->rawSymbol(),
        //        offset,
        //        (void *) ptrLoc,
        //        *(Object **) ptrLoc,
        //        oldPtrVal);

        //(*(Object **) ptrLoc)->displayDetail(2);
        //dprintf(2, "\n");
      }

      // And instructs valgrind to discard out-of-date jitted codes
      // Must do this since we have changed our code
      VALGRIND_DISCARD_TRANSLATIONS(
          info->funcCodeAs<char *>(),
          info->funcCodeAs<char *>() + info->funcSize() -
          RawObject::kFuncCodeOffset);
      break;
    }
    case RawObject::kVectorTag:
    {
      Object **elems = &raw()->vectorElem();
      for (intptr_t i = 0; i < raw()->vectorSize(); ++i) {
        ts->gcScavenge(elems + i);
      }
      break;
    }
    default:
      assert(0 && "Object::gcScavenge: not a tagged object");
  }
}