diff --git a/Makefile b/Makefile index 47494f0c..1267e26e 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,7 @@ # Tiny C Compiler Makefile # prefix=/usr/local +manpath=$(prefix)/man CFLAGS=-O2 -g -Wall LIBS=-ldl @@ -117,7 +118,7 @@ bcheck.o: bcheck.c install: tcc libtcc1.o bcheck.o $(INSTALL) -m755 tcc $(prefix)/bin - $(INSTALL) tcc.1 $(prefix)/man/man1 + $(INSTALL) tcc.1 $(manpath)/man1 mkdir -p $(prefix)/lib/tcc mkdir -p $(prefix)/lib/tcc/include $(INSTALL) -m644 libtcc1.o bcheck.o $(prefix)/lib/tcc diff --git a/libtcc.h b/libtcc.h index df066bd2..6f49baa4 100644 --- a/libtcc.h +++ b/libtcc.h @@ -63,10 +63,16 @@ int tcc_add_library(TCCState *s, const char *libraryname); /* add a symbol to the compiled program */ int tcc_add_symbol(TCCState *s, const char *name, unsigned long val); -/* output an executable file */ +/* output an executable, library or object file */ int tcc_output_file(TCCState *s, const char *filename); /* link and run main() function and return its value */ int tcc_run(TCCState *s, int argc, char **argv); +/* do all relocations (needed before using tcc_get_symbol()) */ +void tcc_relocate(TCCState *s); + +/* return symbol value or error */ +void *tcc_get_symbol(TCCState *s, const char *name); + #endif diff --git a/libtcc_test.c b/libtcc_test.c index a9c379e5..9861ec02 100644 --- a/libtcc_test.c +++ b/libtcc_test.c @@ -23,10 +23,8 @@ char my_program[] = " return fib(n-1) + fib(n-2);\n" "}\n" "\n" -"int main(int argc, char **argv)\n" +"int foo(int n)\n" "{\n" -" int n;\n" -" n = atoi(argv[1]);\n" " printf(\"Hello World!\\n\");\n" " printf(\"fib(%d) = %d\\n\", n, fib(n));\n" " printf(\"add(%d, %d) = %d\\n\", n, 2 * n, add(n, 2 * n));\n" @@ -36,7 +34,7 @@ char my_program[] = int main(int argc, char **argv) { TCCState *s; - char *args[3]; + int (*func)(int); s = tcc_new(); if (!s) { @@ -54,11 +52,11 @@ int main(int argc, char **argv) with tcc_add_dll(() and using its symbols directly. */ tcc_add_symbol(s, "add", (unsigned long)&add); - args[0] = ""; - args[1] = "32"; - args[2] = NULL; + tcc_relocate(s); - tcc_run(s, 2, args); + func = tcc_get_symbol(s, "foo"); + + func(32); tcc_delete(s); return 0; diff --git a/tcc.c b/tcc.c index 750cb391..22874f91 100644 --- a/tcc.c +++ b/tcc.c @@ -7070,11 +7070,10 @@ static void sig_error(int signum, siginfo_t *siginf, void *puc) } #endif -/* launch the compiled program with the given arguments */ -int tcc_run(TCCState *s1, int argc, char **argv) +/* do all relocations (needed before using tcc_get_symbol()) */ +void tcc_relocate(TCCState *s1) { Section *s; - int (*prog_main)(int, char **); int i; tcc_add_runtime(s1); @@ -7104,8 +7103,16 @@ int tcc_run(TCCState *s1, int argc, char **argv) if (s->reloc) relocate_section(s1, s); } +} - prog_main = (void *)get_elf_sym_val("main"); +/* launch the compiled program with the given arguments */ +int tcc_run(TCCState *s1, int argc, char **argv) +{ + int (*prog_main)(int, char **); + + tcc_relocate(s1); + + prog_main = tcc_get_symbol(s1, "main"); if (do_debug) { #ifdef WIN32 @@ -7131,11 +7138,11 @@ int tcc_run(TCCState *s1, int argc, char **argv) void **bound_error_func; /* set error function */ - bound_error_func = (void **)get_elf_sym_val("__bound_error_func"); + bound_error_func = (void **)tcc_get_symbol(s1, "__bound_error_func"); *bound_error_func = rt_error; /* XXX: use .init section so that it also work in binary ? */ - bound_init = (void *)get_elf_sym_val("__bound_init"); + bound_init = (void *)tcc_get_symbol(s1, "__bound_init"); bound_init(); } #endif diff --git a/tccelf.c b/tccelf.c index 0704ab0d..05a9c307 100644 --- a/tccelf.c +++ b/tccelf.c @@ -154,7 +154,7 @@ static int find_elf_sym(Section *s, const char *name) } /* return elf symbol value or error */ -static unsigned long get_elf_sym_val(const char *name) +void *tcc_get_symbol(TCCState *s, const char *name) { int sym_index; Elf32_Sym *sym; @@ -163,7 +163,7 @@ static unsigned long get_elf_sym_val(const char *name) if (!sym_index) error("%s not defined", name); sym = &((Elf32_Sym *)symtab_section->data)[sym_index]; - return sym->st_value; + return (void *)sym->st_value; } /* add an elf symbol : check if it is already defined and patch @@ -1294,7 +1294,7 @@ int tcc_output_file(TCCState *s1, const char *filename) /* get entry point address */ if (file_type == TCC_OUTPUT_EXE) - ehdr.e_entry = get_elf_sym_val("_start"); + ehdr.e_entry = (unsigned long)tcc_get_symbol(s1, "_start"); else ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */ }