コード例 #1
0
/* Debugging output */
void
ML_(am_show_segnames)(Int logLevel, const HChar *prefix)
{
   UInt size, ix, i;

   VG_(debugLog)(logLevel, "aspacem", "%u segment names in %u slots\n",
                 num_segnames, num_slots);

   if (freeslot_chain == end_of_chain)
      VG_(debugLog)(logLevel, "aspacem", "freelist is empty\n");
   else
      VG_(debugLog)(logLevel, "aspacem", "freelist begins at %u\n",
                    freeslot_chain);
   for (i = 0, ix = overhead; (size = get_slotsize(ix)) != 0;
        ix += size + overhead, ++i) {
      if (is_freeslot(ix))
         VG_(debugLog)(logLevel, "aspacem",
                       "(%u,%u,0) [free slot: size=%u  next=%u]\n", i, ix,
                       get_slotsize(ix), get_slotindex(ix));
      else
         VG_(debugLog)(logLevel, "aspacem",
                       "(%u,%u,%u) %s\n", i, ix, get_refcount(ix),
                       segnames + ix);
   }
}
コード例 #2
0
ファイル: fog_of_war.cpp プロジェクト: anttisalonen/kingdoms
void fog_of_war::down_refcount(int x, int y)
{
	int i = get_refcount(x, y);
	if(i == 0)
		return;
	int v = get_value(x, y);
	fog.set(x, y, ((i - 1) << 2) | v);
}
コード例 #3
0
static void
inc_refcount(UInt ix)
{
   aspacem_assert(ix >= overhead && ix <= segnames_used);
   UInt rc = get_refcount(ix);
   if (rc != max_refcount)
      put_refcount(ix, rc + 1);
}
コード例 #4
0
ファイル: fbt_linux.c プロジェクト: HackLinux/linux
/*ARGSUSED*/
static void
fbt_destroy(void *arg, dtrace_id_t id, void *parg)
{
	fbt_probe_t *fbt = parg, *next, *hash, *last;
	struct modctl *ctl = fbt->fbtp_ctl;
	struct module *mp = ctl;
	int ndx;

	do {
//printk("refc=%d load=%d\n", get_refcount(mp), fbt->fbtp_loadcnt);
		if (mp != NULL && get_refcount(mp) == fbt->fbtp_loadcnt) {
			if ((get_refcount(mp) == fbt->fbtp_loadcnt &&
			    mp->state == MODULE_STATE_LIVE)) {
			    	par_module_t *pmp = par_alloc(PARD_FBT, mp, sizeof *pmp, NULL);
				if (pmp && --pmp->fbt_nentries == 0)
					par_free(PARD_FBT, pmp);
			}
		}

		/*
		 * Now we need to remove this probe from the fbt_probetab.
		 */
		ndx = FBT_ADDR2NDX(fbt->fbtp_patchpoint);
		last = NULL;
		hash = fbt_probetab[ndx];

		while (hash != fbt) {
			ASSERT(hash != NULL);
			last = hash;
			hash = hash->fbtp_hashnext;
		}

		if (last != NULL) {
			last->fbtp_hashnext = fbt->fbtp_hashnext;
		} else {
			fbt_probetab[ndx] = fbt->fbtp_hashnext;
		}

		next = fbt->fbtp_next;
		kmem_free(fbt, sizeof (fbt_probe_t));

		fbt = next;
	} while (fbt != NULL);
}
コード例 #5
0
ファイル: fog_of_war.cpp プロジェクト: anttisalonen/kingdoms
void fog_of_war::shade(int x, int y, int radius)
{
	for(int i = x - radius; i <= x + radius; i++) {
		for(int j = y - radius; j <= y + radius; j++) {
			int di = m->wrap_x(i);
			int dj = m->wrap_y(j);
			down_refcount(di, dj);
			if(get_refcount(di, dj) == 0)
				set_value(di, dj, 1);
		}
	}
}
コード例 #6
0
ファイル: fbt_linux.c プロジェクト: HackLinux/linux
static int
fbt_prov_entry(pf_info_t *infp, instr_t *instr, int size, int modrm)
{
	fbt_probe_t *fbt;

	/***********************************************/
	/*   Avoid patching a patched probe point.     */
	/***********************************************/
	if (*instr == 0xcc)
		return 1;

	/***********************************************/
	/*   This  is temporary. Because of the issue  */
	/*   of   %RIP   relative   addressing  modes  */
	/*   potentially not being addressable in our  */
	/*   single-step  jump  buffer, disable those  */
	/*   probes which look like one of these.      */
	/***********************************************/
	if (modrm >= 0 && (instr[modrm] & 0xc7) == 0x05) 
		return 1;

	fbt = kmem_zalloc(sizeof (fbt_probe_t), KM_SLEEP);
	fbt->fbtp_name = infp->name;

	fbt->fbtp_id = dtrace_probe_create(fbt_id, infp->modname,
	    infp->name, FBT_ENTRY, 3, fbt);
	num_probes++;
	fbt->fbtp_patchpoint = instr;
	fbt->fbtp_ctl = infp->mp; // ctl;
	fbt->fbtp_loadcnt = get_refcount(infp->mp);
	fbt->fbtp_rval = DTRACE_INVOP_ANY;
	/***********************************************/
	/*   Save  potential overwrite of instruction  */
	/*   and  length,  because  we  will need the  */
	/*   entire  instruction  when we single step  */
	/*   over it.				       */
	/***********************************************/
	fbt->fbtp_savedval = *instr;
	fbt->fbtp_inslen = size;
	fbt->fbtp_type = 0; /* entry */
//if (modrm >= 0 && (instr[modrm] & 0xc7) == 0x05) printk("modrm %s %p rm=%d\n", name, instr, modrm);
	fbt->fbtp_modrm = modrm;
	fbt->fbtp_patchval = FBT_PATCHVAL;

	fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
	fbt->fbtp_symndx = infp->symndx;
	fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;

	infp->pmp->fbt_nentries++;
	infp->retptr = NULL;

	return 1;
}
コード例 #7
0
ファイル: fbt_linux.c プロジェクト: HackLinux/linux
/*ARGSUSED*/
static void
fbt_disable(void *arg, dtrace_id_t id, void *parg)
{
	fbt_probe_t *fbt = parg;
	struct modctl *ctl = fbt->fbtp_ctl;
	struct module *mp = (struct module *) ctl;

# if 0
	ASSERT(ctl->mod_nenabled > 0);
	ctl->mod_nenabled--;

	if (!ctl->mod_loaded || (ctl->mod_loadcnt != fbt->fbtp_loadcnt))
		return;
# else
	if (mp->state != MODULE_STATE_LIVE ||
	    get_refcount(mp) != fbt->fbtp_loadcnt)
		return;
# endif

	for (; fbt != NULL; fbt = fbt->fbtp_next) {
		if (dtrace_here) {
			printk("%s:%d: Disable %p:%s:%s\n", 
				__func__, __LINE__, 
				fbt->fbtp_patchpoint, 
				fbt->fbtp_ctl->name,
				fbt->fbtp_name);
		}
		/***********************************************/
		/*   Memory  should  be  writable,  but if we  */
		/*   failed  in  the  fbt_enable  code,  e.g.  */
		/*   because  kernel  freed an .init section,  */
		/*   then  dont  try and unpatch something we  */
		/*   didnt patch.			       */
		/*   We  were  trying to be clever and ensure  */
		/*   memory is writable but this seems to GPF  */
		/*   on  us.  Might be a temporary issue as I  */
		/*   fiddle with other things tho.	       */
		/***********************************************/
		if (*fbt->fbtp_patchpoint == fbt->fbtp_patchval) {
			*fbt->fbtp_patchpoint = fbt->fbtp_savedval;

			/***********************************************/
			/*   "Logically"  mark  probe  as gone. So we  */
			/*   can  detect overruns. But even tho it is  */
			/*   disabled,  doesnt  mean we cannot handle  */
			/*   it.				       */
			/***********************************************/
			fbt->fbtp_enabled = FALSE;
		}
	}
}
コード例 #8
0
ファイル: vertexdeclaration.c プロジェクト: devyn/wine
static void test_get_set_vertex_declaration(IDirect3DDevice9 *device_ptr, IDirect3DVertexDeclaration9 *decl_ptr)
{
    IDirect3DVertexDeclaration9 *current_decl_ptr = 0;
    HRESULT hret = 0;
    int decl_refcount = 0;
    int i = 0;
    
    /* SetVertexDeclaration should not touch the declaration's refcount. */
    i = get_refcount((IUnknown *)decl_ptr);
    hret = IDirect3DDevice9_SetVertexDeclaration(device_ptr, decl_ptr);
    decl_refcount = get_refcount((IUnknown *)decl_ptr);
    ok(hret == D3D_OK && decl_refcount == i, "SetVertexDeclaration returned: hret 0x%x, refcount %d. "
        "Expected hret 0x%x, refcount %d.\n", hret, decl_refcount, D3D_OK, i);
    
    /* GetVertexDeclaration should increase the declaration's refcount by one. */
    i = decl_refcount+1;
    hret = IDirect3DDevice9_GetVertexDeclaration(device_ptr, &current_decl_ptr);
    decl_refcount = get_refcount((IUnknown *)decl_ptr);
    ok(hret == D3D_OK && decl_refcount == i && current_decl_ptr == decl_ptr, 
        "GetVertexDeclaration returned: hret 0x%x, current_decl_ptr %p refcount %d. "
        "Expected hret 0x%x, current_decl_ptr %p, refcount %d.\n", hret, current_decl_ptr, decl_refcount, D3D_OK, decl_ptr, i);
    IDirect3DVertexDeclaration9_Release(current_decl_ptr);
}
コード例 #9
0
ファイル: fbt_linux.c プロジェクト: HackLinux/linux
/*ARGSUSED*/
static int
fbt_enable(void *arg, dtrace_id_t id, void *parg)
{
	fbt_probe_t *fbt = parg;
	struct modctl *ctl = fbt->fbtp_ctl;
	struct module *mp = (struct module *) ctl;

# if 0
	ctl->mod_nenabled++;
# endif
	if (mp->state != MODULE_STATE_LIVE) {
		if (fbt_verbose) {
			cmn_err(CE_NOTE, "fbt is failing for probe %s "
			    "(module %s unloaded)",
			    fbt->fbtp_name, mp->name);
		}

		return 0;
	}

	/*
	 * Now check that our modctl has the expected load count.  If it
	 * doesn't, this module must have been unloaded and reloaded -- and
	 * we're not going to touch it.
	 */
	if (get_refcount(mp) != fbt->fbtp_loadcnt) {
		if (fbt_verbose) {
			cmn_err(CE_NOTE, "fbt is failing for probe %s "
			    "(module %s reloaded)",
			    fbt->fbtp_name, mp->name);
		}

		return 0;
	}

	for (; fbt != NULL; fbt = fbt->fbtp_next) {
		fbt->fbtp_enabled = TRUE;
		if (dtrace_here) 
			printk("fbt_enable:patch %p p:%02x %s\n", fbt->fbtp_patchpoint, fbt->fbtp_patchval, fbt->fbtp_name);
		if (memory_set_rw(fbt->fbtp_patchpoint, 1, TRUE)) {
			*fbt->fbtp_patchpoint = fbt->fbtp_patchval;
//printk("FBT: set pp=%p:%p\n", fbt->fbtp_patchpoint, *fbt->fbtp_patchpoint);
		}
	}
	return 0;
}
コード例 #10
0
ファイル: d3d11.c プロジェクト: xcution/wine
static void test_create_device(void)
{
    D3D_FEATURE_LEVEL feature_level, supported_feature_level;
    ID3D11DeviceContext *immediate_context = NULL;
    ID3D11Device *device;
    ULONG refcount;
    HRESULT hr;

    hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &device,
            NULL, NULL);
    if (FAILED(hr))
    {
        skip("Failed to create HAL device, skipping tests.\n");
        return;
    }

    supported_feature_level = ID3D11Device_GetFeatureLevel(device);
    ID3D11Device_Release(device);

    hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, NULL, NULL, NULL);
    ok(SUCCEEDED(hr), "D3D11CreateDevice failed %#x.\n", hr);

    hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, NULL,
            &feature_level, NULL);
    ok(SUCCEEDED(hr), "D3D11CreateDevice failed %#x.\n", hr);
    ok(feature_level == supported_feature_level, "Got feature level %#x, expected %#x.\n",
            feature_level, supported_feature_level);

    hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, NULL, NULL,
            &immediate_context);
    ok(SUCCEEDED(hr), "D3D11CreateDevice failed %#x.\n", hr);

    todo_wine ok(!!immediate_context, "Immediate context is NULL.\n");
    if (!immediate_context) return;

    refcount = get_refcount((IUnknown *)immediate_context);
    ok(refcount == 1, "Got refcount %u, expected 1.\n", refcount);

    ID3D11DeviceContext_GetDevice(immediate_context, &device);
    refcount = ID3D11Device_Release(device);
    ok(refcount == 1, "Got refcount %u, expected 1.\n", refcount);

    refcount = ID3D11DeviceContext_Release(immediate_context);
    ok(!refcount, "ID3D11DeviceContext has %u references left.\n", refcount);
}
コード例 #11
0
/*ARGSUSED*/
static void
instr_resume(void *arg, dtrace_id_t id, void *parg)
{
	instr_probe_t *fbt = parg;
	struct modctl *ctl = fbt->insp_ctl;
	struct module *mp = (struct module *) ctl;

# if 0
	ASSERT(ctl->mod_nenabled > 0);

	if (!ctl->mod_loaded || (ctl->mod_loadcnt != fbt->insp_loadcnt))
		return;
# else
	if (mp->state != MODULE_STATE_LIVE ||
	    get_refcount(mp) != fbt->insp_loadcnt)
		return;
# endif

	for (; fbt != NULL; fbt = fbt->insp_next)
		*fbt->insp_patchpoint = fbt->insp_patchval;
}
コード例 #12
0
/*ARGSUSED*/
static void
instr_disable(void *arg, dtrace_id_t id, void *parg)
{
	instr_probe_t *fbt = parg;
	struct modctl *ctl = fbt->insp_ctl;
	struct module *mp = (struct module *) ctl;

# if 0
	ASSERT(ctl->mod_nenabled > 0);
	ctl->mod_nenabled--;

	if (!ctl->mod_loaded || (ctl->mod_loadcnt != fbt->insp_loadcnt))
		return;
# else
	if (mp->state != MODULE_STATE_LIVE ||
	    get_refcount(mp) != fbt->insp_loadcnt)
		return;
# endif

	for (; fbt != NULL; fbt = fbt->insp_next) {
		if (dtrace_here) {
			printk("%s:%d: Disable %p:%s:%s\n", 
				__func__, __LINE__, 
				fbt->insp_patchpoint, 
				fbt->insp_ctl->name,
				fbt->insp_name);
		}
		/***********************************************/
		/*   Memory  should  be  writable,  but if we  */
		/*   failed  in  the  instr_enable  code,  e.g.  */
		/*   because  kernel  freed an .init section,  */
		/*   then  dont  try and unpatch something we  */
		/*   didnt patch.			       */
		/***********************************************/
		if (*fbt->insp_patchpoint == fbt->insp_patchval) {
			if (memory_set_rw(fbt->insp_patchpoint, 1, TRUE))
				*fbt->insp_patchpoint = fbt->insp_savedval;
		}
	}
}
コード例 #13
0
static void
dec_refcount(UInt ix)
{
   aspacem_assert(ix >= overhead && ix <= segnames_used);
   UInt rc = get_refcount(ix);
   aspacem_assert(rc > 0);
   if (rc != max_refcount) {
      --rc;
      if (rc != 0) {
         put_refcount(ix, rc);
      } else {
         UInt size = get_slotsize(ix);
         /* Chain this slot in the freelist */
         put_slotindex(ix, freeslot_chain);
         get_slotindex(ix);
         put_slotsize(ix + slotsize_size, size);
         get_slotindex(ix);
         freeslot_chain = ix;
         --num_segnames;
         if (0) VG_(am_show_nsegments)(0, "AFTER DECREASE rc -> 0");
      }
   }
}
コード例 #14
0
ファイル: fbt_linux.c プロジェクト: HackLinux/linux
static int
fbt_prov_return(pf_info_t *infp, instr_t *instr, int size)
{
	fbt_probe_t *fbt;
	fbt_probe_t *retfbt = infp->retptr;

# if defined(__i386) || defined(__amd64)
	if (*instr == 0xcc)
		return 1;
# endif
	/***********************************************/
	/*   Sanity check for bad things happening.    */
	/***********************************************/
	if (fbt_is_patched(infp->name, instr)) {
		return 0;
	}

	fbt = kmem_zalloc(sizeof (fbt_probe_t), KM_SLEEP);
	fbt->fbtp_name = infp->name;

	if (retfbt == NULL) {
		fbt->fbtp_id = dtrace_probe_create(fbt_id, infp->modname,
		    infp->name, FBT_RETURN, 3, fbt);
		num_probes++;
	} else {
		retfbt->fbtp_next = fbt;
		fbt->fbtp_id = retfbt->fbtp_id;
	}
	infp->retptr = fbt;
	fbt->fbtp_patchpoint = instr;
	fbt->fbtp_ctl = infp->mp; //ctl;
	fbt->fbtp_loadcnt = get_refcount(infp->mp);

	/***********************************************/
	/*   Swapped  sense  of  the  following ifdef  */
	/*   around so we are consistent.	       */
	/***********************************************/
	fbt->fbtp_rval = DTRACE_INVOP_ANY;
#if defined(__amd64)
	ASSERT(*instr == FBT_RET);
	fbt->fbtp_roffset =
	    (uintptr_t)(instr - (uint8_t *)infp->st_value);
#elif defined(__i386)
	fbt->fbtp_roffset =
	    (uintptr_t)(instr - (uint8_t *)infp->st_value) + 1;
#elif defined(__arm__)
	fbt->fbtp_roffset = 0;
#endif

	/***********************************************/
	/*   Save  potential overwrite of instruction  */
	/*   and  length,  because  we  will need the  */
	/*   entire  instruction  when we single step  */
	/*   over it.				       */
	/***********************************************/
	fbt->fbtp_savedval = *instr;
	fbt->fbtp_inslen = size;
	fbt->fbtp_type = 1; /* return */
	fbt->fbtp_modrm = -1;
	fbt->fbtp_patchval = FBT_PATCHVAL;
	fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
	fbt->fbtp_symndx = infp->symndx;

	fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;

	infp->pmp->fbt_nentries++;
	return 1;
}
コード例 #15
0
ファイル: vertexdeclaration.c プロジェクト: devyn/wine
/* Check whether a declaration converted from FVF is shared.
 * Check whether refcounts behave as expected */
static void test_fvf_decl_management(
    IDirect3DDevice9* device) {

    HRESULT hr;
    IDirect3DVertexDeclaration9* result_decl1 = NULL;
    IDirect3DVertexDeclaration9* result_decl2 = NULL;
    IDirect3DVertexDeclaration9* result_decl3 = NULL;
    IDirect3DVertexDeclaration9* result_decl4 = NULL;
    int ref1, ref2, ref3, ref4;

    DWORD test_fvf1 = D3DFVF_XYZRHW;
    DWORD test_fvf2 = D3DFVF_NORMAL;
    CONST D3DVERTEXELEMENT9 test_elements1[] =
        { { 0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0 }, D3DDECL_END() };
    CONST D3DVERTEXELEMENT9 test_elements2[] =
        { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0 }, D3DDECL_END() };

    /* Clear down any current vertex declaration */
    hr = IDirect3DDevice9_SetVertexDeclaration ( device, NULL );
    ok (SUCCEEDED(hr), "SetVertexDeclaration returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) return;

    /* Conversion */
    hr = IDirect3DDevice9_SetFVF( device, test_fvf1);
    ok(SUCCEEDED(hr), "SetFVF returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) return;

    /* Get converted decl (#1) */
    hr = IDirect3DDevice9_GetVertexDeclaration ( device, &result_decl1);
    ok(SUCCEEDED(hr), "GetVertexDeclaration returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) return;

    /* Get converted decl again (#2) */
    hr = IDirect3DDevice9_GetVertexDeclaration ( device, &result_decl2);
    ok(SUCCEEDED(hr), "GetVertexDeclaration returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) return;

    /* Conversion */
    hr = IDirect3DDevice9_SetFVF( device, test_fvf2);
    ok(SUCCEEDED(hr), "SetFVF returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) return;

    /* The contents should correspond to the first conversion */
    VDECL_CHECK(compare_elements(result_decl1, test_elements1));

    /* Get converted decl (#3) */
    hr = IDirect3DDevice9_GetVertexDeclaration ( device, &result_decl3);
    ok(SUCCEEDED(hr), "GetVertexDeclaration returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) return;

    /* The object should be the same */
    ok (result_decl1 == result_decl2, "Declaration object changes on the second Get() call\n");
    ok (result_decl2 != result_decl3, "Declaration object did not change during conversion\n");

    /* The contents should correspond to the second conversion */
    VDECL_CHECK(compare_elements(result_decl3, test_elements2));
    /* Re-Check if the first decl was overwritten by the new Get() */
    VDECL_CHECK(compare_elements(result_decl1, test_elements1));

    hr = IDirect3DDevice9_SetFVF( device, test_fvf1);
    ok(SUCCEEDED(hr), "SetFVF returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) return;

    hr = IDirect3DDevice9_GetVertexDeclaration ( device, &result_decl4);
    ok(SUCCEEDED(hr), "GetVertexDeclaration returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) return;

    ok(result_decl4 == result_decl1, "Setting an already used FVF over results in a different vertexdeclaration\n");

    ref1 = get_refcount((IUnknown*) result_decl1);
    ref2 = get_refcount((IUnknown*) result_decl2);
    ref3 = get_refcount((IUnknown*) result_decl3);
    ref4 = get_refcount((IUnknown*) result_decl4);
    ok (ref1 == 3, "Refcount #1 is %d, expected 3\n", ref1);
    ok (ref2 == 3, "Refcount #2 is %d, expected 3\n", ref2);
    ok (ref3 == 1, "Refcount #3 is %d, expected 1\n", ref3);
    ok (ref4 == 3, "Refcount #4 is %d, expected 3\n", ref4);

    /* Clear down any current vertex declaration */
    hr = IDirect3DDevice9_SetVertexDeclaration ( device, NULL );
    ok (SUCCEEDED(hr), "SetVertexDeclaration returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) return;

    IDirect3DVertexDeclaration9_Release(result_decl1);
    IDirect3DVertexDeclaration9_Release(result_decl2);
    IDirect3DVertexDeclaration9_Release(result_decl3);
    IDirect3DVertexDeclaration9_Release(result_decl4);

    return;
}
コード例 #16
0
ファイル: fog_of_war.cpp プロジェクト: anttisalonen/kingdoms
void fog_of_war::up_refcount(int x, int y)
{
	int i = get_refcount(x, y);
	int v = get_value(x, y);
	fog.set(x, y, ((i + 1) << 2) | v);
}
コード例 #17
0
ファイル: basic.cpp プロジェクト: bachir151/feelpp
/** Ensure the object may be modified without hurting others, throws if this
 *  is not the case. */
void basic::ensure_if_modifiable() const
{
    if (get_refcount() > 1)
        throw(std::runtime_error("cannot modify multiply referenced object"));
    clearflag(status_flags::hash_calculated | status_flags::evaluated);
}
コード例 #18
0
ファイル: device.c プロジェクト: YongHaoWu/wine-hub
static void test_private_data(void)
{
    ULONG refcount, expected_refcount;
    IDXGIDevice *device;
    HRESULT hr;
    IDXGIDevice *test_object;
    IUnknown *ptr;
    static const DWORD data[] = {1, 2, 3, 4};
    UINT size;
    static const GUID dxgi_private_data_test_guid =
    {
        0xfdb37466,
        0x428f,
        0x4edf,
        {0xa3, 0x7f, 0x9b, 0x1d, 0xf4, 0x88, 0xc5, 0xfc}
    };
    static const GUID dxgi_private_data_test_guid2 =
    {
        0x2e5afac2,
        0x87b5,
        0x4c10,
        {0x9b, 0x4b, 0x89, 0xd7, 0xd1, 0x12, 0xe7, 0x2b}
    };

    if (!(device = create_device()))
    {
        skip("Failed to create device, skipping tests.\n");
        return;
    }

    test_object = create_device();

    /* SetPrivateData with a pointer of NULL has the purpose of FreePrivateData in previous
     * d3d versions. A successful clear returns S_OK. A redundant clear S_FALSE. Setting a
     * NULL interface is not considered a clear but as setting an interface pointer that
     * happens to be NULL. */
    hr = IDXGIDevice_SetPrivateData(device, &dxgi_private_data_test_guid, 0, NULL);
    ok(hr == S_FALSE, "Got unexpected hr %#x.\n", hr);
    hr = IDXGIDevice_SetPrivateDataInterface(device, &dxgi_private_data_test_guid, NULL);
    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
    hr = IDXGIDevice_SetPrivateData(device, &dxgi_private_data_test_guid, ~0U, NULL);
    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
    hr = IDXGIDevice_SetPrivateData(device, &dxgi_private_data_test_guid, ~0U, NULL);
    ok(hr == S_FALSE, "Got unexpected hr %#x.\n", hr);

    hr = IDXGIDevice_SetPrivateDataInterface(device, &dxgi_private_data_test_guid, NULL);
    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
    size = sizeof(ptr) * 2;
    ptr = (IUnknown *)0xdeadbeef;
    hr = IDXGIDevice_GetPrivateData(device, &dxgi_private_data_test_guid, &size, &ptr);
    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
    ok(!ptr, "Got unexpected pointer %p.\n", ptr);
    ok(size == sizeof(IUnknown *), "Got unexpected size %u.\n", size);

    refcount = get_refcount((IUnknown *)test_object);
    hr = IDXGIDevice_SetPrivateDataInterface(device, &dxgi_private_data_test_guid,
            (IUnknown *)test_object);
    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
    expected_refcount = refcount + 1;
    refcount = get_refcount((IUnknown *)test_object);
    ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
    hr = IDXGIDevice_SetPrivateDataInterface(device, &dxgi_private_data_test_guid,
            (IUnknown *)test_object);
    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
    refcount = get_refcount((IUnknown *)test_object);
    ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);

    hr = IDXGIDevice_SetPrivateDataInterface(device, &dxgi_private_data_test_guid, NULL);
    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
    expected_refcount--;
    refcount = get_refcount((IUnknown *)test_object);
    ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);

    hr = IDXGIDevice_SetPrivateDataInterface(device, &dxgi_private_data_test_guid,
            (IUnknown *)test_object);
    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
    size = sizeof(data);
    hr = IDXGIDevice_SetPrivateData(device, &dxgi_private_data_test_guid, size, data);
    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
    refcount = get_refcount((IUnknown *)test_object);
    ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
    hr = IDXGIDevice_SetPrivateData(device, &dxgi_private_data_test_guid, 42, NULL);
    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
    hr = IDXGIDevice_SetPrivateData(device, &dxgi_private_data_test_guid, 42, NULL);
    ok(hr == S_FALSE, "Got unexpected hr %#x.\n", hr);

    hr = IDXGIDevice_SetPrivateDataInterface(device, &dxgi_private_data_test_guid,
            (IUnknown *)test_object);
    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
    expected_refcount++;
    size = 2 * sizeof(ptr);
    ptr = NULL;
    hr = IDXGIDevice_GetPrivateData(device, &dxgi_private_data_test_guid, &size, &ptr);
    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
    ok(size == sizeof(test_object), "Got unexpected size %u.\n", size);
    expected_refcount++;
    refcount = get_refcount((IUnknown *)test_object);
    ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
    if (ptr)
        IUnknown_Release(ptr);
    expected_refcount--;

    ptr = (IUnknown *)0xdeadbeef;
    size = 1;
    hr = IDXGIDevice_GetPrivateData(device, &dxgi_private_data_test_guid, &size, NULL);
    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
    ok(size == sizeof(device), "Got unexpected size %u.\n", size);
    size = 2 * sizeof(ptr);
    hr = IDXGIDevice_GetPrivateData(device, &dxgi_private_data_test_guid, &size, NULL);
    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
    ok(size == sizeof(device), "Got unexpected size %u.\n", size);
    refcount = get_refcount((IUnknown *)test_object);
    ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);

    size = 1;
    hr = IDXGIDevice_GetPrivateData(device, &dxgi_private_data_test_guid, &size, &ptr);
    ok(hr == DXGI_ERROR_MORE_DATA, "Got unexpected hr %#x.\n", hr);
    ok(size == sizeof(device), "Got unexpected size %u.\n", size);
    ok(ptr == (IUnknown *)0xdeadbeef, "Got unexpected pointer %p.\n", ptr);
    hr = IDXGIDevice_GetPrivateData(device, &dxgi_private_data_test_guid2, NULL, NULL);
    ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
    size = 0xdeadbabe;
    hr = IDXGIDevice_GetPrivateData(device, &dxgi_private_data_test_guid2, &size, &ptr);
    ok(hr == DXGI_ERROR_NOT_FOUND, "Got unexpected hr %#x.\n", hr);
    ok(size == 0, "Got unexpected size %u.\n", size);
    ok(ptr == (IUnknown *)0xdeadbeef, "Got unexpected pointer %p.\n", ptr);
    hr = IDXGIDevice_GetPrivateData(device, &dxgi_private_data_test_guid, NULL, &ptr);
    ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
    ok(ptr == (IUnknown *)0xdeadbeef, "Got unexpected pointer %p.\n", ptr);

    refcount = IDXGIDevice_Release(device);
    ok(!refcount, "Device has %u references left.\n", refcount);
    refcount = IDXGIDevice_Release(test_object);
    ok(!refcount, "Test object has %u references left.\n", refcount);
}
コード例 #19
0
static void
instr_provide_function(struct modctl *mp, par_module_t *pmp,
	char *modname, char *name, uint8_t *st_value,
	uint8_t *instr, uint8_t *limit, int symndx)
{
	int	do_print = FALSE;
	instr_probe_t *fbt;
	int	size;
	int	modrm;
	char	*orig_name = name;
	char	name_buf[128];
	char	pred_buf[128];

# define UNHANDLED_FBT() if (do_print || dtrace_unhandled) { \
		printk("fbt:unhandled instr %s:%p %02x %02x %02x %02x\n", \
			name, instr, instr[0], instr[1], instr[2], instr[3]); \
			}

# define INSTR(val, opcode_name) do {if (instr[0] == val) { \
	snprintf(name_buf, sizeof name_buf, "%s-%s", orig_name, opcode_name); \
	name = name_buf; \
	}} while (0)

	for (; instr < limit; instr += size) {
		/***********************************************/
		/*   Make sure we dont try and handle data or  */
		/*   bad instructions.			       */
		/***********************************************/
		if ((size = dtrace_instr_size_modrm(instr, &modrm)) <= 0)
			return;

		name_buf[0] = '\0';

		INSTR(0x70, "jo");
		INSTR(0x71, "jno");
		INSTR(0x72, "jb");
		INSTR(0x73, "jae");
		INSTR(0x74, "je");
		INSTR(0x75, "jne");
		INSTR(0x76, "jbe");
		INSTR(0x77, "ja");
		INSTR(0x78, "js");
		INSTR(0x79, "jns");
		INSTR(0x7a, "jp");
		INSTR(0x7b, "jnp");
		INSTR(0x7c, "jl");
		INSTR(0x7d, "jge");
		INSTR(0x7e, "jle");
		INSTR(0x7f, "jg");

		INSTR(0x90, "nop");

		INSTR(0xa6, "scas");
		INSTR(0xe0, "loopne");
		INSTR(0xe1, "loope");
		INSTR(0xe2, "loop");

		INSTR(0xe8, "callr");
		/***********************************************/
		/*   I  was debugging the fwd/back scenario -  */
		/*   dont need this now.		       */
		/***********************************************/
		if (0 && *instr == 0xe8) {
			if (instr[4] & 0x80)
				INSTR(0xe8, "callr-back");
			else
				INSTR(0xe8, "callr-fwd");
		}

		INSTR(0xf0, "lock");
		INSTR(0xf1, "icebp");
		INSTR(0xf2, "repz");
		INSTR(0xf3, "repz");
		INSTR(0xfa, "cli");
		INSTR(0xfb, "sti");
		
		if (name_buf[0] == 0) {
			continue;
		}

		sprintf(pred_buf, "0x%p", instr);
		/***********************************************/
		/*   Make  sure  this  doesnt overlap another  */
		/*   sym. We are in trouble when this happens  */
		/*   - eg we will mistaken what the emulation  */
		/*   is  for,  but  also,  it means something  */
		/*   strange  happens, like kernel is reusing  */
		/*   a  page  (eg  for init/exit section of a  */
		/*   module).				       */
		/***********************************************/
		if (instr_is_patched(name, instr))
			return;

		fbt = kmem_zalloc(sizeof (instr_probe_t), KM_SLEEP);
		fbt->insp_name = name;

		fbt->insp_id = dtrace_probe_create(instr_id, modname,
		    name, pred_buf, 3, fbt);
		num_probes++;
		fbt->insp_patchpoint = instr;
		fbt->insp_ctl = mp; // ctl;
		fbt->insp_loadcnt = get_refcount(mp);
		/***********************************************/
		/*   Save  potential overwrite of instruction  */
		/*   and  length,  because  we  will need the  */
		/*   entire  instruction  when we single step  */
		/*   over it.				       */
		/***********************************************/
		fbt->insp_savedval = *instr;
		fbt->insp_inslen = size;
	//if (modrm >= 0 && (instr[modrm] & 0xc7) == 0x05) printk("modrm %s %p rm=%d\n", name, instr, modrm);
		fbt->insp_modrm = modrm;
		fbt->insp_patchval = INSTR_PATCHVAL;

		fbt->insp_hashnext = instr_probetab[INSTR_ADDR2NDX(instr)];
		fbt->insp_symndx = symndx;
		instr_probetab[INSTR_ADDR2NDX(instr)] = fbt;

		if (do_print)
			printk("%d:alloc entry-patchpoint: %s %p sz=%d %02x %02x %02x\n", 
				__LINE__, 
				name, 
				fbt->insp_patchpoint, 
				fbt->insp_inslen,
				instr[0], instr[1], instr[2]);

		pmp->fbt_nentries++;
	}
}
コード例 #20
0
static void test_create_shader_resource_view(void)
{
    D3D10_SHADER_RESOURCE_VIEW_DESC1 srv_desc;
    D3D10_TEXTURE2D_DESC texture_desc;
    ULONG refcount, expected_refcount;
    ID3D10ShaderResourceView1 *srview;
    D3D10_BUFFER_DESC buffer_desc;
    ID3D10Texture2D *texture;
    ID3D10Device *tmp_device;
    ID3D10Device1 *device;
    ID3D10Buffer *buffer;
    IUnknown *iface;
    HRESULT hr;

    if (!(device = create_device(NULL)))
    {
        skip("Failed to create device.\n");
        return;
    }

    buffer_desc.ByteWidth = 1024;
    buffer_desc.Usage = D3D10_USAGE_DEFAULT;
    buffer_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
    buffer_desc.CPUAccessFlags = 0;
    buffer_desc.MiscFlags = 0;

    hr = ID3D10Device1_CreateBuffer(device, &buffer_desc, NULL, &buffer);
    ok(SUCCEEDED(hr), "Failed to create a buffer, hr %#x\n", hr);

    hr = ID3D10Device1_CreateShaderResourceView1(device, (ID3D10Resource *)buffer, NULL, &srview);
    ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);

    srv_desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
    srv_desc.ViewDimension = D3D10_1_SRV_DIMENSION_BUFFER;
    U(srv_desc).Buffer.ElementOffset = 0;
    U(srv_desc).Buffer.ElementWidth = 64;

    expected_refcount = get_refcount((IUnknown *)device) + 1;
    hr = ID3D10Device1_CreateShaderResourceView1(device, (ID3D10Resource *)buffer, &srv_desc, &srview);
    ok(SUCCEEDED(hr), "Failed to create a shader resource view, hr %#x\n", hr);
    refcount = get_refcount((IUnknown *)device);
    ok(refcount >= expected_refcount, "Got unexpected refcount %u, expected >= %u.\n", refcount, expected_refcount);
    tmp_device = NULL;
    expected_refcount = refcount + 1;
    ID3D10ShaderResourceView1_GetDevice(srview, &tmp_device);
    ok(tmp_device == (ID3D10Device *)device, "Got unexpected device %p, expected %p.\n", tmp_device, device);
    refcount = get_refcount((IUnknown *)device);
    ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
    ID3D10Device_Release(tmp_device);

    hr = ID3D10ShaderResourceView1_QueryInterface(srview, &IID_ID3D10ShaderResourceView, (void **)&iface);
    ok(SUCCEEDED(hr), "Shader resource view should implement ID3D10ShaderResourceView.\n");
    IUnknown_Release(iface);
    hr = ID3D10ShaderResourceView1_QueryInterface(srview, &IID_ID3D11ShaderResourceView, (void **)&iface);
    ok(SUCCEEDED(hr) || broken(hr == E_NOINTERFACE) /* Not available on all Windows versions. */,
            "Shader resource view should implement ID3D11ShaderResourceView.\n");
    if (SUCCEEDED(hr)) IUnknown_Release(iface);

    ID3D10ShaderResourceView1_Release(srview);
    ID3D10Buffer_Release(buffer);

    texture_desc.Width = 512;
    texture_desc.Height = 512;
    texture_desc.MipLevels = 0;
    texture_desc.ArraySize = 1;
    texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    texture_desc.SampleDesc.Count = 1;
    texture_desc.SampleDesc.Quality = 0;
    texture_desc.Usage = D3D10_USAGE_DEFAULT;
    texture_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
    texture_desc.CPUAccessFlags = 0;
    texture_desc.MiscFlags = 0;

    hr = ID3D10Device1_CreateTexture2D(device, &texture_desc, NULL, &texture);
    ok(SUCCEEDED(hr), "Failed to create a 2d texture, hr %#x\n", hr);

    hr = ID3D10Device1_CreateShaderResourceView1(device, (ID3D10Resource *)texture, NULL, &srview);
    ok(SUCCEEDED(hr), "Failed to create a shader resource view, hr %#x\n", hr);

    ID3D10ShaderResourceView1_GetDesc1(srview, &srv_desc);
    ok(srv_desc.Format == texture_desc.Format, "Got unexpected format %#x.\n", srv_desc.Format);
    ok(srv_desc.ViewDimension == D3D10_1_SRV_DIMENSION_TEXTURE2D,
            "Got unexpected view dimension %#x.\n", srv_desc.ViewDimension);
    ok(U(srv_desc).Texture2D.MostDetailedMip == 0, "Got unexpected MostDetailedMip %u.\n",
            U(srv_desc).Texture2D.MostDetailedMip);
    ok(U(srv_desc).Texture2D.MipLevels == 10, "Got unexpected MipLevels %u.\n", U(srv_desc).Texture2D.MipLevels);

    hr = ID3D10ShaderResourceView1_QueryInterface(srview, &IID_ID3D10ShaderResourceView, (void **)&iface);
    ok(SUCCEEDED(hr), "Shader resource view should implement ID3D10ShaderResourceView.\n");
    IUnknown_Release(iface);
    hr = ID3D10ShaderResourceView1_QueryInterface(srview, &IID_ID3D11ShaderResourceView, (void **)&iface);
    ok(SUCCEEDED(hr) || broken(hr == E_NOINTERFACE) /* Not available on all Windows versions. */,
            "Shader resource view should implement ID3D11ShaderResourceView.\n");
    if (SUCCEEDED(hr)) IUnknown_Release(iface);

    ID3D10ShaderResourceView1_Release(srview);
    ID3D10Texture2D_Release(texture);

    refcount = ID3D10Device1_Release(device);
    ok(!refcount, "Device has %u references left.\n", refcount);
}
コード例 #21
0
ファイル: joystick.c プロジェクト: DeltaYang/wine
static BOOL CALLBACK EnumJoysticks(const DIDEVICEINSTANCEA *lpddi, void *pvRef)
{
    HRESULT hr;
    UserData * data = pvRef;
    IDirectInputDeviceA *pJoystick;
    DIDATAFORMAT format;
    DIDEVCAPS caps;
    DIJOYSTATE2 js;
    JoystickInfo info;
    int i, count;
    ULONG ref;
    DIDEVICEINSTANCEA inst;
    DIDEVICEINSTANCE_DX3A inst3;
    DIPROPDWORD dipw;
    DIPROPSTRING dps;
    DIPROPGUIDANDPATH dpg;
    WCHAR nameBuffer[MAX_PATH];
    HWND hWnd = get_hwnd();
    char oldstate[248], curstate[248];

    ok(data->version > 0x0300, "Joysticks not supported in version 0x%04x\n", data->version);
 
    hr = IDirectInput_CreateDevice(data->pDI, &lpddi->guidInstance, NULL, NULL);
    ok(hr==E_POINTER,"IDirectInput_CreateDevice() should have returned "
       "E_POINTER, returned: %08x\n", hr);

    hr = IDirectInput_CreateDevice(data->pDI, NULL, &pJoystick, NULL);
    ok(hr==E_POINTER,"IDirectInput_CreateDevice() should have returned "
       "E_POINTER, returned: %08x\n", hr);

    hr = IDirectInput_CreateDevice(data->pDI, NULL, NULL, NULL);
    ok(hr==E_POINTER,"IDirectInput_CreateDevice() should have returned "
       "E_POINTER, returned: %08x\n", hr);

    hr = IDirectInput_CreateDevice(data->pDI, &lpddi->guidInstance,
                                   &pJoystick, NULL);
    ok(hr==DI_OK,"IDirectInput_CreateDevice() failed: %08x\n", hr);
    if (hr!=DI_OK)
        goto DONE;

    trace("---- %s ----\n", lpddi->tszProductName);

    /* Test for joystick ID property */
    ZeroMemory(&dipw, sizeof(dipw));
    dipw.diph.dwSize = sizeof(DIPROPDWORD);
    dipw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    dipw.diph.dwObj = 0;
    dipw.diph.dwHow = DIPH_DEVICE;

    hr = IDirectInputDevice_GetProperty(pJoystick, DIPROP_JOYSTICKID, &dipw.diph);
    ok(SUCCEEDED(hr), "IDirectInputDevice_GetProperty() for DIPROP_JOYSTICKID failed\n");

    /* Test for INSTANCENAME property */
    memset(&dps, 0, sizeof(dps));
    dps.diph.dwSize = sizeof(DIPROPSTRING);
    dps.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    dps.diph.dwHow = DIPH_DEVICE;

    hr = IDirectInputDevice_GetProperty(pJoystick, DIPROP_INSTANCENAME, &dps.diph);
    ok(SUCCEEDED(hr), "IDirectInput_GetProperty() for DIPROP_INSTANCENAME failed: %08x\n", hr);

    /* Test if instance name is the same as present in DIDEVICEINSTANCE */
    MultiByteToWideChar(CP_ACP, 0, lpddi->tszInstanceName, -1, nameBuffer, MAX_PATH);
    ok(!lstrcmpW(nameBuffer, dps.wsz), "DIPROP_INSTANCENAME returned is wrong. Expected: %s Got: %s\n",
                 wine_dbgstr_w(nameBuffer), wine_dbgstr_w(dps.wsz));

    /* Test for GUIDPATH properties */
    memset(&dpg, 0, sizeof(dpg));
    dpg.diph.dwSize = sizeof(DIPROPGUIDANDPATH);
    dpg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    dpg.diph.dwHow = DIPH_DEVICE;

    hr = IDirectInputDevice_GetProperty(pJoystick, DIPROP_GUIDANDPATH, &dpg.diph);
    todo_wine ok(SUCCEEDED(hr), "IDirectInput_GetProperty() for DIPROP_GUIDANDPATH failed: %08x\n", hr);

    hr = IDirectInputDevice_SetDataFormat(pJoystick, NULL);
    ok(hr==E_POINTER,"IDirectInputDevice_SetDataFormat() should have returned "
       "E_POINTER, returned: %08x\n", hr);

    ZeroMemory(&format, sizeof(format));
    hr = IDirectInputDevice_SetDataFormat(pJoystick, &format);
    ok(hr==DIERR_INVALIDPARAM,"IDirectInputDevice_SetDataFormat() should have "
       "returned DIERR_INVALIDPARAM, returned: %08x\n", hr);

    /* try the default formats */
    hr = IDirectInputDevice_SetDataFormat(pJoystick, &c_dfDIJoystick);
    ok(hr==DI_OK,"IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);

    hr = IDirectInputDevice_SetDataFormat(pJoystick, &c_dfDIJoystick2);
    ok(hr==DI_OK,"IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);

    /* try an alternate format */
    hr = IDirectInputDevice_SetDataFormat(pJoystick, &c_dfDIJoystickTest);
    ok(hr==DI_OK,"IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);

    hr = IDirectInputDevice_SetDataFormat(pJoystick, &c_dfDIJoystick2);
    ok(hr==DI_OK,"IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);
    if (hr != DI_OK)
        goto RELEASE;

    for (i=0; i<16; i++)
    {
        hr = IDirectInputDevice_SetCooperativeLevel(pJoystick, NULL, i);
        ok(hr == SetCoop_null_window[i], "SetCooperativeLevel(NULL, %d): %08x\n", i, hr);
    }
    for (i=0; i<16; i++)
    {
        hr = IDirectInputDevice_SetCooperativeLevel(pJoystick, hWnd, i);
        ok(hr == SetCoop_real_window[i], "SetCooperativeLevel(hwnd, %d): %08x\n", i, hr);
    }

    hr = IDirectInputDevice_SetCooperativeLevel(pJoystick, hWnd,
                                                DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);
    ok(hr==DI_OK,"IDirectInputDevice_SetCooperativeLevel() failed: %08x\n", hr);

    /* get capabilities */
    hr = IDirectInputDevice_GetCapabilities(pJoystick, NULL);
    ok(hr==E_POINTER,"IDirectInputDevice_GetCapabilities() "
       "should have returned E_POINTER, returned: %08x\n", hr);

    ZeroMemory(&caps, sizeof(caps));
    hr = IDirectInputDevice_GetCapabilities(pJoystick, &caps);
    ok(hr==DIERR_INVALIDPARAM,"IDirectInputDevice_GetCapabilities() "
       "should have returned DIERR_INVALIDPARAM, returned: %08x\n", hr);

    caps.dwSize = sizeof(caps);
    hr = IDirectInputDevice_GetCapabilities(pJoystick, &caps);
    ok(hr==DI_OK,"IDirectInputDevice_GetCapabilities() failed: %08x\n", hr);

    ZeroMemory(&info, sizeof(info));
    info.pJoystick = pJoystick;

    /* default min/max limits */
    info.lMin = 0;
    info.lMax = 0xffff;
    /* enumerate objects */
    hr = IDirectInputDevice_EnumObjects(pJoystick, EnumAxes, &info, DIDFT_ALL);
    ok(hr==DI_OK,"IDirectInputDevice_EnumObjects() failed: %08x\n", hr);

    ok(caps.dwAxes == info.axis, "Number of enumerated axes (%d) doesn't match capabilities (%d)\n", info.axis, caps.dwAxes);
    ok(caps.dwButtons == info.button, "Number of enumerated buttons (%d) doesn't match capabilities (%d)\n", info.button, caps.dwButtons);
    ok(caps.dwPOVs == info.pov, "Number of enumerated POVs (%d) doesn't match capabilities (%d)\n", info.pov, caps.dwPOVs);

    /* Set format and check limits again */
    hr = IDirectInputDevice_SetDataFormat(pJoystick, &c_dfDIJoystick2);
    ok(hr==DI_OK,"IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);
    info.lMin = -2000;
    info.lMax = +2000;
    info.dZone= 123;
    hr = IDirectInputDevice_EnumObjects(pJoystick, EnumAxes, &info, DIDFT_ALL);
    ok(hr==DI_OK,"IDirectInputDevice_EnumObjects() failed: %08x\n", hr);

    hr = IDirectInputDevice_GetDeviceInfo(pJoystick, 0);
    ok(hr==E_POINTER, "IDirectInputDevice_GetDeviceInfo() "
       "should have returned E_POINTER, returned: %08x\n", hr);

    ZeroMemory(&inst, sizeof(inst));
    ZeroMemory(&inst3, sizeof(inst3));

    hr = IDirectInputDevice_GetDeviceInfo(pJoystick, &inst);
    ok(hr==DIERR_INVALIDPARAM, "IDirectInputDevice_GetDeviceInfo() "
       "should have returned DIERR_INVALIDPARAM, returned: %08x\n", hr);

    inst.dwSize = sizeof(inst);
    hr = IDirectInputDevice_GetDeviceInfo(pJoystick, &inst);
    ok(hr==DI_OK,"IDirectInputDevice_GetDeviceInfo() failed: %08x\n", hr);

    inst3.dwSize = sizeof(inst3);
    hr = IDirectInputDevice_GetDeviceInfo(pJoystick, (DIDEVICEINSTANCEA*)&inst3);
    ok(hr==DI_OK,"IDirectInputDevice_GetDeviceInfo() failed: %08x\n", hr);

    hr = IDirectInputDevice_Unacquire(pJoystick);
    ok(hr == S_FALSE, "IDirectInputDevice_Unacquire() should have returned S_FALSE, got: %08x\n", hr);

    hr = IDirectInputDevice_Acquire(pJoystick);
    ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
    if (hr != DI_OK)
        goto RELEASE;

    hr = IDirectInputDevice_Acquire(pJoystick);
    ok(hr == S_FALSE, "IDirectInputDevice_Acquire() should have returned S_FALSE, got: %08x\n", hr);

    if (info.pov < 4)
    {
        hr = IDirectInputDevice_GetDeviceState(pJoystick, sizeof(DIJOYSTATE2), &js);
        ok(hr == DI_OK, "IDirectInputDevice_GetDeviceState() failed: %08x\n", hr);
        ok(js.rgdwPOV[3] == -1, "Default for unassigned POV should be -1 not: %d\n", js.rgdwPOV[3]);
    }

    if (caps.dwFlags & DIDC_FORCEFEEDBACK)
    {
        DWORD axes[2] = {DIJOFS_X, DIJOFS_Y};
        LONG  direction[2] = {0, 0};
        DICONSTANTFORCE force = {0};
        DIEFFECT eff;
        LPDIRECTINPUTEFFECT effect = NULL;
        LONG cnt1, cnt2;
        HWND real_hWnd;
        HINSTANCE hInstance = GetModuleHandleW(NULL);
        DIPROPDWORD dip_gain_set, dip_gain_get;

        trace("Testing force-feedback\n");
        memset(&eff, 0, sizeof(eff));
        eff.dwSize                = sizeof(eff);
        eff.dwFlags               = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
        eff.dwDuration            = INFINITE;
        eff.dwGain                = DI_FFNOMINALMAX;
        eff.dwTriggerButton       = DIEB_NOTRIGGER;
        eff.cAxes                 = sizeof(axes) / sizeof(axes[0]);
        eff.rgdwAxes              = axes;
        eff.rglDirection          = direction;
        eff.cbTypeSpecificParams  = sizeof(force);
        eff.lpvTypeSpecificParams = &force;

        /* Sending effects to joystick requires
         * calling IDirectInputEffect_Initialize, which requires
         * having exclusive access to the device, which requires
         * - not having acquired the joystick when calling
         *   IDirectInputDevice_SetCooperativeLevel
         * - a visible window
         */
        real_hWnd = CreateWindowExA(0, "EDIT", "Test text", 0, 10, 10, 300, 300, NULL, NULL,
                                    hInstance, NULL);
        ok(real_hWnd!=0,"CreateWindowExA failed: %p\n", real_hWnd);
        ShowWindow(real_hWnd, SW_SHOW);
        hr = IDirectInputDevice_Unacquire(pJoystick);
        ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);
        hr = IDirectInputDevice_SetCooperativeLevel(pJoystick, real_hWnd,
                                                    DISCL_EXCLUSIVE | DISCL_FOREGROUND);
        ok(hr==DI_OK,"IDirectInputDevice_SetCooperativeLevel() failed: %08x\n", hr);
        hr = IDirectInputDevice_Acquire(pJoystick);
        ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);

        cnt1 = get_refcount((IUnknown*)pJoystick);

        hr = IDirectInputDevice2_CreateEffect((IDirectInputDevice2A*)pJoystick, &GUID_ConstantForce,
                                              &eff, &effect, NULL);
        ok(hr == DI_OK, "IDirectInputDevice_CreateEffect() failed: %08x\n", hr);
        cnt2 = get_refcount((IUnknown*)pJoystick);
        ok(cnt1 == cnt2, "Ref count is wrong %d != %d\n", cnt1, cnt2);

        if (effect)
        {
            DWORD effect_status;
            struct DIPROPDWORD diprop_word;
            GUID guid = {0};

            hr = IDirectInputEffect_Initialize(effect, hInstance, data->version,
                                               &GUID_ConstantForce);
            ok(hr==DI_OK,"IDirectInputEffect_Initialize failed: %08x\n", hr);
            hr = IDirectInputEffect_SetParameters(effect, &eff, DIEP_AXES | DIEP_DIRECTION |
                                                  DIEP_TYPESPECIFICPARAMS);
            ok(hr==DI_OK,"IDirectInputEffect_SetParameters failed: %08x\n", hr);
            if (hr==DI_OK) {
                /* Test that upload, unacquire, acquire still permits updating
                 * uploaded effect. */
                hr = IDirectInputDevice_Unacquire(pJoystick);
                ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);
                hr = IDirectInputDevice_Acquire(pJoystick);
                ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
                hr = IDirectInputEffect_SetParameters(effect, &eff, DIEP_GAIN);
                ok(hr==DI_OK,"IDirectInputEffect_SetParameters failed: %08x\n", hr);
            }

            /* Check effect status.
             * State: initially stopped
             * start
             * State: started
             * unacquire, acquire, download
             * State: stopped
             * start
             * State: started
             *
             * Shows that:
             * - effects are stopped after Unacquire + Acquire
             * - effects are preserved (Download + Start doesn't complain
             *   about incomplete effect)
             */
            hr = IDirectInputEffect_GetEffectStatus(effect, &effect_status);
            ok(hr==DI_OK,"IDirectInputEffect_GetEffectStatus() failed: %08x\n", hr);
            ok(effect_status==0,"IDirectInputEffect_GetEffectStatus() reported effect as started\n");
            hr = IDirectInputEffect_SetParameters(effect, &eff, DIEP_START);
            ok(hr==DI_OK,"IDirectInputEffect_SetParameters failed: %08x\n", hr);
            hr = IDirectInputEffect_GetEffectStatus(effect, &effect_status);
            ok(hr==DI_OK,"IDirectInputEffect_GetEffectStatus() failed: %08x\n", hr);
            todo_wine ok(effect_status!=0,"IDirectInputEffect_GetEffectStatus() reported effect as stopped\n");
            hr = IDirectInputDevice_Unacquire(pJoystick);
            ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);
            hr = IDirectInputDevice_Acquire(pJoystick);
            ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
            hr = IDirectInputEffect_Download(effect);
            ok(hr==DI_OK,"IDirectInputEffect_Download() failed: %08x\n", hr);
            hr = IDirectInputEffect_GetEffectStatus(effect, &effect_status);
            ok(hr==DI_OK,"IDirectInputEffect_GetEffectStatus() failed: %08x\n", hr);
            ok(effect_status==0,"IDirectInputEffect_GetEffectStatus() reported effect as started\n");
            hr = IDirectInputEffect_Start(effect, 1, 0);
            ok(hr==DI_OK,"IDirectInputEffect_Start() failed: %08x\n", hr);
            hr = IDirectInputEffect_GetEffectStatus(effect, &effect_status);
            ok(hr==DI_OK,"IDirectInputEffect_GetEffectStatus() failed: %08x\n", hr);
            todo_wine ok(effect_status!=0,"IDirectInputEffect_GetEffectStatus() reported effect as stopped\n");
            hr = IDirectInputEffect_GetEffectGuid(effect, &guid);
            ok(hr==DI_OK,"IDirectInputEffect_GetEffectGuid() failed: %08x\n", hr);
            ok(IsEqualGUID(&GUID_ConstantForce, &guid), "Wrong guid returned\n");

            /* Check autocenter status
             * State: initially stopped
             * enable
             * State: enabled
             * acquire
             * State: enabled
             * unacquire
             * State: enabled
             *
             * IDirectInputDevice2_SetProperty(DIPROP_AUTOCENTER) can only be
             * executed when the device is released.
             *
             * If Executed interactively, user can feel that autocenter is
             * only disabled when the joystick is acquired.
             */
            diprop_word.diph.dwSize = sizeof(diprop_word);
            diprop_word.diph.dwHeaderSize = sizeof(diprop_word.diph);
            diprop_word.diph.dwObj = 0;
            diprop_word.diph.dwHow = DIPH_DEVICE;
            hr = IDirectInputDevice_Unacquire(pJoystick);
            ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);
            hr = IDirectInputDevice2_GetProperty(pJoystick, DIPROP_AUTOCENTER, &diprop_word.diph);
            ok(hr==DI_OK,"IDirectInputDevice2_GetProperty() failed: %08x\n", hr);
            ok(diprop_word.dwData==DIPROPAUTOCENTER_ON,"IDirectInputDevice2_GetProperty() reported autocenter as disabled\n");
            diprop_word.dwData = DIPROPAUTOCENTER_OFF;
            hr = IDirectInputDevice2_SetProperty(pJoystick, DIPROP_AUTOCENTER, &diprop_word.diph);
            ok(hr==DI_OK,"IDirectInputDevice2_SetProperty() failed: %08x\n", hr);
            hr = IDirectInputDevice2_GetProperty(pJoystick, DIPROP_AUTOCENTER, &diprop_word.diph);
            ok(hr==DI_OK,"IDirectInputDevice2_GetProperty() failed: %08x\n", hr);
            ok(diprop_word.dwData==DIPROPAUTOCENTER_OFF,"IDirectInputDevice2_GetProperty() reported autocenter as enabled\n");
            if (winetest_interactive) {
                trace("Acquiring in 2s, autocenter will be disabled.\n");
                Sleep(2000);
            }
            hr = IDirectInputDevice_Acquire(pJoystick);
            ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
            if (winetest_interactive)
                trace("Acquired.\n");
            hr = IDirectInputDevice2_GetProperty(pJoystick, DIPROP_AUTOCENTER, &diprop_word.diph);
            ok(hr==DI_OK,"IDirectInputDevice2_GetProperty() failed: %08x\n", hr);
            ok(diprop_word.dwData==DIPROPAUTOCENTER_OFF,"IDirectInputDevice2_GetProperty() reported autocenter as enabled\n");
            if (winetest_interactive) {
                trace("Releasing in 2s, autocenter will be re-enabled.\n");
                Sleep(2000);
            }
            hr = IDirectInputDevice_Unacquire(pJoystick);
            ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);
            if (winetest_interactive)
                trace("Released\n");
            hr = IDirectInputDevice2_GetProperty(pJoystick, DIPROP_AUTOCENTER, &diprop_word.diph);
            ok(hr==DI_OK,"IDirectInputDevice2_GetProperty() failed: %08x\n", hr);
            ok(diprop_word.dwData==DIPROPAUTOCENTER_OFF,"IDirectInputDevice2_GetProperty() reported autocenter as enabled\n");
            hr = IDirectInputDevice_Acquire(pJoystick);
            ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
            hr = IDirectInputDevice2_GetProperty(pJoystick, DIPROP_AUTOCENTER, &diprop_word.diph);
            ok(hr==DI_OK,"IDirectInputDevice2_GetProperty() failed: %08x\n", hr);

            /* Device gain (DIPROP_FFGAIN).
             * From MSDN:
             *  0..10000 range, otherwise DIERR_INVALIDPARAM.
             *  Can be changed even if device is acquired.
             * Difference found by tests:
             *  <0 is refused, >10000 is accepted
             */
            dip_gain_set.diph.dwSize       = sizeof(DIPROPDWORD);
            dip_gain_set.diph.dwHeaderSize = sizeof(DIPROPHEADER);
            dip_gain_set.diph.dwObj        = 0;
            dip_gain_set.diph.dwHow        = DIPH_DEVICE;
            dip_gain_set.dwData            = 10000;
            dip_gain_get.diph.dwSize       = sizeof(DIPROPDWORD);
            dip_gain_get.diph.dwHeaderSize = sizeof(DIPROPHEADER);
            dip_gain_get.diph.dwObj        = 0;
            dip_gain_get.diph.dwHow        = DIPH_DEVICE;
            dip_gain_get.dwData            = 0;

            /* Test device is acquisition (non)impact. */
            hr = IDirectInputDevice_Unacquire(pJoystick);
            ok(hr == DI_OK, "IDirectInputDevice_Unacquire() should have returned S_FALSE, got: %08x\n", hr);
            dip_gain_set.dwData = 1;
            hr = IDirectInputDevice_SetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_set.diph);
            ok(hr==DI_OK, "IDirectInputDevice_SetProperty() failed: %08x\n", hr);
            hr = IDirectInputDevice_GetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_get.diph);
            ok(hr==DI_OK, "IDirectInputDevice_GetProperty() failed: %08x\n", hr);
            ok(dip_gain_get.dwData==dip_gain_set.dwData, "Gain not updated: %i\n", dip_gain_get.dwData);
            hr = IDirectInputDevice_Acquire(pJoystick);
            ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
            dip_gain_set.dwData = 2;
            hr = IDirectInputDevice_SetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_set.diph);
            ok(hr==DI_OK, "IDirectInputDevice_SetProperty() failed: %08x\n", hr);
            hr = IDirectInputDevice_GetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_get.diph);
            ok(hr==DI_OK, "IDirectInputDevice_GetProperty() failed: %08x\n", hr);
            ok(dip_gain_get.dwData==dip_gain_set.dwData, "Gain not updated: %i\n", dip_gain_get.dwData);
            /* Test range and internal clamping. */
            dip_gain_set.dwData = -1;
            hr = IDirectInputDevice_SetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_set.diph);
            todo_wine ok(hr==DIERR_INVALIDPARAM, "IDirectInputDevice_SetProperty() should have returned %08x: %08x\n", DIERR_INVALIDPARAM, hr);
            dip_gain_set.dwData = 0;
            hr = IDirectInputDevice_SetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_set.diph);
            ok(hr==DI_OK, "IDirectInputDevice_SetProperty() failed: %08x\n", hr);
            hr = IDirectInputDevice_GetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_get.diph);
            ok(hr==DI_OK, "IDirectInputDevice_GetProperty() failed: %08x\n", hr);
            ok(dip_gain_get.dwData==dip_gain_set.dwData, "Gain not updated: %i\n", dip_gain_get.dwData);
            dip_gain_set.dwData = 10000;
            hr = IDirectInputDevice_SetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_set.diph);
            ok(hr==DI_OK, "IDirectInputDevice_SetProperty() failed: %08x\n", hr);
            hr = IDirectInputDevice_GetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_get.diph);
            ok(hr==DI_OK, "IDirectInputDevice_GetProperty() failed: %08x\n", hr);
            ok(dip_gain_get.dwData==dip_gain_set.dwData, "Gain not updated: %i\n", dip_gain_get.dwData);
            /* WARNING: This call succeeds, on the contrary of what is stated on MSDN. */
            dip_gain_set.dwData = 10001;
            hr = IDirectInputDevice_SetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_set.diph);
            ok(hr==DI_OK, "IDirectInputDevice_SetProperty() failed: %08x\n", hr);
            hr = IDirectInputDevice_GetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_get.diph);
            ok(hr==DI_OK, "IDirectInputDevice_GetProperty() failed: %08x\n", hr);
            ok(dip_gain_get.dwData==dip_gain_set.dwData, "Gain not updated: %i\n", dip_gain_get.dwData);

            ref = IUnknown_Release(effect);
            ok(ref == 0, "IDirectInputDevice_Release() reference count = %d\n", ref);
        }
        cnt1 = get_refcount((IUnknown*)pJoystick);
        ok(cnt1 == cnt2, "Ref count is wrong %d != %d\n", cnt1, cnt2);

        /* Before destroying the window, release joystick to revert to
         * non-exclusive, background cooperative level. */
        hr = IDirectInputDevice_Unacquire(pJoystick);
        ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);
        hr = IDirectInputDevice_SetCooperativeLevel(pJoystick, hWnd,
                                                    DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);
        ok(hr==DI_OK,"IDirectInputDevice_SetCooperativeLevel() failed: %08x\n", hr);
        DestroyWindow (real_hWnd);
        hr = IDirectInputDevice_Acquire(pJoystick);
        ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
    }

    if (winetest_interactive) {
        trace("You have 30 seconds to test all axes, sliders, POVs and buttons\n");
        count = 300;
    } else
        count = 1;

    trace("\n");
    oldstate[0]='\0';
    for (i = 0; i < count; i++) {
        hr = IDirectInputDevice_GetDeviceState(pJoystick, sizeof(DIJOYSTATE2), &js);
        ok(hr==DI_OK,"IDirectInputDevice_GetDeviceState() failed: %08x\n", hr);
        if (hr != DI_OK)
            break;
        sprintf(curstate, "X%5d Y%5d Z%5d Rx%5d Ry%5d Rz%5d "
              "S0%5d S1%5d POV0%5d POV1%5d POV2%5d POV3%5d "
              "B %d %d %d %d %d %d %d %d %d %d %d %d\n",
              js.lX, js.lY, js.lZ, js.lRx, js.lRy, js.lRz,
              js.rglSlider[0], js.rglSlider[1],
              js.rgdwPOV[0], js.rgdwPOV[1], js.rgdwPOV[2], js.rgdwPOV[3],
              js.rgbButtons[0]>>7, js.rgbButtons[1]>>7, js.rgbButtons[2]>>7,
              js.rgbButtons[3]>>7, js.rgbButtons[4]>>7, js.rgbButtons[5]>>7,
              js.rgbButtons[6]>>7, js.rgbButtons[7]>>7, js.rgbButtons[8]>>7,
              js.rgbButtons[9]>>7, js.rgbButtons[10]>>7, js.rgbButtons[11]>>7);
        if (strcmp(oldstate, curstate) != 0)
        {
            trace("%s\n", curstate);
            strcpy(oldstate, curstate);
        }
        Sleep(100);
    }
    trace("\n");

    hr = IDirectInputDevice_Unacquire(pJoystick);
    ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);

RELEASE:
    ref = IDirectInputDevice_Release(pJoystick);
    ok(ref==0,"IDirectInputDevice_Release() reference count = %d\n", ref);

DONE:
    return DIENUM_CONTINUE;
}
コード例 #22
0
/*ARGSUSED*/
static void
instr_getargdesc(void *arg, dtrace_id_t id, void *parg, dtrace_argdesc_t *desc)
{
	instr_probe_t *fbt = parg;
	struct modctl *ctl = fbt->insp_ctl;
	struct module *mp = (struct module *) ctl;
	ctf_file_t *fp = NULL;
	ctf_funcinfo_t f;
//	int error;
	ctf_id_t argv[32], type;
	int argc = sizeof (argv) / sizeof (ctf_id_t);
//	const char *parent;

	if (mp->state != MODULE_STATE_LIVE ||
	    get_refcount(mp) != fbt->insp_loadcnt)
		return;

	if (fbt->insp_roffset != 0 && desc->dtargd_ndx == 0) {
		(void) strcpy(desc->dtargd_native, "int");
		return;
	}

# if 0
	if ((fp = ctf_modopen(mp, &error)) == NULL) {
		/*
		 * We have no CTF information for this module -- and therefore
		 * no args[] information.
		 */
		goto err;
	}
# endif

	//TODO();
	if (fp == NULL)
		goto err;
# if 0

	/*
	 * If we have a parent container, we must manually import it.
	 */
	if ((parent = ctf_parent_name(fp)) != NULL) {
		ctf_file_t *pfp;
		TODO();
		struct modctl *mod;

		/*
		 * We must iterate over all modules to find the module that
		 * is our parent.
		 */
		for (mod = &modules; mod != NULL; mod = mod->mod_next) {
			if (strcmp(mod->mod_filename, parent) == 0)
				break;
		}

		if (mod == NULL)
			goto err;

		if ((pfp = ctf_modopen(mod->mod_mp, &error)) == NULL)
			goto err;

		if (ctf_import(fp, pfp) != 0) {
			ctf_close(pfp);
			goto err;
		}

		ctf_close(pfp);
	}
# endif

	if (ctf_func_info(fp, fbt->insp_symndx, &f) == CTF_ERR)
		goto err;

	if (fbt->insp_roffset != 0) {
		if (desc->dtargd_ndx > 1)
			goto err;

		ASSERT(desc->dtargd_ndx == 1);
		type = f.ctc_return;
	} else {
		if (desc->dtargd_ndx + 1 > f.ctc_argc)
			goto err;

		if (ctf_func_args(fp, fbt->insp_symndx, argc, argv) == CTF_ERR)
			goto err;

		type = argv[desc->dtargd_ndx];
	}

	if (ctf_type_name(fp, type, desc->dtargd_native,
	    DTRACE_ARGTYPELEN) != NULL) {
		ctf_close(fp);
		return;
	}
err:
	if (fp != NULL)
		ctf_close(fp);

	desc->dtargd_ndx = DTRACE_ARGNONE;
}
コード例 #23
0
static void test_create_blend_state(void)
{
    static const D3D10_BLEND_DESC1 desc_conversion_tests[] =
    {
        {
            FALSE, FALSE,
            {
                {
                    FALSE, D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD,
                    D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD
                },
            },
        },
        {
            FALSE, TRUE,
            {
                {
                    TRUE, D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD,
                    D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD, D3D10_COLOR_WRITE_ENABLE_ALL
                },
                {
                    FALSE, D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD,
                    D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD, D3D10_COLOR_WRITE_ENABLE_RED
                },
                {
                    TRUE, D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD,
                    D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD, D3D10_COLOR_WRITE_ENABLE_ALL
                },
                {
                    FALSE, D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD,
                    D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD, D3D10_COLOR_WRITE_ENABLE_GREEN
                },
                {
                    TRUE, D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD,
                    D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD, D3D10_COLOR_WRITE_ENABLE_ALL
                },
                {
                    TRUE, D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD,
                    D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD, D3D10_COLOR_WRITE_ENABLE_ALL
                },
                {
                    TRUE, D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD,
                    D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD, D3D10_COLOR_WRITE_ENABLE_ALL
                },
                {
                    TRUE, D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD,
                    D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD, D3D10_COLOR_WRITE_ENABLE_ALL
                },
            },
        },
        {
            FALSE, TRUE,
            {
                {
                    TRUE, D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD,
                    D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD, D3D10_COLOR_WRITE_ENABLE_ALL
                },
                {
                    TRUE, D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_SUBTRACT,
                    D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD, D3D10_COLOR_WRITE_ENABLE_ALL
                },
                {
                    TRUE, D3D10_BLEND_ZERO, D3D10_BLEND_ONE, D3D10_BLEND_OP_ADD,
                    D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD, D3D10_COLOR_WRITE_ENABLE_ALL
                },
                {
                    TRUE, D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD,
                    D3D10_BLEND_ZERO, D3D10_BLEND_ONE, D3D10_BLEND_OP_ADD, D3D10_COLOR_WRITE_ENABLE_ALL
                },
                {
                    TRUE, D3D10_BLEND_ONE, D3D10_BLEND_ONE, D3D10_BLEND_OP_MAX,
                    D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD, D3D10_COLOR_WRITE_ENABLE_ALL
                },
                {
                    TRUE, D3D10_BLEND_ONE, D3D10_BLEND_ONE, D3D10_BLEND_OP_MIN,
                    D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD, D3D10_COLOR_WRITE_ENABLE_ALL
                },
                {
                    FALSE, D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD,
                    D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD, D3D10_COLOR_WRITE_ENABLE_ALL
                },
                {
                    FALSE, D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD,
                    D3D10_BLEND_ONE, D3D10_BLEND_ZERO, D3D10_BLEND_OP_ADD, D3D10_COLOR_WRITE_ENABLE_ALL
                },
            },
        },
    };

    ID3D10BlendState1 *blend_state1, *blend_state2;
    D3D10_BLEND_DESC1 desc, obtained_desc;
    ID3D10BlendState *d3d10_blend_state;
    D3D10_BLEND_DESC d3d10_blend_desc;
    ULONG refcount, expected_refcount;
    ID3D10Device1 *device;
    ID3D10Device *tmp;
    unsigned int i, j;
    IUnknown *iface;
    HRESULT hr;

    if (!(device = create_device(NULL)))
    {
        skip("Failed to create device.\n");
        return;
    }

    hr = ID3D10Device1_CreateBlendState1(device, NULL, &blend_state1);
    ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);

    memset(&desc, 0, sizeof(desc));
    desc.AlphaToCoverageEnable = FALSE;
    desc.IndependentBlendEnable = FALSE;
    desc.RenderTarget[0].BlendEnable = FALSE;
    desc.RenderTarget[0].SrcBlend = D3D10_BLEND_ONE;
    desc.RenderTarget[0].DestBlend = D3D10_BLEND_ZERO;
    desc.RenderTarget[0].BlendOp = D3D10_BLEND_OP_ADD;
    desc.RenderTarget[0].SrcBlendAlpha = D3D10_BLEND_ONE;
    desc.RenderTarget[0].DestBlendAlpha = D3D10_BLEND_ZERO;
    desc.RenderTarget[0].BlendOpAlpha = D3D10_BLEND_OP_ADD;
    desc.RenderTarget[0].RenderTargetWriteMask = D3D10_COLOR_WRITE_ENABLE_ALL;

    expected_refcount = get_refcount((IUnknown *)device) + 1;
    hr = ID3D10Device1_CreateBlendState1(device, &desc, &blend_state1);
    ok(SUCCEEDED(hr), "Failed to create blend state, hr %#x.\n", hr);
    hr = ID3D10Device1_CreateBlendState1(device, &desc, &blend_state2);
    ok(SUCCEEDED(hr), "Failed to create blend state, hr %#x.\n", hr);
    ok(blend_state1 == blend_state2, "Got different blend state objects.\n");
    refcount = get_refcount((IUnknown *)device);
    ok(refcount >= expected_refcount, "Got unexpected refcount %u, expected >= %u.\n", refcount, expected_refcount);
    tmp = NULL;
    expected_refcount = refcount + 1;
    ID3D10BlendState1_GetDevice(blend_state1, &tmp);
    ok(tmp == (ID3D10Device *)device, "Got unexpected device %p, expected %p.\n", tmp, device);
    refcount = get_refcount((IUnknown *)device);
    ok(refcount == expected_refcount, "Got unexpected refcount %u, expected %u.\n", refcount, expected_refcount);
    ID3D10Device_Release(tmp);

    ID3D10BlendState1_GetDesc1(blend_state1, &obtained_desc);
    ok(obtained_desc.AlphaToCoverageEnable == FALSE, "Got unexpected alpha to coverage enable %#x.\n",
            obtained_desc.AlphaToCoverageEnable);
    ok(obtained_desc.IndependentBlendEnable == FALSE, "Got unexpected independent blend enable %#x.\n",
            obtained_desc.IndependentBlendEnable);
    for (i = 0; i < D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i)
    {
        ok(obtained_desc.RenderTarget[i].BlendEnable == FALSE,
                "Got unexpected blend enable %#x for render target %u.\n",
                obtained_desc.RenderTarget[i].BlendEnable, i);
        ok(obtained_desc.RenderTarget[i].SrcBlend == D3D10_BLEND_ONE,
                "Got unexpected src blend %u for render target %u.\n",
                obtained_desc.RenderTarget[i].SrcBlend, i);
        ok(obtained_desc.RenderTarget[i].DestBlend == D3D10_BLEND_ZERO,
                "Got unexpected dest blend %u for render target %u.\n",
                obtained_desc.RenderTarget[i].DestBlend, i);
        ok(obtained_desc.RenderTarget[i].BlendOp == D3D10_BLEND_OP_ADD,
                "Got unexpected blend op %u for render target %u.\n",
                obtained_desc.RenderTarget[i].BlendOp, i);
        ok(obtained_desc.RenderTarget[i].SrcBlendAlpha == D3D10_BLEND_ONE,
                "Got unexpected src blend alpha %u for render target %u.\n",
                obtained_desc.RenderTarget[i].SrcBlendAlpha, i);
        ok(obtained_desc.RenderTarget[i].DestBlendAlpha == D3D10_BLEND_ZERO,
                "Got unexpected dest blend alpha %u for render target %u.\n",
                obtained_desc.RenderTarget[i].DestBlendAlpha, i);
        ok(obtained_desc.RenderTarget[i].BlendOpAlpha == D3D10_BLEND_OP_ADD,
                "Got unexpected blend op alpha %u for render target %u.\n",
                obtained_desc.RenderTarget[i].BlendOpAlpha, i);
        ok(obtained_desc.RenderTarget[i].RenderTargetWriteMask == D3D10_COLOR_WRITE_ENABLE_ALL,
                "Got unexpected render target write mask %#x for render target %u.\n",
                obtained_desc.RenderTarget[0].RenderTargetWriteMask, i);
    }

    hr = ID3D10BlendState1_QueryInterface(blend_state1, &IID_ID3D10BlendState, (void **)&iface);
    ok(SUCCEEDED(hr), "Blend state should implement ID3D10BlendState.\n");
    IUnknown_Release(iface);
    hr = ID3D10BlendState1_QueryInterface(blend_state1, &IID_ID3D11BlendState, (void **)&iface);
    ok(SUCCEEDED(hr) || broken(hr == E_NOINTERFACE) /* Not available on all Windows versions. */,
            "Blend state should implement ID3D11BlendState.\n");
    if (SUCCEEDED(hr)) IUnknown_Release(iface);

    refcount = ID3D10BlendState1_Release(blend_state1);
    ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
    refcount = ID3D10BlendState1_Release(blend_state2);
    ok(!refcount, "Blend state has %u references left.\n", refcount);

    for (i = 0; i < sizeof(desc_conversion_tests) / sizeof(*desc_conversion_tests); ++i)
    {
        const D3D10_BLEND_DESC1 *current_desc = &desc_conversion_tests[i];

        hr = ID3D10Device1_CreateBlendState1(device, current_desc, &blend_state1);
        ok(SUCCEEDED(hr), "Failed to create blend state, hr %#x.\n", hr);

        hr = ID3D10BlendState1_QueryInterface(blend_state1, &IID_ID3D10BlendState, (void **)&d3d10_blend_state);
        ok(SUCCEEDED(hr), "Blend state should implement ID3D10BlendState.\n");

        ID3D10BlendState_GetDesc(d3d10_blend_state, &d3d10_blend_desc);
        ok(d3d10_blend_desc.AlphaToCoverageEnable == current_desc->AlphaToCoverageEnable,
                "Got unexpected alpha to coverage enable %#x for test %u.\n",
                d3d10_blend_desc.AlphaToCoverageEnable, i);
        ok(d3d10_blend_desc.SrcBlend == current_desc->RenderTarget[0].SrcBlend,
                "Got unexpected src blend %u for test %u.\n", d3d10_blend_desc.SrcBlend, i);
        ok(d3d10_blend_desc.DestBlend == current_desc->RenderTarget[0].DestBlend,
                "Got unexpected dest blend %u for test %u.\n", d3d10_blend_desc.DestBlend, i);
        ok(d3d10_blend_desc.BlendOp == current_desc->RenderTarget[0].BlendOp,
                "Got unexpected blend op %u for test %u.\n", d3d10_blend_desc.BlendOp, i);
        ok(d3d10_blend_desc.SrcBlendAlpha == current_desc->RenderTarget[0].SrcBlendAlpha,
                "Got unexpected src blend alpha %u for test %u.\n", d3d10_blend_desc.SrcBlendAlpha, i);
        ok(d3d10_blend_desc.DestBlendAlpha == current_desc->RenderTarget[0].DestBlendAlpha,
                "Got unexpected dest blend alpha %u for test %u.\n", d3d10_blend_desc.DestBlendAlpha, i);
        ok(d3d10_blend_desc.BlendOpAlpha == current_desc->RenderTarget[0].BlendOpAlpha,
                "Got unexpected blend op alpha %u for test %u.\n", d3d10_blend_desc.BlendOpAlpha, i);
        for (j = 0; j < D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; j++)
        {
            unsigned int k = current_desc->IndependentBlendEnable ? j : 0;
            ok(d3d10_blend_desc.BlendEnable[j] == current_desc->RenderTarget[k].BlendEnable,
                    "Got unexpected blend enable %#x for test %u, render target %u.\n",
                    d3d10_blend_desc.BlendEnable[j], i, j);
            ok(d3d10_blend_desc.RenderTargetWriteMask[j] == current_desc->RenderTarget[k].RenderTargetWriteMask,
                    "Got unexpected render target write mask %#x for test %u, render target %u.\n",
                    d3d10_blend_desc.RenderTargetWriteMask[j], i, j);
        }

        ID3D10BlendState_Release(d3d10_blend_state);

        refcount = ID3D10BlendState1_Release(blend_state1);
        ok(!refcount, "Got unexpected refcount %u.\n", refcount);
    }

    refcount = ID3D10Device1_Release(device);
    ok(!refcount, "Device has %u references left.\n", refcount);
}
コード例 #24
0
static void
fbt_provide_function(struct modctl *mp, par_module_t *pmp,
	char *modname, char *name, uint8_t *st_value,
	uint8_t *instr, uint8_t *limit, int symndx)
{
	int	do_print = FALSE;
	int	invop = 0;
	fbt_probe_t *fbt, *retfbt;
	int	size;
	int	modrm;

	/***********************************************/
	/*   Dont  let  us  register  anything on the  */
	/*   notifier list(s) we are on, else we will  */
	/*   have recursion trouble.		       */
	/***********************************************/
	if (on_notifier_list(instr)) {
		printk("fbt_provide_function: Skip %s:%s - on notifier_chain\n",
			modname, name);
		return;
	}

# define UNHANDLED_FBT() if (do_print || dtrace_unhandled) { \
		printk("fbt:unhandled instr %s:%p %02x %02x %02x %02x\n", \
			name, instr, instr[0], instr[1], instr[2], instr[3]); \
			}

	/***********************************************/
	/*   Make sure we dont try and handle data or  */
	/*   bad instructions.			       */
	/***********************************************/
	if ((size = dtrace_instr_size_modrm(instr, &modrm)) <= 0)
		return;

	/***********************************************/
	/*   Allow  us  to  work on a single function  */
	/*   for  debugging/tracing  else we generate  */
	/*   too  much  printk() output and swamp the  */
	/*   log daemon.			       */
	/***********************************************/
//	do_print = strncmp(name, "update_process", 9) == NULL;

#ifdef __amd64
// am not happy with 0xe8 CALLR instructions, so disable them for now.
if (*instr == 0xe8) return;
	invop = DTRACE_INVOP_ANY;
	switch (instr[0] & 0xf0) {
	  case 0x00:
	  case 0x10:
	  case 0x20:
	  case 0x30:
	  	break;

	  case 0x40:
	  	if (instr[0] == 0x48 && instr[1] == 0xcf)
			return;
	  	break;

	  case 0x50:
	  case 0x60:
	  case 0x70:
	  case 0x80:
	  case 0x90:
	  case 0xa0:
	  case 0xb0:
		break;
	  case 0xc0:
	  	/***********************************************/
	  	/*   We  cannot  single step an IRET for now,  */
	  	/*   so just ditch them as potential probes.   */
	  	/***********************************************/
	  	if (instr[0] == 0xcf)
			return;
		break;
	  case 0xd0:
	  case 0xe0:
		break;
	  case 0xf0:
	  	/***********************************************/
	  	/*   This  doesnt  work - if we single step a  */
	  	/*   HLT, well, the kernel doesnt really like  */
	  	/*   it.				       */
	  	/***********************************************/
	  	if (instr[0] == 0xf4)
			return;

//		printk("fbt:F instr %s:%p size=%d %02x %02x %02x %02x %02x %02x\n", name, instr, size, instr[0], instr[1], instr[2], instr[3], instr[4], instr[5]);
		break;
	  }
#else
	/***********************************************/
	/*   GCC    generates   lots   of   different  */
	/*   assembler  functions plus we have inline  */
	/*   assembler  to  deal  with.  We break the  */
	/*   opcodes  down  into groups, which helped  */
	/*   during  debugging,  or  if  we  need  to  */
	/*   single  out  specific  opcodes,  but for  */
	/*   now,   we  can  pretty  much  allow  all  */
	/*   opcodes.  (Apart  from HLT - which I may  */
	/*   get around to fixing).		       */
	/***********************************************/
	invop = DTRACE_INVOP_ANY;
	switch (instr[0] & 0xf0) {
	  case 0x00:
	  case 0x10:
	  case 0x20:
	  case 0x30:
	  case 0x40:
	  case 0x50:
	  case 0x60:
	  case 0x70:
	  case 0x80:
	  case 0x90:
	  case 0xa0:
	  case 0xb0:
		break;
	  case 0xc0:
	  	/***********************************************/
	  	/*   We  cannot  single step an IRET for now,  */
	  	/*   so just ditch them as potential probes.   */
	  	/***********************************************/
	  	if (instr[0] == 0xcf)
			return;
		break;
	  case 0xd0:
	  case 0xe0:
		break;
	  case 0xf0:
	  	/***********************************************/
	  	/*   This  doesnt  work - if we single step a  */
	  	/*   HLT, well, the kernel doesnt really like  */
	  	/*   it.				       */
	  	/***********************************************/
	  	if (instr[0] == 0xf4)
			return;

//		printk("fbt:F instr %s:%p size=%d %02x %02x %02x %02x %02x %02x\n", name, instr, size, instr[0], instr[1], instr[2], instr[3], instr[4], instr[5]);
		break;
	  }
#endif
	/***********************************************/
	/*   Handle  fact we may not be ready to cope  */
	/*   with this instruction yet.		       */
	/***********************************************/
	if (invop == 0) {
		UNHANDLED_FBT();
		return;
	}

	/***********************************************/
	/*   Make  sure  this  doesnt overlap another  */
	/*   sym. We are in trouble when this happens  */
	/*   - eg we will mistaken what the emulation  */
	/*   is  for,  but  also,  it means something  */
	/*   strange  happens, like kernel is reusing  */
	/*   a  page  (eg  for init/exit section of a  */
	/*   module).				       */
	/***********************************************/
	if (fbt_is_patched(name, instr))
		return;
/*if (modrm >= 0 && (instr[modrm] & 0xc7) == 0x05) {
static char buf[128];
sprintf(buf, "MODRM_%s", name);
name = buf;
}
*/
	/***********************************************/
	/*   Special code here for debugging - we can  */
	/*   make  the  name of a probe a function of  */
	/*   the  instruction, so we can validate and  */
	/*   binary search to find faulty instruction  */
	/*   stepping code in cpu_x86.c		       */
	/***********************************************/
	if (fbt_name_opcodes) {
		static char buf[128];
		if (fbt_name_opcodes == 2)
			snprintf(buf, sizeof buf, "x%02x%02x_%s", *instr, instr[1], name);
		else
			snprintf(buf, sizeof buf, "x%02x_%s", *instr, name);
		name = buf;
	}

	fbt = kmem_zalloc(sizeof (fbt_probe_t), KM_SLEEP);
	fbt->fbtp_name = name;

	fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
	    name, FBT_ENTRY, 3, fbt);
	num_probes++;
	fbt->fbtp_patchpoint = instr;
	fbt->fbtp_ctl = mp; // ctl;
	fbt->fbtp_loadcnt = get_refcount(mp);
	fbt->fbtp_rval = invop;
	/***********************************************/
	/*   Save  potential overwrite of instruction  */
	/*   and  length,  because  we  will need the  */
	/*   entire  instruction  when we single step  */
	/*   over it.				       */
	/***********************************************/
	fbt->fbtp_savedval = *instr;
	fbt->fbtp_inslen = size;
//if (modrm >= 0 && (instr[modrm] & 0xc7) == 0x05) printk("modrm %s %p rm=%d\n", name, instr, modrm);
	fbt->fbtp_modrm = modrm;
	fbt->fbtp_patchval = FBT_PATCHVAL;

	fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
	fbt->fbtp_symndx = symndx;
	fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;

	if (do_print)
		printk("%d:alloc entry-patchpoint: %s %p invop=%x sz=%d %02x %02x %02x\n", 
			__LINE__, 
			name, 
			fbt->fbtp_patchpoint, 
			fbt->fbtp_rval, 
			fbt->fbtp_inslen,
			instr[0], instr[1], instr[2]);

	pmp->fbt_nentries++;

	retfbt = NULL;

	/***********************************************/
	/*   This   point   is   part   of   a   loop  */
	/*   (implemented  with goto) to find the end  */
	/*   part  of  a  function.  Original Solaris  */
	/*   code assumes a single exit, via RET, for  */
	/*   amd64,  but  is more accepting for i386.  */
	/*   However,  with  GCC  as a compiler a lot  */
	/*   more    things   can   happen   -   very  */
	/*   specifically,  we can have multiple exit  */
	/*   points in a function. So we need to find  */
	/*   each of those.			       */
	/***********************************************/
again:
	if (instr >= limit) {
		return;
	}

	/*
	 * If this disassembly fails, then we've likely walked off into
	 * a jump table or some other unsuitable area.  Bail out of the
	 * disassembly now.
	 */
	if ((size = dtrace_instr_size(instr)) <= 0)
		return;

//HERE();
#ifdef __amd64
	/*
	 * We only instrument "ret" on amd64 -- we don't yet instrument
	 * ret imm16, largely because the compiler doesn't seem to
	 * (yet) emit them in the kernel...
	 */
	switch (*instr) {
	  case FBT_RET:
		invop = DTRACE_INVOP_RET;
		break;
	  default:
		instr += size;
		goto again;
	  }
#else
	switch (*instr) {
/*		  case FBT_POPL_EBP:
		invop = DTRACE_INVOP_POPL_EBP;
		break;
	  case FBT_LEAVE:
		invop = DTRACE_INVOP_LEAVE;
		break;
*/
	  case FBT_RET:
		invop = DTRACE_INVOP_RET;
		break;
	  case FBT_RET_IMM16:
		invop = DTRACE_INVOP_RET_IMM16;
		break;
	  /***********************************************/
	  /*   Some  functions  can end in a jump, e.g.	 */
	  /*   security_file_permission has an indirect	 */
	  /*   jmp.  Dont  think we care too much about	 */
	  /*   this,  but  we  could  handle direct and	 */
	  /*   indirect jumps out of the function body.	 */
	  /***********************************************/
	  default:
		instr += size;
		goto again;
	  }
#endif

	/***********************************************/
	/*   Sanity check for bad things happening.    */
	/***********************************************/
	if (fbt_is_patched(name, instr)) {
		instr += size;
		goto again;
	}
	/*
	 * We have a winner!
	 */
	fbt = kmem_zalloc(sizeof (fbt_probe_t), KM_SLEEP);
	fbt->fbtp_name = name;

	if (retfbt == NULL) {
		fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
		    name, FBT_RETURN, 3, fbt);
		num_probes++;
	} else {
		retfbt->fbtp_next = fbt;
		fbt->fbtp_id = retfbt->fbtp_id;
	}
	retfbt = fbt;
	fbt->fbtp_patchpoint = instr;
	fbt->fbtp_ctl = mp; //ctl;
	fbt->fbtp_loadcnt = get_refcount(mp);

	/***********************************************/
	/*   Swapped  sense  of  the  following ifdef  */
	/*   around so we are consistent.	       */
	/***********************************************/
	fbt->fbtp_rval = invop;
#ifdef __amd64
	ASSERT(*instr == FBT_RET);
	fbt->fbtp_roffset =
	    (uintptr_t)(instr - (uint8_t *)st_value);
#else
	fbt->fbtp_roffset =
	    (uintptr_t)(instr - (uint8_t *)st_value) + 1;

#endif

	/***********************************************/
	/*   Save  potential overwrite of instruction  */
	/*   and  length,  because  we  will need the  */
	/*   entire  instruction  when we single step  */
	/*   over it.				       */
	/***********************************************/
	fbt->fbtp_savedval = *instr;
	fbt->fbtp_inslen = size;
	fbt->fbtp_modrm = -1;
	fbt->fbtp_patchval = FBT_PATCHVAL;
	fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
	fbt->fbtp_symndx = symndx;

	if (do_print) {
		printk("%d:alloc return-patchpoint: %s %p: %02x %02x invop=%d\n", __LINE__, name, instr, instr[0], instr[1], invop);
	}

	fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;

	pmp->fbt_nentries++;

	instr += size;
	goto again;
}