Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stdio.h>
- #include <assert.h>
- #include <libtcc.h>
- FILE *log_func_call;
- /* The code dynamically generated can't get access to variable, must provide a
- * function. */
- FILE *get_log_func_call() {
- return log_func_call;
- }
- typedef int (*func_t)(int arg);
- int foo(int a) {
- return a + 1;
- }
- char wrap[] =
- "int wrapped(int arg) {"
- " int val = origin(arg);"
- " printf(\"Inside wrapped function\n\");"
- " fprintf(get_log_func_call(), \"arg: %d ret: %d\n\", arg, val);"
- " return val;"
- "}";
- func_t create_wrap_function(func_t origin) {
- TCCState *s;
- func_t func = func;
- void *mem;
- int size;
- s = tcc_new();
- if (!s) {
- fprintf(stderr, "Could not create tcc state\n");
- exit(1);
- }
- /* MUST BE CALLED before any compilation */
- tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
- if (tcc_compile_string(s, wrap) == -1)
- exit(1);
- /* as a test, we add a symbol that the compiled program can use.
- You may also open a dll with tcc_add_dll() and use symbols from that */
- tcc_add_symbol(s, "get_log_func_call", get_log_func_call);
- tcc_add_symbol(s, "origin", origin);
- /* get needed size of the code */
- size = tcc_relocate(s, NULL);
- if (size == -1)
- exit(1);
- /* allocate memory and copy the code into it */
- mem = malloc(size);
- tcc_relocate(s, mem);
- /* get entry symbol */
- func = tcc_get_symbol(s, "wrapped");
- if (!func) {
- fprintf(stderr, "can't get function entry\n");
- exit(1);
- }
- /* delete the state */
- tcc_delete(s);
- return func;
- }
- int main(int argc, char* argv[]) {
- assert(log_func_call = fopen("log_func_call", "w"));
- func_t bar = create_wrap_function(foo);
- printf("%d\n", bar(2));
- return 0;
- }
Add Comment
Please, Sign In to add comment