Exemplo n.º 1
0
void *jitcode(dasm_State **state)
{
	size_t size;
	int dasm_status = dasm_link(state, &size);
	assert(dasm_status == DASM_S_OK);

	// Allocate memory readable and writable so we can
	// write the encoded instructions there.
	char *mem = malloc(size + sizeof(size_t));
	assert(mem != NULL);

	// Store length at the beginning of the region, so we
	// can free it without additional context.
	*(size_t *) mem = size;
	void *ret = mem + sizeof(size_t);

	dasm_encode(state, ret);
	dasm_free(state);

#ifndef NDEBUG
	// Write generated machine code to a temporary file.
	// View with: (x86-64)
	//  objdump -D -b binary -mi386 -Mx86-64 /tmp/jitcode
	// Or: (arm)
	//  arm-linux-gnueabihf-objdump -D -b binary -marm /tmp/jitcode
	FILE *f = fopen("jitcode", "wb");
	fwrite(ret, size, 1, f);
	fclose(f);
#endif

	return ret;
}
Exemplo n.º 2
0
int build_code(Dst_DECL)
{
  int ret = 0;
  size_t codesz = 0;
  uint8_t* code = NULL;

  int nglob = GLOB_MAX;
  void **glob = (void **)malloc(nglob*sizeof(void *));
  memset(glob, 0, nglob*sizeof(void *));

  dasm_init(Dst, DASM_MAXSECTION);
  dasm_setupglobal(Dst, glob, nglob);
  dasm_setup(Dst, build_actionlist);

  (void)create_backend(Dst);

  /* Finalize */
  (void)dasm_checkstep(Dst, -1); /* sanity check */
  if((ret = dasm_link(Dst, &codesz))) return ret;
  code = (uint8_t *)pa_malloc(codesz, true);
  if((ret = dasm_encode(Dst, (void *)code))) return ret;

  //write_raw("debug.out", code, codesz);

  dasm_gen_func fp = (dasm_gen_func)code;
  ret = fp();

  printf("generated function return value = %d\n",ret);

  dasm_free(Dst);
  free(glob);
  free(code);
  return 0;
}
Exemplo n.º 3
0
static compiled_code_t make_exec(program_t *prog, dasm_State **state) {
  size_t size;
  int dasm_status = dasm_link(state, &size);
  assert(dasm_status == DASM_S_OK);
  (void) dasm_status;

  ensure_space(prog, size);

  /*  For performance reasons, we care about page RWX access only in
   *  when asserts are enabled.  */
  int result =
      mprotect(prog->codepages, prog->codepages->size, PROT_READ | PROT_WRITE);
  assert(result == 0);
  (void) result;

  compiled_code_t code = (compiled_code_t) prog->begin;
  prog->begin += size;

  dasm_encode(state, code);
  dasm_free(state);

  result = mprotect(prog->codepages, size, PROT_EXEC | PROT_READ);
  assert(result == 0);
  (void) result;

  return code;
}
Exemplo n.º 4
0
static cfunction compile(struct jit* jit, lua_State* L, cfunction func, int ref)
{
    struct jit_head* code;
    size_t codesz;
    int err;

    dasm_checkstep(jit, -1);
    if ((err = dasm_link(jit, &codesz)) != 0) {
        char buf[32];
        sprintf(buf, "%x", err);
        luaL_error(L, "dasm_link error %s", buf);
    }

    codesz += sizeof(struct jit_head);
    code = (struct jit_head*) reserve_code(jit, L, codesz);
    code->ref = ref;
    code->size = codesz;
    compile_extern_jump(jit, L, func, code->jump);

    if ((err = dasm_encode(jit, code+1)) != 0) {
        char buf[32];
        sprintf(buf, "%x", err);
        commit_code(jit, code, 0);
        luaL_error(L, "dasm_encode error %s", buf);
    }

    commit_code(jit, code, codesz);
    return (cfunction) (code+1);
}
Exemplo n.º 5
0
static void* link_and_encode(dasm_State**d) {
    size_t sz;
    void* buf;
    dasm_link(d, &sz);
    buf = mmap(0, sz, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
    dasm_encode(d, buf);
    //dumpcode(buf, sz);
    mprotect(buf, sz, PROT_READ|PROT_EXEC);
    return buf;
}
Exemplo n.º 6
0
static void* _jitcode_new(dasm_State** state){
  size_t size;
  assert(dasm_link(state, &size)==DASM_S_OK);
  // printf("_jitcode_new size: %zd\n", size);

  char *mem = (char*)mmap(NULL, size + sizeof(size_t),
                          PROT_READ | PROT_WRITE,
                          MAP_ANON | MAP_PRIVATE, -1, 0);
  assert(mem != MAP_FAILED);

  *(size_t*)mem = size;
  void *ret = mem + sizeof(size_t);

  dasm_encode(state, ret);

  assert(mprotect(mem, size, PROT_EXEC | PROT_READ)==0);
  return ret;
}
Exemplo n.º 7
0
static void* link_and_encode(dasm_State** d)
{
  size_t sz;
  void* buf;
  dasm_link(d, &sz);
#ifdef _WIN32
  buf = VirtualAlloc(0, sz, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
#else
  buf = mmap(0, sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
#endif
  dasm_encode(d, buf);
#ifdef _WIN32
  {DWORD dwOld; VirtualProtect(buf, sz, PAGE_EXECUTE_READ, &dwOld); }
#else
  mprotect(buf, sz, PROT_READ | PROT_EXEC);
#endif
  return buf;
}
Exemplo n.º 8
0
/* Link generated code. Return mcode address, size and status. */
int luaJIT_link(jit_State *J, void **mcodep, size_t *szp)
{
  size_t sz;
  void *mcode;

  /* Pass 2: link sections. */
  if ((J->dasmstatus = dasm_link(Dst, &sz))) return JIT_S_DASM_ERROR;

  /* Check for hardcoded limit on mcode size. */
  if (sz > LUAJIT_LIM_MCODE) return JIT_S_TOOLARGE;

  /* TODO: mark mcode readonly when we're done. */
  mcode = mcode_alloc(J, sz);

  /* Pass 3: encode sections. */
  if ((J->dasmstatus = dasm_encode(Dst, mcode))) {
    mcode_free(J->L, J, mcode, sz);
    return JIT_S_DASM_ERROR;
  }
  *mcodep = mcode;
  *szp = sz;
  return JIT_S_OK;
}
Exemplo n.º 9
0
void *jitcode(dasm_State **state) {
  size_t size;
  int dasm_status = dasm_link(state, &size);
  assert(dasm_status == DASM_S_OK);

  // Allocate memory readable and writable so we can
  // write the encoded instructions there.
  char *mem = mmap(NULL, size + sizeof(size_t),
		   PROT_READ | PROT_WRITE,
                   MAP_ANON | MAP_PRIVATE, -1, 0);
  assert(mem != MAP_FAILED);

  // Store length at the beginning of the region, so we
  // can free it without additional context.
  *(size_t*)mem = size;
  void *ret = mem + sizeof(size_t);

  dasm_encode(state, ret);
  dasm_free(state);

  // Adjust the memory permissions so it is executable
  // but no longer writable.
  int success = mprotect(mem, size, PROT_EXEC | PROT_READ);
  assert(success == 0);

#ifndef NDEBUG
  // Write generated machine code to a temporary file.
  // View with:
  //  objdump -D -b binary -mi386 -Mx86-64 /tmp/jitcode
  FILE *f = fopen("/tmp/jitcode", "wb");
  fwrite(ret, size, 1, f);
  fclose(f);
#endif

  return ret;
}
Exemplo n.º 10
0
/* Build the machine code. */
static int build_code(BuildCtx *ctx)
{
  int status;
  int i;

  /* Initialize DynASM structures. */
  ctx->nglob = GLOB__MAX;
  ctx->glob = (void **)malloc(ctx->nglob*sizeof(void *));
  memset(ctx->glob, 0, ctx->nglob*sizeof(void *));
  ctx->nreloc = 0;

  ctx->globnames = globnames;
  ctx->relocsym = (const char **)malloc(NRELOCSYM*sizeof(const char *));
  ctx->nrelocsym = 0;
  for (i = 0; i < (int)NRELOCSYM; i++) relocmap[i] = -1;

  ctx->dasm_ident = DASM_IDENT;
  ctx->dasm_arch = DASM_ARCH;

  dasm_init(Dst, DASM_MAXSECTION);
  dasm_setupglobal(Dst, ctx->glob, ctx->nglob);
  dasm_setup(Dst, build_actionlist);

  /* Call arch-specific backend to emit the code. */
  ctx->npc = build_backend(ctx);

  /* Finalize the code. */
  (void)dasm_checkstep(Dst, -1);
  if ((status = dasm_link(Dst, &ctx->codesz))) return status;
  ctx->code = (uint8_t *)malloc(ctx->codesz);
  if ((status = dasm_encode(Dst, (void *)ctx->code))) return status;

  /* Allocate symbol table and bytecode offsets. */
  ctx->beginsym = sym_decorate(ctx, "", LABEL_PREFIX "vm_asm_begin");
  ctx->sym = (BuildSym *)malloc((ctx->npc+ctx->nglob+1)*sizeof(BuildSym));
  ctx->nsym = 0;
  ctx->bc_ofs = (int32_t *)malloc(ctx->npc*sizeof(int32_t));

  /* Collect the opcodes (PC labels). */
  for (i = 0; i < ctx->npc; i++) {
    int32_t ofs = dasm_getpclabel(Dst, i);
    if (ofs < 0) return 0x22000000|i;
    ctx->bc_ofs[i] = ofs;
    if ((LJ_HASJIT ||
	 !(i == BC_JFORI || i == BC_JFORL || i == BC_JITERL || i == BC_JLOOP ||
	   i == BC_IFORL || i == BC_IITERL || i == BC_ILOOP)) &&
	(LJ_HASFFI || i != BC_KCDATA))
      sym_insert(ctx, ofs, LABEL_PREFIX_BC, bc_names[i]);
  }

  /* Collect the globals (named labels). */
  for (i = 0; i < ctx->nglob; i++) {
    const char *gl = globnames[i];
    int len = (int)strlen(gl);
    if (!ctx->glob[i]) {
      fprintf(stderr, "Error: undefined global %s\n", gl);
      exit(2);
    }
    /* Skip the _Z symbols. */
    if (!(len >= 2 && gl[len-2] == '_' && gl[len-1] == 'Z'))
      sym_insert(ctx, (int32_t)((uint8_t *)(ctx->glob[i]) - ctx->code),
		 LABEL_PREFIX, globnames[i]);
  }

  /* Close the address range. */
  sym_insert(ctx, (int32_t)ctx->codesz, "", "");
  ctx->nsym--;

  dasm_free(Dst);

  return 0;
}
Exemplo n.º 11
0
SRE_API sre_int_t
sre_vm_thompson_jit_compile(sre_pool_t *pool, sre_program_t *prog,
    sre_vm_thompson_code_t **pcode)
{
#if (SRE_TARGET != SRE_ARCH_X64)
    return SRE_DECLINED;
#else
    int              status;
    size_t           codesz;
    size_t           size;
    unsigned char   *mem;
    dasm_State      *dasm;
    void           **glob;
    unsigned         nglobs = SRE_VM_THOMPSON_GLOB__MAX;

    sre_vm_thompson_code_t      *code;

    glob = sre_pcalloc(pool, nglobs * sizeof(void *));
    if (glob == NULL) {
        return SRE_ERROR;
    }

    dasm_init(&dasm, 1);
    dasm_setupglobal(&dasm, glob, nglobs);
    dasm_setup(&dasm, sre_vm_thompson_jit_actions);

    dd("thread size: %d", (int) sizeof(sre_vm_thompson_thread_t));

    if (sre_vm_thompson_jit_do_compile(&dasm, pool, prog) != SRE_OK) {
        dasm_free(&dasm);
        return SRE_ERROR;
    }

    status = dasm_link(&dasm, &codesz);
    if (status != DASM_S_OK) {
        dasm_free(&dasm);
        return SRE_ERROR;
    }

    size = codesz + sizeof(sre_vm_thompson_code_t);

    dd("size: %d, codesiz: %d", (int) size, (int) codesz);

    mem = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
    if (mem == MAP_FAILED) {
        perror("mmap");
        dasm_free(&dasm);
        return SRE_ERROR;
    }

    code = (sre_vm_thompson_code_t *) mem;

    code->size = size;
    code->handler = (sre_vm_thompson_exec_pt)
        (mem + sizeof(sre_vm_thompson_code_t));

    *pcode = code;

    dasm_encode(&dasm, code->handler);

#if (DDEBUG)
    {
        int              i;
        int              len;
        FILE            *f;
        const char      *gl;

        /*
         * write generated machine code to a temporary file.
         * wiew with objdump or ndisasm
         */
        f = fopen("/tmp/thompson-jit.bin", "wb");
        fwrite(code->handler, codesz, 1, f);
        fclose(f);

        f = fopen("/tmp/thompson-jit.txt", "w");
        fprintf(f, "code section: start=%p len=%lu\n", code->handler,
                (unsigned long) codesz);

        fprintf(f, "global names:\n");

        for (i = 0; i < nglobs; i++) {
            gl = sre_vm_thompson_jit_global_names[i];
            len = (int) strlen(gl);
            if (!glob[i]) {
                continue;
            }
            /* Skip the _Z symbols. */
            if (!(len >= 2 && gl[len-2] == '_' && gl[len-1] == 'Z')) {
                fprintf(f, "  %s => %p\n", gl, glob[i]);
            }
        }

        fprintf(f, "\npc labels:\n");
        for (i = 0; i < dasm->pcsize; i++) {
            int32_t ofs = dasm_getpclabel(&dasm, i);
            if (ofs >= 0) {
                fprintf(f, "  %d => %ld\n", i, (long) ofs);
            }
        }

        fclose(f);
    }
#endif

    dasm_free(&dasm);

    if (mprotect(mem, size, PROT_EXEC | PROT_READ) != 0) {
        (void) munmap(code, code->size);
        return SRE_ERROR;
    }

    dd("code start addr: %p", code->handler);

    return SRE_OK;
#endif /* SRE_TARGET == SRE_ARCH_X64 */
}