1 #include <stddef.h>
2 #include <stdio.h>
3 #include <string.h>
4 
5 void *func[8], **pfunc;
6 
7 typedef struct xxx xxx_t;
8 struct xxx {
9 	int dummy;
10 	void **pfunc;
11 } q;
12 
13 #define XF_strcpy 3
14 #define XF_printf 4
15 
16 #define LABEL(x)					\
17 asm volatile (						\
18 
19 #if defined(__i386__)
20 #define EXPORT_FUNC(x)					\
21 asm volatile (						\
22 "	.globl mon_" #x "\n"				\
23 "mon_" #x ":\n"						\
24 "	movl	%0, %%eax\n"				\
25 "	movl	pfunc, %%ecx\n"				\
26 "	jmp	*(%%ecx,%%eax)\n"			\
27 	: : "i"(XF_ ## x * sizeof(void *)) : "eax", "ecx");
28 #elif defined(__powerpc__)
29 #define EXPORT_FUNC(x)					\
30 asm volatile (						\
31 "	.globl mon_" #x "\n"				\
32 "mon_" #x ":\n"						\
33 "	lwz	%%r11, %0(%%r2)\n"			\
34 "	lwz	%%r11, %1(%%r11)\n"			\
35 "	mtctr	%%r11\n"				\
36 "	bctr\n"					\
37 	: : "i"(offsetof(xxx_t, pfunc)), "i"(XF_ ## x * sizeof(void *)) : "r11", "r2");
38 #elif defined(__arm__)
39 #define EXPORT_FUNC(x)					\
40 asm volatile (						\
41 "	.globl mon_" #x "\n"				\
42 "mon_" #x ":\n"						\
43 "	ldr	ip, [r8, %0]\n"				\
44 "	ldr	pc, [ip, %1]\n"				\
45 	: : "i"(offsetof(xxx_t, pfunc)), "i"(XF_ ## x * sizeof(void *)) : "ip");
46 #elif defined(__mips__)
47 #define EXPORT_FUNC(x)					\
48 asm volatile (						\
49 "	.globl mon_" #x "\n"				\
50 "mon_" #x ":\n"						\
51 "	lw	$25, %0($26)\n"				\
52 "	lw	$25, %1($25)\n"				\
53 "	jr	$25\n"					\
54 	: : "i"(offsetof(xxx_t, pfunc)), "i"(XF_ ## x * sizeof(void *)) : "t9");
55 #else
56 #error [No stub code for this arch]
57 #endif
58 
dummy(void)59 void dummy(void)
60 {
61 EXPORT_FUNC(printf)
62 EXPORT_FUNC(strcpy)
63 }
64 
main(void)65 int main(void)
66 {
67 #if defined(__i386__)
68 	xxx_t *pq;
69 #elif defined(__powerpc__)
70 	register volatile xxx_t *pq asm("r2");
71 #elif defined(__arm__)
72 	register volatile xxx_t *pq asm("r8");
73 #elif defined(__mips__)
74 	register volatile xxx_t *pq asm("k0");
75 #endif
76 	char buf[32];
77 
78 	func[XF_strcpy] = strcpy;
79 	func[XF_printf] = printf;
80 	pq = &q;
81 	pq->pfunc = pfunc = func;
82 
83 	mon_strcpy(buf, "test");
84 	mon_printf("hi %s %d z\n", buf, 444);
85 
86 	return 0;
87 }
88