Re: [DynInst_API:] dyninst lock_tramp_guard


Date: Mon, 26 Mar 2018 18:12:26 +0000
From: Bill Williams <bill@xxxxxxxxxxx>
Subject: Re: [DynInst_API:] dyninst lock_tramp_guard
Taken from test1_24 in the testsuite (and yet another reminder that meaningful names in the test suite would help a lot of people):

	BPatch_variableExpr *lvar;
	BPatch_variableExpr *gvar[10];

	for (int i=1; i <= 9; i++) 
	{
		char name[80];

		sprintf(name, "test1_24_globalVariable%d", i);
		gvar[i] = appImage->findVariable(name);

		if (!gvar[i]) 
		{
			logerror("**Failed** test #24 (array variables)\n");
			logerror("  can't find variable %s\n", name);
			return FAILED;
		}
	}

	lvar = appImage->findVariable(*(*point24_1)[0], "localVariable24_1");

	//     globalVariable24_1[1] = 2400001
	BPatch_arithExpr assignment1(BPatch_assign,
			BPatch_arithExpr(BPatch_ref, *gvar[1], BPatch_constExpr(1)),
			BPatch_constExpr(2400001));
	if (!appAddrSpace->insertSnippet(assignment1, *point24_1))
		return FAILED;
	//     globalVariable24_1[globalVariable24_2] = 2400002
	BPatch_arithExpr assignment2(BPatch_assign,
			BPatch_arithExpr(BPatch_ref, *gvar[1], *gvar[2]),
			BPatch_constExpr(2400002));
	if (!appAddrSpace->insertSnippet(assignment2, *point24_1))
		return FAILED;

	//     globalVariable24_3 = globalVariable24_1[79]
	BPatch_arithExpr assignment3(BPatch_assign, *gvar[3],
			BPatch_arithExpr(BPatch_ref, *gvar[1], BPatch_constExpr(79)));
	if (!appAddrSpace->insertSnippet(assignment3, *point24_1))
		return FAILED;

	//     globalVariable24_5 = globalVariable24_1[globalVariable24_4]
	BPatch_arithExpr assignment4(BPatch_assign, *gvar[5],
			BPatch_arithExpr(BPatch_ref, *gvar[1], *gvar[4]));
	appAddrSpace->insertSnippet(assignment4, *point24_1);

The above of course assumes that globalVariable24_i are all of array type, but as long as they are, the arithmetic expressions and assignments do the right and natural thing.

--bw

________________________________________
From: Marc <marc@xxxxxxxxxxx>
Sent: Monday, March 26, 2018 12:12 PM
To: Bill Williams; dyninst-api@xxxxxxxxxxx
Subject: Re: [DynInst_API:] dyninst lock_tramp_guard

Hi Bill,

that could help - how would I use that? what are the necessary dyninst
functions for that?
lets say map is a variableExpr that is a pointer to the map, how do I
read a byte from there at a specific offset? Lets assume the offset is a
different variableExpr.

Regards,
Marc

On 26.03.2018 18:58, Bill Williams wrote:
> Marc--
>
> If you allocate map as a variableExpr of type unsigned char* (or whatever type is contained in the buffer) rather than unsigned long, and then perform the same magic so that it contains the base of the buffer, you should be able to use it as an array and/or perform pointer math without needing any gymnastics to dereference its contents. Does that help?
>
> --bw
> ________________________________________
> From: Marc <marc@xxxxxxxxxxx>
> Sent: Monday, March 26, 2018 11:40 AM
> To: Bill Williams; dyninst-api@xxxxxxxxxxx
> Subject: Re: [DynInst_API:] dyninst lock_tramp_guard
>
> Hi Bill,
>
> On 26.03.2018 17:58, Bill Williams wrote:
>> I think the right thing here is to back up several steps because you've de-variabled something prematurely, in all likelihood.
>>
>> If you're trying to access a field in a structure or an element of an array, there are BPatch_variable and BPatch_type methods that will help you out while ensuring that you're still dealing with a variable. As soon as you've turned it into an arithmetic expression, we assume it's just a number and our type system is hostile towards treating arbitrary numbers as pointers--for what I hope are obvious reasons.
>>
>> Am I understanding the shape of the problem correctly, and does the above help?
>
> the following description is not fully correct but a simplification.
>
> I am doing a openBinary() with writeFile().
>
> the program I am instrumenting has a 64kb buffer.
> with some magic I can get that buffer by:
>
> BPatch_variableExpr *map = appBin->malloc(*(appImage->findType("unsigned
> long")), "map");
> BPatch_constExpr map_ptr (map->getBaseAddr());
> instArgs.push_back(&map_ptr);
> BPatch_funcCallExpr instIncExpr(*instIncFunc, instArgs);
> etc.
>
> so that function I am inserting is doing the magic of finding that 64
> buffer and writing the starting location into the map variable.
>
> in the following part of the program I have to continiously read from
> that buffer.
> I did use a different BPatch_funcCallExpr for that, but the performance
> is bad, too bad to be usable.
>
> so thats why I am switching to arithExpr to makes things faster, and
> yes, it is way, way faster.
> with the current show stopper that I dont know how to read the specific
> byte in that 64kb buffer I am calculating every time.
>
> if there is no way to do that I have to go hardcore, write dummy
> snippets, write the file, and then open the file with a second program
> that just overwrites the dummy instructions with the necessary
> instructions I need.
> Which will then only work on x64 or until there is a change in dyninst
> which will change the generated instructions.
>
> that being said, it is an open source program which expands on an
> existing one that is widely used already, and the speed increase I
> expect from my effort will be around 30-50% - when its working.
>
> Thanks!
>
> Regards,
> Marc
>
>
>
>> ________________________________________
>> From: Marc <marc@xxxxxxxxxxx>
>> Sent: Friday, March 23, 2018 1:40 PM
>> To: Bill Williams; dyninst-api@xxxxxxxxxxx
>> Subject: Re: [DynInst_API:] dyninst lock_tramp_guard
>>
>> Hi Bill,
>>
>> thanks a lot, that was very helpful.
>> I am in the middle of doing that and I am now stuck at one thing:
>>
>> I have a BPatch_arithExpr() result that is a number and represents a
>> memory location in the instrumented program.
>> Now I want to read the byte at that address. How do I do that?
>>
>> Thanks!
>>
>> Regards,
>> Marc
>>
>> On 22.03.2018 17:31, Bill Williams wrote:
>>> Marc--
>>>
>>> The common idiom here is something like the following:
>>>
>>> BPatch_variable my_data = BPatch_malloc(my_inst_data_t);
>>> // initialize data
>>> for(p: points)
>>> {
>>>   // extractField left as an exercise for the implementer
>>>   BPatch_variableExpr data_for_point = extractField(my_data, p);
>>>   BPatch_assignExpr assignment(data_for_point, value_for_point);
>>>   insertSnippet(assignment, p);
>>> }
>>> BPatch_funcCallExpr print_summary(summary_func, BPatch_Vector<BPatch_snippet>{my_data});
>>> insertSnippet(print_summary, program_exit_point);
>>>
>>> where you build a data structure that can effectively be indexed by instpoint and record what you need, and then serialize your results at the end of execution. The simpler you can make the data structures and assignments, the faster the instrumented code will execute--but the more work you may need to do at summary time.
>>>
>>> --bw
>>> ________________________________________
>>> From: Dyninst-api <dyninst-api-bounces@xxxxxxxxxxx> on behalf of Marc <marc@xxxxxxxxxxx>
>>> Sent: Wednesday, March 21, 2018 9:14 PM
>>> To: dyninst-api@xxxxxxxxxxx
>>> Subject: Re: [DynInst_API:] dyninst lock_tramp_guard
>>>
>>> anwering myself:
>>>
>>> setTrampRecursive(true) and setSaveFPR(false) get the wished result :)
>>>
>>> In the documentation I find the note: "Write BPatch_snippet code that
>>> avoids making function calls."
>>>
>>> so far I have only used it with function calls, and all snippets
>>> elsewhere in code I saw - same same ... :)
>>>
>>> so, maybe anyone has a pointer on how to do that efficiently without
>>> calling a function?
>>>
>>> Regards,
>>> Marc
>>>
>>> On 22.03.2018 02:18, Marc wrote:
>>>> Hi,
>>>>
>>>> I am instrumenting a binary, inserting various calls into it and saving
>>>> it into a new file. (so, bpatch.openBinary(), walking through the basic
>>>> blocks, using insertSnippet() where I want things)
>>>>
>>>> When I look at the newly saved file I notice that every snippit is
>>>> preceded by DYNINST_lock_tramp_guard and followed by a
>>>> DYNINST_unlock_tramp_guard.
>>>>
>>>> I know this is generally speaking a very good thing.
>>>> But lets say that I know for 100% that in my target application that is
>>>> an unneeded measure and hurts performance actually a lot.
>>>> How can I disable it?
>>>> Basically I would like that only the call to the function is in the
>>>> location I want - plus pushing/poping the necessary registers.
>>>>
>>>> Thanks!
>>>>
>>>> Regards,
>>>> Marc
>>>> _______________________________________________
>>>> Dyninst-api mailing list
>>>> Dyninst-api@xxxxxxxxxxx
>>>> https://lists.cs.wisc.edu/mailman/listinfo/dyninst-api
>>>>
>>> _______________________________________________
>>> Dyninst-api mailing list
>>> Dyninst-api@xxxxxxxxxxx
>>> https://lists.cs.wisc.edu/mailman/listinfo/dyninst-api
>>>
>>
>

[← Prev in Thread] Current Thread [Next in Thread→]