@@ -20,10 +20,19 @@ */ #include #include #include "tcc.h" +#ifdef HAVE_DLFCN_H +#include +#endif +#ifdef HAVE_PSAPI_H +# ifdef HAVE_WINDOWS_H +# include +# endif +# include +#endif struct TclTCCState { TCCState *s; int relocated; }; @@ -57,17 +66,21 @@ TCCState *s; Tcl_Obj *sym_addr; static CONST char *options[] = { "add_include_path", "add_file", "add_library", "add_library_path", "add_symbol", "command", "compile", - "define", "get_symbol", "output_file", "undefine", (char *) NULL + "define", "get_symbol", "output_file", "undefine", + "add_runtime_sym", + (char *) NULL }; enum options { - TCLTCC_ADD_INCLUDE, TCLTCC_ADD_FILE, TCLTCC_ADD_LIBRARY, - TCLTCC_ADD_LIBRARY_PATH, TCLTCC_ADD_SYMBOL, TCLTCC_COMMAND, TCLTCC_COMPILE, - TCLTCC_DEFINE, TCLTCC_GET_SYMBOL, TCLTCC_OUTPUT_FILE, TCLTCC_UNDEFINE + TCC4TCL_ADD_INCLUDE, TCC4TCL_ADD_FILE, TCC4TCL_ADD_LIBRARY, + TCC4TCL_ADD_LIBRARY_PATH, TCC4TCL_ADD_SYMBOL, TCC4TCL_COMMAND, TCC4TCL_COMPILE, + TCC4TCL_DEFINE, TCC4TCL_GET_SYMBOL, TCC4TCL_OUTPUT_FILE, TCC4TCL_UNDEFINE, + TCC4TCL_ADD_RUNTIME_SYM }; + char *str; ts = (struct TclTCCState *) cdata; s = ts->s; if (objc < 2) { @@ -78,19 +91,19 @@ if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0, &index) != TCL_OK) { return TCL_ERROR; } switch (index) { - case TCLTCC_ADD_INCLUDE: + case TCC4TCL_ADD_INCLUDE: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "path"); return TCL_ERROR; } else { tcc_add_include_path(s, Tcl_GetString(objv[2])); return TCL_OK; } - case TCLTCC_ADD_FILE: + case TCC4TCL_ADD_FILE: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "filename"); return TCL_ERROR; } else { if(tcc_add_file(s, Tcl_GetString(objv[2]))!=0) { @@ -97,38 +110,38 @@ return TCL_ERROR; } else { return TCL_OK; } } - case TCLTCC_ADD_LIBRARY: + case TCC4TCL_ADD_LIBRARY: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "lib"); return TCL_ERROR; } else { tcc_add_library(s, Tcl_GetString(objv[2])); return TCL_OK; } - case TCLTCC_ADD_LIBRARY_PATH: + case TCC4TCL_ADD_LIBRARY_PATH: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "path"); return TCL_ERROR; } else { tcc_add_library_path(s, Tcl_GetString(objv[2])); return TCL_OK; } -#if 0 - case TCLTCC_ADD_SYMBOL: + case TCC4TCL_ADD_SYMBOL: if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "symbol value"); return TCL_ERROR; } - Tcl_GetLongFromObj(interp,objv[3], &val); + + Tcl_GetLongFromObj(interp, objv[3], &val); + val_p = (void *) val; - tcc_add_symbol(s,Tcl_GetString(objv[2]),val); + tcc_add_symbol(s,Tcl_GetString(objv[2]), val_p); return TCL_OK; -#endif - case TCLTCC_COMMAND: + case TCC4TCL_COMMAND: if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "tclname cname"); return TCL_ERROR; } if (!ts->relocated) { @@ -147,11 +160,11 @@ } /*printf("symbol: %x\n",val); */ Tcl_CreateObjCommand(interp,Tcl_GetString(objv[2]),val_p,NULL,NULL); return TCL_OK; - case TCLTCC_COMPILE: + case TCC4TCL_COMPILE: if(ts->relocated == 1) { Tcl_AppendResult(interp, "code already relocated, cannot compile more",NULL); return TCL_ERROR; } if (objc != 3) { @@ -167,18 +180,18 @@ return TCL_ERROR; } else { return TCL_OK; } } - case TCLTCC_DEFINE: + case TCC4TCL_DEFINE: if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "symbol value"); return TCL_ERROR; } tcc_define_symbol(s,Tcl_GetString(objv[2]),Tcl_GetString(objv[3])); return TCL_OK; - case TCLTCC_GET_SYMBOL: + case TCC4TCL_GET_SYMBOL: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "symbol"); return TCL_ERROR; } if (!ts->relocated) { @@ -195,11 +208,11 @@ return TCL_ERROR; } sym_addr = Tcl_NewWideIntObj((Tcl_WideInt) val_p); Tcl_SetObjResult(interp, sym_addr); return TCL_OK; - case TCLTCC_OUTPUT_FILE: + case TCC4TCL_OUTPUT_FILE: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "filename"); return TCL_ERROR; } if (ts->relocated) { @@ -216,17 +229,66 @@ Tcl_AppendResult(interp, "output to file failed", NULL); return TCL_ERROR; } else { return TCL_OK; } - case TCLTCC_UNDEFINE: + case TCC4TCL_UNDEFINE: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "symbol"); return TCL_ERROR; } tcc_undefine_symbol(s,Tcl_GetString(objv[2])); return TCL_OK; + case TCC4TCL_ADD_RUNTIME_SYM: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "symbol_name"); + return(TCL_ERROR); + } + + str = Tcl_GetString(objv[2]); +#ifdef HAVE_DLSYM + val_p = dlsym(NULL, str); +#elif defined(HAVE_ENUMPROCESSMODULES) + val_p = NULL; + { + HANDLE cur_proc; + HMODULE *modules; + DWORD needed, i; + + needed = 0; + + cur_proc = GetCurrentProcess(); + EnumProcessModules(cur_proc, NULL, 0, &needed); + + if (needed > 0) { + modules = (void *) ckalloc(needed); + if (EnumProcessModules(cur_proc, modules, needed, &needed)) { + for (i = 0; i < (needed / sizeof(HMODULE)); i++) { + val_p = (void *) GetProcAddress(modules[i], str); + + if (val_p) { + break; + } + } + } + + ckfree((void *) modules); + } + } +#else + val_p = NULL; +#endif + + if (val_p == NULL) { + Tcl_AppendResult(interp, "symbol not found", NULL); + + return(TCL_ERROR); + } + + tcc_add_symbol(s, Tcl_GetString(objv[2]), val_p); + + return(TCL_OK); default: Tcl_Panic("internal error during option lookup"); } return TCL_OK; } @@ -269,10 +331,12 @@ ts->relocated = 0; /*printf("type: %d\n", index); */ tcc_set_output_type(s,index); Tcl_CreateObjCommand(interp,Tcl_GetString(objv[objc-1]),Tcc4tclHandleCmd,ts,Tcc4tclCCommandDeleteProc); + + Tcl_SetObjResult(interp, objv[objc-1]); return TCL_OK; } int Tcc4tcl_Init(Tcl_Interp *interp) {