Re: [patch 0/2] Immediate Values - jump patching update

!MAILaRCHIVE_VOTE_RePLACE
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: H. Peter Anvin <hpa@...>
Cc: Ingo Molnar <mingo@...>, <akpm@...>, <linux-kernel@...>, Frank Ch. Eigler <fche@...>
Date: Monday, April 28, 2008 - 9:46 pm

* H. Peter Anvin (hpa@zytor.com) wrote:

Peter, do you have something like the following code in mind ?

I think the main differences between the code snippet down here and the
markers is that markers rely on the compiler to generate the stack
setup, and have this code a little bit closer to the function than what
I propose here, where I put the stack setup code in a "farfaraway"
section.  Moreover, markers are much simpler than what I show here.
And actually, markers can be deployed portably, with
architecture-specific optimizations refined later. This has to be
implemented all up front for any traced architecture. In addition,
dealing with weird types like unsigned long long can become a pain.
Also, due to fact that we are asking the compiler to put keep some
variables live in registers, I would be tempted to embed this in a block
controlled by an if() statement (conditional branch, like I use for the
markers) so we don't have to pay the penality of populating the
registers when not required if there are not live at the marker site.

Here is the toy program :

#include <stdio.h>

#define SAVE_REGS   \
	"pushl %%eax\n\t" \
	"pushl %%ebp\n\t" \
	"pushl %%edi\n\t" \
	"pushl %%esi\n\t" \
	"pushl %%edx\n\t" \
	"pushl %%ecx\n\t" \
	"pushl %%ebx\n\t"

#define RESTORE_REGS \
	"popl %%ebx\n\t"	\
	"popl %%ecx\n\t"	\
	"popl %%edx\n\t"	\
	"popl %%esi\n\t"	\
	"popl %%edi\n\t"	\
	"popl %%ebp\n\t"	\
	"popl %%eax\n\t"

#define asmlinkage __attribute__((regparm(0)))
#define _ASM_PTR ".long "

struct marker_info {
	const char *name;
	const char *fields;
	unsigned char nr_args;
	unsigned char type_sizes[];
};

#define trace_mark3(name, fields, arg1, arg2, arg3)			\
	do {								\
		static struct marker_info info = {			\
			#name,						\
			fields,						\
			3, { sizeof(arg1), sizeof(arg2), sizeof(arg3) } }; \
		asm (".section __marker_info, \"a\",@progbits\n\t"	\
			_ASM_PTR "%c0, 1f, 2f\n\t"			\
			".previous\n\t"					\
			".section __farfarawaycode,\"ax\",@progbits\n\t"\
			"1:\n\t"					\
			SAVE_REGS	/* Save caller-saved registers */\
			"pushl %3\n\t"					\
			"pushl %2\n\t"					\
			"pushl %1\n\t"					\
			"pushl %0\n\t"					\
			"call do_kernel_trace\n\t"			\
			"addl $(4*(1+3)), %%esp\n\t"			\
			RESTORE_REGS					\
			"ret\n\t"					\
			".previous\n\t"					\
			"2:\n\t"					\
			"call 1b\n\t"	/* TEST */			\
			".byte 0xe9\n\t"/* jmp near 0x0 (5-bytes 1 insn nop) */\
			".int 0x0\n\t"	/* patched to "call ...\n\t" */	\
			: : "i" (&info),				\
			"g" (arg1), "g" (arg2), "g" (arg3));		\
	} while (0)

/*
 * Patching address "2f" with a call 1f. All the information required is in 
 * the __marker_info section/table.
 */

asmlinkage void do_kernel_trace(const struct marker_info *info,
	 unsigned long arg1, unsigned long arg2, unsigned long arg3)
{
	unsigned long *args = &arg1;
	int i;
	printf("%s \n", info->name);
	for (i = 0; i < info->nr_args; i++) {
		switch (info->type_sizes[i]) {
		case 1:
			printf("%hu ", (unsigned char)args[i]);
			break;
		case 2:
			printf("%hu ", (unsigned short)args[i]);
			break;
		case 4:
			printf("%u ", (unsigned int)args[i]);
			break;
		case 8:
			printf("%llu ", (unsigned long long)args[i]);
			break;
		}
	}
	printf("\n");
}

unsigned long long gg = -1ULL;  /* this guy does not work. No warning
                                   generated. */

void f(void)
{
	char y = 4;
	trace_mark3(test_event, "name1 name2 name3", y, gg, 6);
}

void main()
{
	f();
}


-- 
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68
--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[patch 0/2] Immediate Values - jump patching update, Mathieu Desnoyers, (Sun Apr 27, 11:34 pm)
Re: [patch 0/2] Immediate Values - jump patching update, H. Peter Anvin, (Mon Apr 28, 1:21 pm)
Re: [patch 0/2] Immediate Values - jump patching update, H. Peter Anvin, (Mon Apr 28, 5:03 pm)
Re: [patch 0/2] Immediate Values - jump patching update, H. Peter Anvin, (Mon Apr 28, 6:25 pm)
Re: [patch 0/2] Immediate Values - jump patching update, H. Peter Anvin, (Mon Apr 28, 7:06 pm)
Re: [patch 0/2] Immediate Values - jump patching update, Mathieu Desnoyers, (Mon Apr 28, 9:46 pm)
Re: [patch 0/2] Immediate Values - jump patching update, H. Peter Anvin, (Mon Apr 28, 10:07 pm)
Re: [patch 0/2] Immediate Values - jump patching update, Mathieu Desnoyers, (Tue Apr 29, 8:18 am)
Re: [patch 0/2] Immediate Values - jump patching update, H. Peter Anvin, (Tue Apr 29, 11:35 am)
Re: [patch 0/2] Immediate Values - jump patching update, Mathieu Desnoyers, (Sun May 4, 10:54 am)
Re: [patch 0/2] Immediate Values - jump patching update, H. Peter Anvin, (Sun May 4, 5:05 pm)
Re: [patch 0/2] Immediate Values - jump patching update, Frank Ch. Eigler, (Mon Apr 28, 8:47 pm)
Re: [patch 0/2] Immediate Values - jump patching update, H. Peter Anvin, (Mon Apr 28, 9:08 pm)
Re: [patch 0/2] Immediate Values - jump patching update, Pavel Machek, (Wed May 14, 10:53 am)
Re: [patch 0/2] Immediate Values - jump patching update, Mathieu Desnoyers, (Mon Apr 28, 10:35 am)