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