I have this c program:
#include <sys/types.h>
#include "ourhdr.h"
int glob = 6; /* external variable in initialized data */
char buf[] = "a write to stdout\n";
int
main(void)
{
int var; /* automatic variable on the stack */
pid_t pid;
var = 88;
if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1)
err_sys("write error");
printf("before fork\n"); /* we don't flush stdout */
if ( (pid = fork()) < 0)
err_sys("fork error");
else if (pid == 0) { /* child */
glob++; /* modify variables */
var++;
} else
sleep(2); /* parent */
printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var);
exit(0);
}
In the header file "ourhdr.h" (located in the same folder) i defined several functions, such as err_sys().
I get this error while compiling with gcc:
In function "main":
undefined reference to "err_sys"
How can i get this working? I can post the header file here if needed. Thank you.
** EDIT: ** This is the ourhdr.h file: http://pastebin.com/fMUiG4zU
You have included the header file with the declaration of err_sys. Ensure you have also an implementation that is passed to the linker. Background:
The compiler compiles a module to an object file:
g++ -c modul1.c generates modul1.o
g++ -c modul2.c generates modul2.o
Each of the modules can reference functions that are defined in a included header file. Up to here, no actual implementation of that function is needed.
In the next step, the linker links toghether all object files (and libraries):
g++ modul1.o modul2.o generates ./a.out or similar
In the second step, an implementation for all used functions is needed. Be sure you provided it!
(P.S.: Some compilers allow compiling and linking with one command, if you have multiple modules you can perhaps add them to a single gcc-call. I'd recomment to use make though)
I think what's likely to happen is that you have a header, ourhdr.h, containing the definition of the function, but the implementation is in a different file: ourhdr.c. In that case, if you try to compile without including ourhdr.c you'll get a reference error:
$ gcc main.c
/bin/ld: /tmp/ccVzNF6w.o: in function `main':
main.c:(.text+0x38): undefined reference to `err_sys'
To fix it, you need to compile like this:
$ gcc main.c ourhdr.c
Another option is to define the body of the function in ourhdr.h:
// ourhdr.h
#include <stdio.h>
void err_sys(const char* str);
void err_sys(const char* str) {
fprintf(stderr, "%s\n", str);
}
In that case, gcc main.c should work.
For me, it is compiling and working fine if you write the function name is written correctly.
Related
I have one base library written in C. And other external extensions/definitions files. With a simple search tool the base library (when is used) can search in a directory for extensions libraries. Without telling the compiler which files it are. Then the C program can call a function in that external file.
So i want to run a function in a external file. I can choose which file I want to run the function from at running time. (Ex, I enter that the file is located at ./external_file at running time) (NOT COMPILE TIME!). Is this possible?
I need to read a return from the function, I need to wait until the function is finished, I need to call the function with arguments and it must be possible that the program at run time can choose the file and function.
Is this possible? Yes, program files does contains function names (with names). Only I need to know HOW do I call that function in a external file at run time.
Use dynamic libraries - most OS's provide support for loading a library given a name and getting the address of the function to call.
In windows see LoadLibrary and ProcAddress. In linux see dlopen and dlsym.
You can use the dlopen function to load a shared library (i.e. a .so file) at runtime, then use dlsym to get the functions to call.
For example, suppose you had the following library file:
mylib.c:
#include <stdio.h>
void f1(int a)
{
printf("in f1, a=%d\n", a);
}
int f2(char *s)
{
printf("in f2, s=%s\n", s);
return *s;
}
Then you compile it to a shared library:
gcc -g -Wall -Wextra -fPIC -c mylib.c
gcc -g -Wall -Wextra -fPIC -o libmylib.so mylib.o
You can call these functions as follows:
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main()
{
// get a handle to the shared library
void *handle = dlopen("./libmylib.so", RTLD_LAZY);
if (!handle) {
printf("dlopen failed: %s\n", dlerror());
exit(1);
}
// get a pointer to the function to call
void (*myf1)(int) = dlsym(handle, "f1");
if (!myf1) {
printf("dlsym 1 failed: %s\n", dlerror());
exit(1);
}
myf1(4);
// get a pointer to another function to call
int (*myf2)(char *) = dlsym(handle, "f2");
if (!myf2) {
printf("dlsym 2 failed: %s\n", dlerror());
exit(1);
}
printf("rval=%d\n", myf2("hello"));
dlclose(handle);
return 0;
}
Note that you need to know at compile time what the function signatures look like so you can call them correctly.
I'm trying to compile this code which call func from "libcfmapi.so" to decrypt "cfg" file
#include <stdlib.h>
#include <stdio.h>
int restorebackup(const char *tmp_cfg_name,const char *xml_cfg_name);
int ATP_CFM_ExtCustomImportEncryptedUserCfgFile(const char *tmp_cfg_name);
int main(int argc, char **argv)
{
int ret;
if(argc < 3)
{
printf("specify temp config file name.\n");
exit(1);
}
ret=restorebackup(argv[1],argv[2]);
return ret;
}
int restorebackup(const char *tmp_cfg_name,const char *xml_cfg_name)
{
int ret=0;
//ret = ATP_CFM_ExtDigVerifyFile(tmp_cfg_name,tmp_cfg_name);
if(ret != 0)
{
printf("Verify File failed.\n");
return ret;
}
ret = ATP_CFM_ExtCustomImportEncryptedUserCfgFile(tmp_cfg_name);
return ret;
}
but got error regarding func type declare
root#kali:~/debian-qemu# gcc h.c -o demo
/tmp/ccVbt5NT.o: In function `restorebackup':
h.c:(.text+0x8c): undefined reference to `ATP_CFM_ExtCustomImportEncryptedUserCfgFile'
collect2: error: ld returned 1 exit status
any help appreciated
The reason you're getting this error is because you're not linking against the required library, libcfmapi.so.
This is not a library you would expect to find in your Debian system as it is unique to the BT device you're trying to hack.
In short - get the lib from your device, cross compile to the device architecture against the lib you extracted from the device and you should be fine.
More information based on Ishay Peled answer:
readelf -s <pulled library> | grep ATP_CFM_ExtCustomImportEncryptedUserCfgFile
I suspect the problem isn't that function you call doesn't exist but rather there are no functions being displayed it is most likely empty just like nm result:
nm: libcfmapi.so: no symbols
do the command without piping to grep, my bet is your output is:
readelf -s libcfmapi.so
Dynamic symbol information is not available for displaying symbols.
If someone knows the way of getting the headers from the file, i believe then you can find your function you require then link and run (i too am trying to use libcfmapi.so, but lack the programming/reversing knowledge required).
when using a library, then must:
include that library in the link statement via
-l cfmapi
include the header file for that library in the source code:
#include <cfmapi.h>
I created a program in C and I tried to compile it. When I use my gcc 4.8.1 compiler in Widows everything worked and my program too.
I compiled with the following arguments:
gcc -std=c99 -O2 -DCONTEST -s -static -lm children.c
But in linux I getting the following error:
/usr/lib/gcc/i486-linux-gnu/4.7/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: error: ld returned 1 exit status
Why is that? My programm is working and I can't understand why I getting compiling errors in linux.
My code is:
/*---------------------*/
/* included files */
/*---------------------*/
#include <stdio.h>
#include <stdlib.h>
/*---------------------*/
/* defined constants */
/* for restriction */
/*---------------------*/
#define MIN 1
#define MAX 1000000
#define IOERROR 5 // 'Input/Output Error'
/*---------------------*/
/* function prototypes */
/*---------------------*/
int main();
FILE *read_input(const char *filename_r);
int count_children(FILE *input);
int pass_heights(FILE *input, int *children, int size);
int check_tall(const int *children, int size);
void write_output(const int total,const char *filename_w);
/*---------------------*/
/* start of program */
/*---------------------*/
int main() {
const char *filename_r = "xxx.in";
const char *filename_w = "xxx.out";
FILE *input = read_input(filename_r);
int size = count_children(input);
int *children = malloc(size * sizeof *children);
if (children==NULL)
exit(1); //General application error
pass_heights(input, children, size);
fclose(input);
int total = check_tall(children, size);
free(children);
write_output(total,filename_w);
return 0;
}
FILE *read_input(const char *filename_r) {
FILE *input = fopen(filename_r, "r");
if(input == NULL)
exit(IOERROR);
return input;
}
int count_children(FILE *input) {
int count = 0;
fscanf(input, "%d",&count);
if(count > MAX || count < MIN)
exit(1); //General application error
return count;
}
int pass_heights(FILE *input, int *children, int size) {
for(int i = 0; i < size; i++)
fscanf(input, "%d",&children[i]);
return *children;
}
int check_tall(const int *children, int size) {
int total = 0;
int tmp_max = 0;
for(int i = size - 1; i >= 0; i--)
{
if(children[i] > tmp_max) {
tmp_max = children[i];
total++;
}
}
return total;
}
void write_output(const int total,const char *filename_w) {
FILE *output = fopen(filename_w, "w");
if(output == NULL)
exit(IOERROR);
fprintf(output, "%d\n", total);
fclose(output);
}
You used -static option, which modifies the way executable is linked.
I was unable to reproduce your exact error message, but on my Linux it says that it is unable to link with -lc in static mode, and under my OSX it says that it is unable to locate -lcrt0.o. For me in both case, this means that the system is unable to locate the static stub.
If you remove -static it should work. If not, your problem is very strange.
The error you show indicates the linker is not finding the main() function in your code. As it is evident that you have included it in the source file, it is also evident you are not compiling with that command line (or you are compiling in other directory where you have a non-main() source called children.c, perhaps the build system makes a touch children.c if it doesn't find the source, and then compiles it --on that case it will not have a main() routine). Check that the files are properly created and where, as I think you aren't compiling that file anyway.
Try to use simple options before you go to more complicated ones. Try something like:
gcc -std=c99 -o children children.c
before trying to experiment with optimization or static linking anyway. Also, dynamic linking is normally better than static, so you'll get smaller executables (8Kb vs. 800Kb, and multiple copies of libc loaded per executable). Also, you don't need to include -lm as you aren't using any of the <math.h> functions (having it doesn't hurt anyway).
I have compiled your source with the following command line without any problem, but I do have support for statically linked executables and perhaps you don't (the command line I have put above would work in any linux, I suppose)
$ make CC='gcc' CFLAGS='-std=c99 -O2 -DCONTEST' LDFLAGS='-s -static -lm' children
gcc -std=c99 -O2 -DCONTEST -s -static -lm children.c -o children
children.c: In function ‘pass_heights’:
children.c:81:11: warning: ignoring return value of ‘fscanf’, declared with attribute warn_unused_result [-Wunused-result]
children.c: In function ‘count_children’:
children.c:69:11: warning: ignoring return value of ‘fscanf’, declared with attribute warn_unused_result [-Wunused-result]
Suppose you created a main() to deal with an exercise you asked your students.
Every student is supposed to write their own function, with the same API. And a single file will be created, with all functions and the main calling them.
Lets say: int studentname(int a, int b) is the function pattern.
One way I deal with it was using a vector of pointer to functions int (*func[MAX])(). But you need to fulfill the vector one by one func[0]=studentname;.
I wonder, is there a way a function can be called by its name somehow?
Something like: int student1(int a , int b), student2(), etc.
And in main somehow we could just call sscanf(funcname,"student%d",i); funcname();.
Do you have any other idea? Maybe
int studentname(int a, int b, char *fname)
{
strcpy(fname, "studentname");
Anything creative will do! :)
Thanks!
Beco
PS. I tried just a vector of functions, but C won't allow me! :)
int func[2]()={{;},{;}};
This way I could just give to each student a number, and voilá... But no way. It was funny though.
Edited: I'm using linux.
Edited 2: Thanks! I've accepted an answer that helped me, but I've also documented a complete example as an answer bellow.
Maybe a bit overcomplicating it, but spontaneous idea:
Compile all student source files into one shared library with the students' functions being exports.
Then enumerate all exposed functions, call and test them.
As an alternative:
Write a small tool that will compile all "student units" using a preprocessor define to replace a predefined function name with an unique name ("func1", "func2", etc.).
Then let the tool write a small unit calling all these functions while performing tests, etc.
And yet another idea:
Use C++ to write a special class template that's going to register derived classes in a object factory and just embed student's code using extern "C". Depending on the implementation this might look a bit confusing and overcomplicated though.
Then use the factory to create one instance of each and run the code.
Example for the approach with dlopen() and dlsym() (whether only one function per library or all - doesn't matter):
void *pluginlib = dlopen("student1.so", RTLD_NOW); // RTLD_NOW will load the file right away
if (!pluginlib)
; // failed to load
studentproc func = (studentproc)dlsym(pluginlib, "student1"); // this loads the function called "student1"
if (!func)
; // failed to resolve
func("hello world!"); // call the lib
dlclose(pluginlib); // unloads the dll (this will make all further calls invalid)
Similar to what #Jamey-Sharp proposed:
ask each student to provide .c file with entry function of a given name/signature
compile each .c into a shared library, named by the student name, or given whatever unique name. This step can be easily automated with make or simple script.
make a simple host application which enumerates all .so files in a given directory, and uses dlopen() and dlsym() to get to the entry point function.
now you can simply call each student's implementation.
BTW, that's how plug-ins are implemented usually, isn't it?
Edit: Here's a working proof of concept (and a proof, that each student can use the same name of the entry point function).
Here's student1.c:
#include <stdio.h>
void student_task()
{
printf("Hello, I'm Student #1\n");
}
Here's student2.c:
#include <stdio.h>
void student_task()
{
printf("Hello, I'm Student #2\n");
}
And here's the main program, tester.c:
#include <stdio.h>
#include <dlfcn.h>
/* NOTE: Error handling intentionally skipped for brevity!
* It's not a production code!
*/
/* Type of the entry point function implemented by students */
typedef void (*entry_point_t)(void);
/* For each student we have to store... */
typedef struct student_lib_tag {
/* .. pointer to the entry point function, */
entry_point_t entry;
/* and a library handle, so we can play nice and close it eventually */
void* library_handle;
} student_solution_t;
void load(const char* lib_name, student_solution_t* solution)
{
/* Again - all error handling skipped, I only want to show the idea! */
/* Open the library. RTLD_LOCAL is quite important, it keeps the libs separated */
solution->library_handle = dlopen(lib_name, RTLD_NOW | RTLD_LOCAL);
/* Now we ask for 'student_task' function. Every student uses the same name.
* strange void** is needed for C99, see dlsym() manual.
*/
*(void**) (&solution->entry) = dlsym(solution->library_handle, "student_task");
/* We have to keep the library open */
}
int main()
{
/* Two entries hardcoded - you need some code here that would scan
* the directory for .so files, allocate array dynamically and load
* them all.
*/
student_solution_t solutions[2];
/* Load both solutions */
load("./student1.so", &solutions[0]);
load("./student2.so", &solutions[1]);
/* Now we can call them both, despite the same name of the entry point function! */
(solutions[0].entry)();
(solutions[1].entry)();
/* Eventually it's safe to close the libs */
dlclose(solutions[0].library_handle);
dlclose(solutions[1].library_handle);
return 0;
}
Let's compile it all:
czajnik#czajnik:~/test$ gcc -shared -fPIC student1.c -o student1.so -Wall
czajnik#czajnik:~/test$ gcc -shared -fPIC student2.c -o student2.so -Wall
czajnik#czajnik:~/test$ gcc tester.c -g -O0 -o tester -ldl -Wall
And see it works:
czajnik#czajnik:~/test$ ./tester
Hello, I'm Student #1
Hello, I'm Student #2
I'd take a different approach:
Require every student to use the same function name, and place each student's code in a separate source file.
Write one more source file with a main that calls the standard name.
Produce a separate executable from linking main.c with student1.c, then main.c with student2.c, and so on. You might be able to use wildcards in a makefile or shell script to automate this.
That said, at least on Unix-like OSes, you can do what you asked for.
Call dlopen(NULL) to get a handle on the symbols in the main program.
Pass that handle and the function name you want to dlsym. Coerce the resulting pointer to a function pointer of the right type, and call it.
Here is an ugly preprocessor hack:
#Makefile
FILE_NAME=student
${FILE_NAME}: main.c
cc -Wall -DFILE_NAME=\"${FILE_NAME}.c\" -o $# main.c -lm
Teacher's main.c:
#include <math.h>
#include <stdio.h>
#include FILE_NAME
char *my_name(void);
double my_sin(double val);
int main(void)
{
double dd;
dd = my_sin(3.1415923563);
printf("%s: %f\n", my_name(), dd);
return 0;
}
Student's .c File:
#include <math.h>
char * my_name(void);
double my_sin(double val);
char * my_name(void)
{
return "Wildplasser-1.0";
}
double my_sin(double val)
{
return sin (val);
}
The trick lies i the literal inclusion of the student's .c file.
To avoid this, you could also use a different make line, like:
cc -Wall -o $# ${FILE_NAME}.c main.c -lm
(and remove the ugly #include FILENAME, of course)
Thanks you all. I've accepted an answer that gave me the inspiration to solve the question. Here, just to document it, is my complete solution:
File shamain.c
/* Uses shared library shalib.so
* Compile with:
* gcc shamain.c -o shamain -ldl -Wall
*/
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main(void)
{
void *libstud;
int (*student[2])(int, int);
char fname[32];
int i,r;
libstud = dlopen("./shalib.so", RTLD_NOW);
if (!libstud)
{
fprintf(stderr, "error: %s\n", dlerror());
exit(EXIT_FAILURE);
}
dlerror(); /* Clear any existing error */
for(i=0; i<2; i++)
{
sprintf(fname, "func%d", i);
*(void **) (&student[i]) = dlsym(libstud, fname); /* c99 crap */
//student[i] = (int (*)(int, int)) dlsym(libstud, fname); /* c89 format */
}
for(i=0; i<2; i++)
{
r=student[i](i, i);
printf("i=%d,r=%d\n", i, r);
}
return 0;
}
File shalib.c
/* Shared library.
* Compile with:
* gcc -shared -fPIC shalib.c -o shalib.so -Wall
*/
#include <stdio.h>
int func0(int one, int jadv)
{
printf("%d = Smith\n", one);
return 0;
}
int func1(int one, int jadv)
{
printf("%d = John\n", one);
return 0;
}
It is a while since I have used shared libraries, but I have a feeling you can extract named functions from a DLL/shlib. Could you create a DLL/shared library containing all of the implementations and then access them by name from the main?
Per #william-morris's suggestion, you might have luck using dlsym() to do a dynamic lookup of the functions. (dlsym() may or may not be the library call to use on your particular platform.)
When loaded a shared library is opened via the function dlopen(), is there a way for it to call functions in main program?
Code of dlo.c (the lib):
#include <stdio.h>
// function is defined in main program
void callb(void);
void test(void) {
printf("here, in lib\n");
callb();
}
Compile with
gcc -shared -olibdlo.so dlo.c
Here the code of the main program (copied from dlopen manpage, and adjusted):
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
void callb(void) {
printf("here, i'm back\n");
}
int
main(int argc, char **argv)
{
void *handle;
void (*test)(void);
char *error;
handle = dlopen("libdlo.so", RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
dlerror(); /* Clear any existing error */
*(void **) (&test) = dlsym(handle, "test");
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s\n", error);
exit(EXIT_FAILURE);
}
(*test)();
dlclose(handle);
exit(EXIT_SUCCESS);
}
Build with
gcc -ldl -rdynamic main.c
Output:
[js#HOST2 dlopen]$ LD_LIBRARY_PATH=. ./a.out
here, in lib
here, i'm back
[js#HOST2 dlopen]$
The -rdynamic option puts all symbols in the dynamic symbol table (which is mapped into memory), not only the names of the used symbols. Read further about it here. Of course you can also provide function pointers (or a struct of function pointers) that define the interface between the library and your main program. It's actually the method what i would choose probably. I heard from other people that it's not so easy to do -rdynamic in windows, and it also would make for a cleaner communication between library and main program (you've got precise control on what can be called and not), but it also requires more house-keeping.
Yes, If you provide your library a pointer to that function, I'm sure the library will be able to run/execute the function in the main program.
Here is an example, haven't compiled it so beware ;)
/* in main app */
/* define your function */
int do_it( char arg1, char arg2);
int do_it( char arg1, char arg2){
/* do it! */
return 1;
}
/* some where else in main app (init maybe?) provide the pointer */
LIB_set_do_it(&do_it);
/** END MAIN CODE ***/
/* in LIBRARY */
int (*LIB_do_it_ptr)(char, char) = NULL;
void LIB_set_do_it( int (*do_it_ptr)(char, char) ){
LIB_do_it_ptr = do_it_ptr;
}
int LIB_do_it(){
char arg1, arg2;
/* do something to the args
...
... */
return LIB_do_it_ptr( arg1, arg2);
}
The dlopen() function, as discussed by #litb, is primarily provided on systems using ELF format object files. It is rather powerful and will let you control whether symbols referenced by the loaded library can be satisfied from the main program, and generally does let them be satisfied. Not all shared library loading systems are as flexible - be aware if it comes to porting your code.
The callback mechanism outlined by #hhafez works now that the kinks in that code are straightened out.