On May 28, 2013, at 20:38 , Marvin Humphrey <[email protected]> wrote:
> Last, find a way to persuade the dynamic loader to resolve all method
> invocation functions at a given offset to a single compiled thunk,
> **regardless of the method signature**.
Here's an interesting blog post discussing this topic:
http://blog.omega-prime.co.uk/?p=121
The program below works for me on OS X when compiled with
cc -O2 -Wl,-alias,_thunk1,_Obj_Add,-alias,_thunk2,_Obj_Sub alias.c -o alias
But the thunks should actually be written in assembler, so we don't have to
rely on compiler optimizations.
A single thunk per offset might be bad for branch prediction. But this could be
worked around by providing separate thunks for each method.
Nick
#include <stdio.h>
#include <stdlib.h>
typedef struct VTable VTable;
typedef struct Obj {
VTable *vtable;
int value;
} Obj;
typedef void
(*method_t)(Obj* self);
struct VTable {
method_t method1;
method_t method2;
};
void
thunk1(Obj *self) {
self->vtable->method1(self);
}
void
thunk2(Obj *self) {
self->vtable->method2(self);
}
Obj_add(Obj *self, int value) {
self->value += value;
}
void
Obj_sub(Obj *self, int value) {
self->value -= value;
}
VTable vtable = {
(method_t)Obj_add,
(method_t)Obj_sub
};
Obj*
Obj_new(int value) {
Obj *self = (Obj*)malloc(sizeof(Obj));
self->vtable = &vtable;
self->value = value;
return self;
}
int
Obj_Add(Obj *self, int value);
int
Obj_Sub(Obj *self, int value);
int
main() {
Obj *obj = Obj_new(42);
Obj_Add(obj, 10);
Obj_Sub(obj, 5);
printf("%d\n", obj->value);
return 0;
}