Last active
March 8, 2016 04:58
-
-
Save gbluma/1158a1af7a70db3cfce7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include "libtcc.h" | |
#include "tcc.h" | |
void repl() | |
{ | |
char repl_input[1024]; | |
void (*func)(); | |
char repl_name[20]; | |
int index=0; | |
void *offset = TCC_RELOCATE_AUTO; | |
TCCState *s; | |
void *symbol_table[1024]; | |
while(1) | |
{ | |
/* create a new page of program definitions */ | |
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); | |
/* Add the symbols we want to expose to our REPL */ | |
/* 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, "printf", printf); | |
/* Add previous REPL symbols back in */ | |
for (int x=0; x<index; x++) { | |
char tmp_name[20]; | |
sprintf(tmp_name, "repl_%d", x); | |
printf("re-adding symbol %s to current context\n", tmp_name); | |
tcc_add_symbol(s, tmp_name, symbol_table[x]); | |
} | |
/* generate an index name for the code about to be read */ | |
sprintf(repl_name, "repl_%d", index++); | |
/* read a string */ | |
printf(">>> "); | |
fgets(repl_input, 1024, stdin); | |
/* wrap the input in a function */ | |
char tmp_code[1024]; | |
strcpy(tmp_code, repl_input); | |
sprintf(repl_input, "void %s(){ %s };", repl_name, tmp_code); | |
/* try to compile that code */ | |
if (tcc_compile_string(s, repl_input) == -1) { | |
printf("Error compiling string. Please try again\n"); | |
continue; | |
} | |
/* relocate the code and make it executable */ | |
if (tcc_relocate(s, TCC_RELOCATE_AUTO) < 0) { | |
printf("Error relocating JIT'ed code. Please try again\n"); | |
continue; | |
} | |
printf("Offset is: %lu\n", offset); | |
printf("Current symbol is: %s\n", repl_name); | |
// ------------------------ | |
// Experiment: list out all of the compiled symbols. | |
// Status: WIP | |
printf("number of sections: %d\n", s->nb_sections); | |
Sym *sym, *esym, *sym_end; | |
sym_end = (Sym *)(s->symtab->data + s->symtab->data_offset); | |
for(sym = (Sym *)s->symtab->data + 1; | |
sym < sym_end; | |
sym++) | |
{ | |
//printf(" name: %d\n", get_tok_str(sym->v, NULL)); | |
} | |
// ------------------------ | |
/* get entry symbol */ | |
func = tcc_get_symbol(s, repl_name); | |
printf("Func addr: %lu\n", (unsigned long)func); | |
if (!func) { | |
printf("Error retrieving symbol %s. Please try again\n", repl_name); | |
continue; | |
} | |
/* track new function for use in later loops */ | |
symbol_table[index-1] = func; | |
/* TODO: loop over all symbols in the repl micro-session and add them to | |
the aggregate symbol table. This way we can track everything | |
from the input instead of wrapping in an ugly function. */ | |
/* run the code */ | |
func(); | |
/* delete the state */ | |
//tcc_delete(s); // TODO: defer to end of program | |
/* Note: I'm skipping this for now so the later loop iterations | |
can still access code from the earlier loop. */ | |
} | |
} | |
int main(int argc, char **argv) | |
{ | |
/* disable output buffering so we can see the */ | |
setbuf(stdout, NULL); | |
/* if tcclib.h and libtcc1.a are not installed, where can we find them | |
if (argc == 2 && !memcmp(argv[1], "lib_path=",9)) | |
tcc_set_lib_path(s, argv[1]+9); | |
*/ | |
// enter read-eval-print loop | |
repl(); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ tcc -L ./libtcc -llibtcc -I ../tcc-source/tcc-0.9.26/ -run examples/libtcc_test2.c | |
>>> printf("A\n"); | |
Offset is: 1 | |
Current symbol is: repl_0 | |
number of sections: 10 | |
Func addr: 8722432 | |
A | |
re-adding symbol repl_0 to current context | |
>>> printf("B\n"); | |
Offset is: 1 | |
Current symbol is: repl_1 | |
number of sections: 10 | |
Func addr: 8781488 | |
B | |
re-adding symbol repl_0 to current context | |
re-adding symbol repl_1 to current context | |
>>> repl_1(); | |
Offset is: 1 | |
Current symbol is: repl_2 | |
number of sections: 10 | |
Func addr: 9273312 | |
B | |
re-adding symbol repl_0 to current context | |
re-adding symbol repl_1 to current context | |
re-adding symbol repl_2 to current context | |
>>> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment