How is it possible to compile code from code - function

I want to experiment with the programs that write programs in C code, and i want to use construction like following:
int main() {
char* srcCode="int f(int x) { return x+42; }";
int (*compiledFun)(int) = compile(srcCode);
printf("result=%d", (*compiledFun)(123));
return 0;
}
Desired output should be printed "result=165".
My question is about compile() function. I may try to put srcCode in a file, then invoke external compiler, like gcc, then try to read produced binary, probably fix some addresses, and so to fill the compiledFun memory. But I feel like that would be a very inefficient stub. Is there any way to compile a program from within a program, directly from memory to memory? Maybe some library or a subset that can be ripped off gcc sources, responsible for producting binary code from source text?
That may be important addition, all source code that should be compiled is a function that takes arguments and returns. It will not call any external libraries and function like printf, but only do some calculations and return.

Use libtcc an in-memory C compiler from TinyC.
A complete example from here https://github.com/TinyCC/tinycc/blob/mob/tests/libtcc_test.c
/*
* Simple Test program for libtcc
*
* libtcc can be useful to use tcc as a "backend" for a code generator.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "libtcc.h"
/* this function is called by the generated code */
int add(int a, int b)
{
return a + b;
}
/* this strinc is referenced by the generated code */
const char hello[] = "Hello World!";
char my_program[] =
"#include <tcclib.h>\n" /* include the "Simple libc header for TCC" */
"extern int add(int a, int b);\n"
"#ifdef _WIN32\n" /* dynamically linked data needs 'dllimport' */
" __attribute__((dllimport))\n"
"#endif\n"
"extern const char hello[];\n"
"int fib(int n)\n"
"{\n"
" if (n <= 2)\n"
" return 1;\n"
" else\n"
" return fib(n-1) + fib(n-2);\n"
"}\n"
"\n"
"int foo(int n)\n"
"{\n"
" printf(\"%s\\n\", hello);\n"
" printf(\"fib(%d) = %d\\n\", n, fib(n));\n"
" printf(\"add(%d, %d) = %d\\n\", n, 2 * n, add(n, 2 * n));\n"
" return 0;\n"
"}\n";
int main(int argc, char **argv)
{
TCCState *s;
int i;
int (*func)(int);
s = tcc_new();
if (!s) {
fprintf(stderr, "Could not create tcc state\n");
exit(1);
}
/* if tcclib.h and libtcc1.a are not installed, where can we find them */
for (i = 1; i < argc; ++i) {
char *a = argv[i];
if (a[0] == '-') {
if (a[1] == 'B')
tcc_set_lib_path(s, a+2);
else if (a[1] == 'I')
tcc_add_include_path(s, a+2);
else if (a[1] == 'L')
tcc_add_library_path(s, a+2);
}
}
/* MUST BE CALLED before any compilation */
tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
if (tcc_compile_string(s, my_program) == -1)
return 1;
/* as a test, we add symbols 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, "add", add);
tcc_add_symbol(s, "hello", hello);
/* relocate the code */
if (tcc_relocate(s, TCC_RELOCATE_AUTO) < 0)
return 1;
/* get entry symbol */
func = tcc_get_symbol(s, "foo");
if (!func)
return 1;
/* run the code */
func(32);
/* delete the state */
tcc_delete(s);
return 0;
}

Related

TCL tclOODecls.h Functions Not Exported

My compiled TCL library (Tcl8.6.7, win7) didn't export the functions in tclOODecls.h. I exported the functions by putting: #define TCLAPI extern DLLEXPORT in tclOODecls.h before the auto generated section.
I would like to know why the functions were not exported by default and the preferred way of enabling the export.
The symbols have been defined to use MODULE_SCOPE. See issue 3010352 which mentions this a while ago. The idea is that if you want to use these symbols you should be using the Tcl stubs linking mechanism and define the USE_TCLOO_STUBS macro and link with the stubs library (tclstub86). The functions are in there - just not exported on the DLL exports.
From tcl.h:
/*
* Include platform specific public function declarations that are accessible
* via the stubs table. Make all TclOO symbols MODULE_SCOPE (which only
* has effect on building it as a shared library). See ticket [3010352].
*/
Example of static embedding Tcl with TclOO API usage
The following code will build an executable that works like the standard Tcl shell but includes an additional command that accesses the TclOO API as a demonstration.
/* Demonstrate embedding Tcl and using the TclOO API.
*
* Build with MSVC (adjust paths for local setup):
*
* cl -nologo -W3 -MT -Zi -GL -DSTATIC_BUILD -Ic:\opt\tcl\include test_embed_oo.c \
* -Fe:test_embed_oo.exe -link -debug -subsystem:console -ltcg -libpath:C:\src\tcl\kitgen\8.6\tcl\win\Release_VC13 \
* tcl86ts.lib user32.lib ws2_32.lib netapi32.lib
*
* Requires a static libary if Tcl (tcl86ts.lib on windows)
*/
#include <tcl.h>
#include <tclOO.h>
#include <locale.h>
static int
GetObjectNameCmd(ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[])
{
int r = TCL_ERROR;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "object");
return r;
}
Tcl_Object object = Tcl_GetObjectFromObj(interp, objv[1]);
if (object != NULL) {
Tcl_Obj *resultObj = Tcl_GetObjectName(interp, object);
if (resultObj != NULL) {
Tcl_SetObjResult(interp, resultObj);
r = TCL_OK;
}
}
return r;
}
#define TCL_LOCAL_APPINIT Custom_AppInit
int
Custom_AppInit(Tcl_Interp *interp)
{
Tcl_CreateObjCommand(interp, "getobjectname", GetObjectNameCmd, NULL, NULL);
return Tcl_Eval(interp, "source test_embed_oo.tcl");
}
#include "c:/src/tcl/kitgen/8.6/tcl/win/tclAppInit.c"
Embed Tcl using dynamic loading
Tcl can be linked to an application dynamically using the Tcl stubs linkage mechanism. This requires loading two functions from the DLL and then initializing the stubs table. The following shows this with TclOO access enabled.
/* Demonstrate embedding Tcl and using the TclOO API via stubs
*
* Build with MSVC (adjust paths for local setup):
*
* cl -nologo -W3 -MD -Zi -GL -Ic:\opt\tcl\include test_embed_oo_ex.c \
* -Fe:test_embed_oo_ex.exe -link -debug -ltcg -subsystem:console \
* -libpath:C:\opt\tcl\lib tclstub86.lib user32.lib
*
* Dynamically loads Tcl and then uses stubs for API access.
*/
#define WIN32_LEAN_AND_MEAN
#define STRICT
#include <windows.h>
#include <locale.h>
#define USE_TCL_STUBS
#define USE_TCLOO_STUBS
#include <tcl.h>
#include <tclOO.h>
static int
GetObjectNameCmd(ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[])
{
int r = TCL_ERROR;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "object");
return r;
}
Tcl_Object object = Tcl_GetObjectFromObj(interp, objv[1]);
if (object != NULL) {
Tcl_Obj *resultObj = Tcl_GetObjectName(interp, object);
if (resultObj != NULL) {
Tcl_SetObjResult(interp, resultObj);
r = TCL_OK;
}
}
return r;
}
typedef Tcl_Interp *(*LPFNTCLCREATEINTERP)();
typedef void *(*LPFNTCLFINDEXECUTABLE)(const char *);
static Tcl_Interp *
InitializeTcl(int argc, char *argv[])
{
Tcl_Interp *interp = NULL;
//Tcl_DString dString;
char szLibrary[16];
int nMinor;
HINSTANCE hTcl = NULL;
for (nMinor = 6; hTcl == NULL && nMinor > 4; nMinor--) {
wsprintfA(szLibrary, "tcl8%d.dll", nMinor);
hTcl = LoadLibraryA(szLibrary);
}
if (hTcl != NULL) {
LPFNTCLCREATEINTERP lpfnTcl_CreateInterp;
LPFNTCLFINDEXECUTABLE lpfnTcl_FindExecutable;
lpfnTcl_CreateInterp = (LPFNTCLCREATEINTERP)
GetProcAddress(hTcl, "Tcl_CreateInterp");
lpfnTcl_FindExecutable = (LPFNTCLFINDEXECUTABLE)
GetProcAddress(hTcl, "Tcl_FindExecutable");
if (lpfnTcl_CreateInterp != NULL) {
interp = lpfnTcl_CreateInterp();
if (interp != NULL) {
Tcl_InitStubs(interp, "8.6", 0);
#ifdef USE_TCLOO_STUBS
Tcl_OOInitStubs(interp);
#endif
lpfnTcl_FindExecutable(argv[0]);
Tcl_InitMemory(interp);
Tcl_Init(interp);
}
}
}
return interp;
}
/*
* Embed tcl interpreter into a C program.
*/
int
main(int argc, char *argv[])
{
Tcl_Interp *interp = NULL;
int r = TCL_ERROR;
setlocale(LC_ALL, "C");
interp = InitializeTcl(argc, argv);
if (interp == NULL) {
fprintf(stderr, "error: failed to initialize Tcl runtime\n");
} else {
Tcl_CreateObjCommand(interp, "getobjectname", GetObjectNameCmd, NULL, NULL);
if (argc > 1) {
r = Tcl_EvalFile(interp, argv[1]);
printf(Tcl_GetStringResult(interp));
}
Tcl_DeleteInterp(interp);
}
return r;
}
To test this you want a file that contains some tcl code that can call getobjectname and run the executable with the path to this file as the only argument.

How to reverse a structure in text file with C?

I have an exercise and I don't know how to solve it well!
I want write a C program that give from user the information of a student and then save it to file A.txt. After that reverse the first name, last name and student number and save it to file B.txt.
For example:
john
lopez
123456
It changes to:
nhoj
zepol
654321
#include <stdio.h>
#include <stdlib.h>
#define SIZE 50
struct student {
char fname[SIZE];
char lname[SIZE];
char num[SIZE];
}st;
int main()
{
FILE *in, *out;
char ch;
int tmp=0,flag=0,i;
printf("INPUT First name: ");
scanf("%s", &st.fname);
printf("INPUT Last name: ");
scanf("%s", &st.lname);
printf("INPUT personal num: ");
scanf("%s", &st.num);
in= fopen("A.txt", "w");
fputs(st.fname, in);
fputs(st.lname, in);
fputs(st.num, in);
fclose(in);
in= fopen("A.txt", "r");
out=fopen("B.txt", "w");
fgets(st.fname, strlen(st.fname)+1,in);
strrev(st.fname);
fputs(st.fname, out);
printf("\n%s", st.fname);
fgets(st.lname, strlen(st.lname)+1, in);
strrev(st.lname);
fputs(st.lname, out);
printf("\n%s", st.lname);
fgets(st.num, strlen(st.num)+1, in);
strrev(&st.num);
fputs(st.num, out);
printf("\n%d", st.num);
fclose(in);
fclose(out);
return 0;
}
If you want to copy the data to a file, then you first need to put the data in some dynamic memory allocation and then after reversing the content required in dynamic memory, you need to copy it into your file.
this is the program to reverse the each word in given string
#include
#include
void reverse_string(char*);
void reverse_words(char*);
int main() {
char a[100];
gets(a);
reverse_words(a);
printf("%s\n", a);
return 0;
}
void reverse_words(char *s) {
char b[100], *t, *z;
int c = 0;
t = s;
while(*t) { //processing complete string
while(*t != ' ' && *t != '\0') { //extracting word from string
b[c] = *t;
t++;
c++;
}
b[c] = '\0';
c = 0;
reverse_string(b); // reverse the extracted word
z = b;
while (*z) { //copying the reversed word into original string
*s = *z;
z++;
s++;
}
while (*s == ' ') { // skipping space(s)
s++;
}
/*
* You may use if statement in place of while loop if
* you are assuming only one space between words. If condition is
* used because null terminator can also occur after a word, in
* that case we don't want to increment pointer.
* if (*s == ' ') {
* s++;
* }
*/
t = s; // pointing to next word
}
}
/*
* Function to reverse a word.
*/
void reverse_string(char *t) {
int l, c;
char *e, s;
l = strlen(t);
e = t + l - 1;
for (c = 0; c < l/2; c++) {
s = *t;
*t = *e;
*e = s;
t++;
e--;
}
}
Then you can try using fputc, i.e., reading char by char along with a loop to get your data line by line as 3 lines.
char *ch;
for(i=0;st.fname[i];i++)
{
ch=getc(st.fname[i]);
fputc(ch,in);
}
repeat the same even for st.lname and st.num

C++ program called "Palindrome integer" two func. Function 1// Return reversal integer. Function 2// Returns true if palindrome

Please Help
I am writing a program in C++ using visual basic 2010 the program is called "Palindrome integer" I need to write two functions one that//Return the reversal of an integer. For example reverse(456) returns 654
//with header:-->
int reverse(int number)
I need to write another function that//Returns true if number is a palindrome
//with header:-->
bool isPalindrome(int number)
I need to use the reverse function to implement the function isPalindrome. A number is a palindrome if the numbers reversal is the same as itself. My program should report whether the number is a palindrome. Everything is in one file.
I think this program worked when I first wrote the code not as two functions but just directly into int main(). But I must put the code into the specified two functions and once I had done that and made the adjustments I got the following error messages and the black cout display box didn't appear. Here's a snippet of the error report followed by the full error report
: error LNK2005: "int __cdecl reverse(int)" (?reverse##YAHH#Z) already defined in Driver.obj
:fatal error LNK1169: one or more multiply defined symbols found
I'm getting the following Error Report
1>------ Build started: Project: Palindrome integer, Configuration: Debug Win32 ------
1>Build started 12/7/2013 4:54:25 PM.
1>InitializeBuildStatus:
1> Touching "Debug\Palindrome integer.unsuccessfulbuild".
1>ClCompile:
1> All outputs are up-to-date.
1>ManifestResourceCompile:
1> All outputs are up-to-date.
1>implementation.obj : error LNK2005: "int __cdecl reverse(int)" (?reverse##YAHH#Z) already defined in Driver.obj
1>c:\documents and settings\dell\my documents\visual studio 2010\Projects\Palindrome integer\Debug\Palindrome integer.exe : fatal error LNK1169: one or more multiply defined symbols found
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:02.25
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
//Bellow is my Code
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
//Retun reversal of an integer
int reverse(int number); //function prototype
//Return true if number is a palindrome
bool isPalindrome(int number); //function prototype
//Driver
int main()
{
int usersNumber = 456; //0; //a few lines commented tempararily for easier number testing
// cout<<"Enter a number and I'll tell you if it's a Palindrome: ";
// cin>> usersNumber;
bool palindromeToF = (isPalindrome(usersNumber));
if (palindromeToF == true)
{
cout <<"YES the number is a Palindrome";
}
else
{
cout <<"NO the number is not a Palindrome";
}
return 0;
}
//function Implementation
//Retun reversal of an integer
int reverse(int number)
{
//do while loop to count number of digits in Number
int digitsCount = 0;
double exponent1 = 1.0;
int quotient;
do
{
int tenToPower = pow( 10.0, exponent1);
// cout <<"tenToPower "<< tenToPower <<"\t ";
quotient = (number / tenToPower);
// cout <<"exponent1 "<< exponent1<<"\t ";
exponent1++;
//cout <<"quotient "<< quotient<< "\t "<<endl;
digitsCount++;
}while (!quotient == 0);
//populating array "arrDigits" with integer's digits
int *arrDigits = NULL;
arrDigits = new int[digitsCount];
double exponent2 = 0.0;
for(int i = 0; i < digitsCount; i++)
{
int powerOfTen = pow( 10.0, exponent2);
//cout <<endl<<"adding "<<((number / powerOfTen) % 10) <<" to sum";
//cout <<powerOfTen;
arrDigits[i]= ((number / powerOfTen) % 10);
exponent2++;
}
//reverse number & populate array "arrDigRevers" with reversed order number
int *arrDigRevers = NULL;
arrDigRevers = new int[digitsCount];
int j = 0;
int reversedNum = 0;
double exponent3 = 0.0;
for(int i = digitsCount-1; i >= 0; i--)
{
int powerOfTenB = pow( 10.0, exponent3);
reversedNum += (powerOfTenB * arrDigits[i]); //return of reverse func.
exponent3++;
/* //reversed integer put into array
if(j < digitsCount)
{
arrDigRevers[j] = arrDigits[i];
//cout <<"\t"<< "arrDigRevers"<<"["<< j<<"]="<< arrDigRevers[j]<<" "<< "arrDigits"<<"["<< j<<"]="<< " "<<arrDigits[j]<<" ";
j++;
}
*/
}
delete[] arrDigits;
delete[] arrDigRevers;
arrDigits = NULL;
arrDigRevers = NULL;
//cout <<endl<<"reversed number is "<< reversedNum;
return reversedNum;
}
//function Implementation
//Return true if number is a palindrome
bool isPalindrome(int number)
{
if(number == reverse(number))
{
return true;
}
else
{
return false;
}
}
The answer lies here:
1>implementation.obj : error LNK2005: "int __cdecl reverse(int)" (?reverse##YAHH#Z) already defined in Driver.obj
It appears that have defined int reverse(int number) in both implementation.cpp and Driver.cpp. You need to rename or remove one of these definitions from your project.

How to call exported function from dll in C/C++?

My aim is to call some function via its address. How can I do it?
I have done the next work for such aim, but at first(1) - I've got access violation ( don't know why ) and with the second I have some problems with calling function is ASM with ESP value...
The first (the problem with access violation):
#include <iostream>
#include <Windows.h>
const DWORD_PTR offset = 0x00001a90;
typedef void (__stdcall *uef)(int);
int main(void)
{
HMODULE hModule = LoadLibrary(L"C:\\Windows\\system32\\OpenAL32.dll");
DWORD_PTR addr = (DWORD_PTR)hModule + offset;
uef func = (uef)offset;
func(0);
return 0;
}
The second (problems at runtime with ESP value):
#include <iostream>
#include <Windows.h>
typedef void (__stdcall *uef)(int);
int main(void)
{
HMODULE hModule = LoadLibrary(L"C:\\Windows\\system32\\OpenAL32.dll");
uef obj = NULL;
if(hModule != NULL)
{
obj = reinterpret_cast<uef>(GetProcAddress(hModule, "alEnable"));
}
if(obj != NULL)
{
(*obj)(0);
}
if(hModule != NULL)
{
FreeLibrary(hModule);
}
return 0;
}
How could I solve this problem?
PS
And the another main question is:
How can I dynamically calculate the function address in runtime for next calling?
Thanks,
Best Regards!
First, there is a major issue (hence the access violation) with the hardcoded address offset (const DWORD_PTR offset = 0x00001a90). Don't do that! How can you know that the offsett will not be changed because of ASLR?

How to call MessageBox with GetProcAddress function?

I want to call MessageBox() function in such way:
1). load needed library
2). get the function address
3). call it
So, for such aim as I understand, I should define new type with all types of arguments in MessageBox function.
It returnes INT and accepts: HWND, LPCSTR, LPCSTR, UNIT.
So I registred new type:
typedef int(__stdcall *msgbox)(HWND, LPCSTR, LPCSTR, UINT);
I have problems with calling such function. Does such way work for all functions or only for exported?
How can I call MessageBox exactly in such way?
Full code:
#include <iostream>
#include <windows.h>
using namespace std;
typedef int(__stdcall *msgbox)(HWND, LPCSTR, LPCSTR, UINT);
int main(void)
{
HINSTANCE__ *hModule = LoadLibrary(L"\\Windows\\System32\\User32.dll");
msgbox *me = 0;
if(hModule != 0)
{
me = (msgbox*)GetProcAddress(hModule, "MessageBox");
}
return 0;
}
Why are you declaring everything as a pointer?
LoadLibrary returns an HMODULE, not an HINSTANCE__ * (it will work with the latter but it's always better to adhere to the documentation).
Similarly, msgbox is typedef'd to a function pointer type, so me is a msgbox, not a msgbox *.
The reason why GetProcAddress fails is because user32.dll exports 2 functions, MessageBoxA and MessageBoxW. When you simply call MessageBox in your code, macros defined in Windows.h replace it with one of the 2 actual function names depending on whether you're compiling for UNICODE or not. But when you're trying to directly access the exported function as you are doing, you need to explicitly specify which one you're trying to get a pointer to.
#include <iostream>
#include <windows.h>
typedef int(__stdcall *msgbox)(HWND, LPCSTR, LPCSTR, UINT);
int main(void)
{
HMODULE hModule = ::LoadLibrary(L"User32.dll");
msgbox me = NULL;
if( hModule != NULL ) {
me = reinterpret_cast<msgbox>( ::GetProcAddress(hModule, "MessageBoxA") );
}
if( me != NULL ) {
(*me)( NULL, "I'm a MessageBox", "Hello", MB_OK );
}
if( hModule != NULL ) {
::FreeLibrary( hModule );
}
}