-
Notifications
You must be signed in to change notification settings - Fork 5
/
labrea.cc
80 lines (65 loc) · 1.92 KB
/
labrea.cc
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
#include <iostream>
#include <queue>
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <sys/select.h>
#include "labrea.h"
START_DEFS
#include "definecalls.h"
END_DEFS
#include "buildfunctions.h"
namespace labrea {
void (*labreafree)(void*);
void* (*labrearealloc)(void*, size_t);
#define acceptable_arg_size(x) ( (x == 4) || (x == 8) )
static int computeOffset(struct ftype *fun) {
assert(fun);
int offset(0);
for (size_t b = 0; b < fun->num_args; ++b) {
assert(acceptable_arg_size(fun->arg_widths[b]));
offset = (offset << 1) | (fun->arg_widths[b] == 4 ? 0 : 1);
}
assert(acceptable_arg_size(fun->rv_size));
offset = (offset << 1) | (fun->rv_size == 4 ? 0 : 1);
return offset;
}
static class LabreaInit {
public:
LabreaInit() {
initPthreadKeys();
LuaInvocation invocation;
labreafree = function_cast<typeof(labreafree)>(dlsym(RTLD_NEXT, "free"));
labrearealloc = function_cast<typeof(labrearealloc)>(dlsym(RTLD_NEXT, "realloc"));
assert(labreafree);
assert(labrearealloc);
for (size_t n = 0; functions[n].name; ++n) {
functions[n].pos = static_cast<int>(n);
functions[n].offset = computeOffset(&functions[n]);
functions[n].orig = dlsym(RTLD_NEXT, functions[n].name);
assert(functions[n].orig);
}
initScriptingState();
}
~LabreaInit() {
LuaInvocation invocation;
destroyScriptingState();
}
} initializer;
struct ftype *findFunc(const char *name) {
struct ftype *rv(NULL);
for (size_t i = 0; rv == NULL && functions[i].name; ++i) {
if (strcmp(functions[i].name, name) == 0) {
rv = &functions[i];
}
}
if (rv == NULL) {
std::cerr << "Failed to find " << name << std::endl;
abort();
}
return rv;
}
}