Jonnycake Posted April 15, 2009 Share Posted April 15, 2009 So, I'm trying to write an eval function in C because it sounds like a fun and challenging idea. So, I have this so far: #include <stdio.h> int eval(int* funaddr) { asm( "calll %0\n" : : "r" (funaddr) ); return 0; } int whatever() { printf("Hi, whatever() was executed :D :D :D.\n"); return 0; } int main() { eval((int*) &whatever); return 0; } What I'm trying to figure out how is how I would make it so that a user could input the name of the function and it would execute it. This would require me translating their input into an address of the function which is named that and since the functions don't have names after it's compiled, I'm running into a problem. The only way I can think about doing it is if I were to look at the function table in the file like what gdb does when it translates the function addresses to names. Does anyone else have a better idea? Edit: Also, when I compile I get this warning: /tmp/ccxrgb26.s: Assembler messages: /tmp/ccxrgb26.s:10: Warning: indirect call without `*' When it's run, it still works, but I was wondering if this is necessary to fix (as it doesn't appear to be) and if it is, how could I fix it? Quote Link to comment Share on other sites More sharing options...
Gyf Posted May 14, 2009 Share Posted May 14, 2009 I'm not sure if I completely understand you but if i am thinking what you are thinking :P you can use function pointers! :P (as long as the functions have the same return type) So I am going to use these functions: int first_function() { printf("Hey I am the First Function \n"); return 0; } int second_function() { printf("Hey I am the Second Function \n"); return 0; } now lets go ahead and make the main code: //main.c #include <stdio.h> #include <string.h> // Declare Function prototypes int first_function(void); int second_function(void); int main(int argc, char **argv) { //our generic function will be generi_func which will // be assigned one of the two int (*generic_func) (void) = NULL; //just some input parsing that is only used to select //either function and set the address of our temp //function to that needed. if(strcmp(argv[1], "first") == 0) { generic_func = &first_function; return generic_func(); } else if(strcmp(argv[1], "second") == 0) { generic_func = &second_function; return generic_func(); } } //Declare Functions int first_function() { printf("Hey I am the First Function \n"); return 0; } int second_function() { printf("Hey I am the Second Function \n"); return 0; } Now if i run: >gnuc main.c >a.out first this will run the first_function and if i run >gnuc main.c >a.out second it will run the second function (also if you run just >a.out the program will segfault as i made this in a few minutes and didn't put any error checking in) If this is what you were looking for..GREAT!!...if not well sorry but someone else may learn something from it. If it is what you wanted and don't understand some parts just drop me a line! Quote Link to comment Share on other sites More sharing options...
Jonnycake Posted May 14, 2009 Author Share Posted May 14, 2009 Hey, thanks for replying. That's sort of what I wanted, but not exactly. I know about function pointers and stuff like that. My problem is that I want to not have to explicitly define names. For example, I want to be able to run a program which accepts input which will be run like it would be if it were in a compiled program. Like, an input of printf("Hi\n"); should print Hi to the screen. I've been trying to look into the ELF file structure and getting the memory address from there, atm, this is my eval function: // Call the function located at funaddr using the arguments in argv[] int eval(int* funaddr,int argc,char* argv[]) { int x; // Set up the stack to run the function for(x=argc-1;x>=0;x--) asm( "pushl %0\n" : : "r" (argv[x]) ); // Call the function asm( "call *%0\n" : : "r" (funaddr) ); // %eax has not been reset so it will return the return value of the function called return; } My problem is getting the function address so that I can run it (which I assume I can do since gdb does). Anyway, hope I made what I wanted a little clearer. Edit: BTW, example of the use of the function: eval((int*) &printf,1,"Hi\n");. Quote Link to comment Share on other sites More sharing options...
OneTimePad Posted May 15, 2009 Share Posted May 15, 2009 The problem with an eval() in C is that C is a compiled language, so by the time the user enters the string to evaluate, function names and other higher level language features have been reduced to machine code. This is why C doesn't have a built-in eval function, but an interpreted language like javascript does: in js, when eval() is called, it is translated into machine code on-the-fly, so interpreting the string you want to evaluate is just a matter of sending it to the interpreter. So, there are two ways to do an eval-like function in C that I can think of: 1) If you only need a limited number of commands, you could build a small interpreter that would parse the supplied string and execute the appropriate function calls, etc. Theoretically, you could write something universal, but then you'd have a full C interpreter, and I doubt you want to embark on a project that ambitious... 2) You could: i) wrap the input string in a "main(){...}", ii) write this to a file (with appropriate #includes, etc), iii) compile the file with gcc, iv) execute the generated binary as a child process, and v) after execution, return control to the main program and delete the files from ii) and iii)... Solution 1) would give you access to only as many features as you code for, but it would give you access to other parts of your program. Solution 2) would allow you to enter any C code, but you wouldn't be able to access other parts of your program directly. Edit: Info on how GDB gets it's symbolic information (e.g. function and variable names, etc) here: http://sourceware.org/gdb/current/onlinedo...nt_8.html#SEC49 Quote Link to comment Share on other sites More sharing options...
Gyf Posted May 16, 2009 Share Posted May 16, 2009 Theoretically, you could write something universal, but then you'd have a full C interpreter, and I doubt you want to embark on a project that ambitious... Haha...I actually thought about that >_>...don't make a C interpreter :P Quote Link to comment Share on other sites More sharing options...
Jonnycake Posted May 16, 2009 Author Share Posted May 16, 2009 @OneTimePad: Thanks for the link, I'll look at it a little bit later today. I think I'm probably just gonna make it able to run functions and have variables. Of course, writing it so that it can do while and for loops would be fun too *thinks*. Would take lots of code, but would be totally worth it lol. @Gyf: Well, it would be fun :P Quote Link to comment Share on other sites More sharing options...
Gyf Posted May 16, 2009 Share Posted May 16, 2009 Haha I would totally be up for making a C interpreter, however I don't see myself making a useful one in the near or distant future :P Was this just an experiment you were conducting Jonnycake? Or do you actually need it done? If you need it done and are not restricted to a language check out C# (looking at the internet it looks like it lets you do what you are trying to achieve a lot easier than C but that is ually the case with C# and C lol) or err BAH i forgot the other language :P I wrote it down at home (YES WITH A PENCIL AND ACTUAL PAPER) but yeah :P Quote Link to comment Share on other sites More sharing options...
Jonnycake Posted May 16, 2009 Author Share Posted May 16, 2009 Lol, yeah, just an experiment (and I'm trying to impress my algebra teacher that used to be a software engineer :P). Quote Link to comment Share on other sites More sharing options...
Gyf Posted May 17, 2009 Share Posted May 17, 2009 Hahaha. Totally make a C interpreter then XD Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.