Link C against object from LLVM - c

I've been playing with LLVM more and ran into a wall trying to do this:
Assuming I have the bitcode of a project (input.bc), I can compile that to an object file (input.o) using llc.
Now if I write a separate file (funcdefs.c) that uses some symbol definitions which are in input.o, is it possible to compile funcdefs.c to its own IR representation using input.o as an include?
I've tried clang -c -emit-llvm input.o funcdefs.c but I don't see anything that looks like it's finding the missing symbol/global definitions.
Thank you for any guidance!

You need to create an object file for funcdefs.c first and then link it with input.o.
clang -c funcdefs.c -o funcdefs.o
clang funcdefs.o input.o
You can club those into
clang funcdefs.c input.o

To use functions from input.o file you need to create input.h file with definition of functions in it. To create such file see How to call the functions in another compiled *.o object files in C and How do I find out what all symbols are exported from a shared object?

Related

How to use LibFuzz on a C project that is not a library

I am trying to run libFuzz on a C project that usually compiles to an executable. The examples I found for libFuzz almost exclusively link with a library, i.e. a mylibary.a file. So I compiled the project with the normal Makefile, and combined the generated object files into a library with ar rcs a.o b.o etc.. Now I want to link this library file with the fuzzing target using clang++, but the linker is not able to find the implementation of the function I want to fuzz.
The command I use for linking inside the src directory of the project is
clang++ -Wall -fsanitize=fuzzer -Wno-cpp -Wpedantic -std=c++11 -O2 -g  -I/usr/include/libxml2 -g -O2 -rdynamic  -o fuzzing libmylib.a fuzztarget.cc -lcurl -lxml2 -I.
The error I get is "Undefined reference to function_xy()"
So the compiler finds the import of the function but not the implementation of it.
I am new to clang and generally building complex C projects so all help is greatly appreciated. Thank you!
I tried compiling the project with the included Makefile, then combining the generated object files into a .a library and finally linking the library with my fuzzing target.
The error you got is about linking, not the LibFuzzer. If you can compile and link your file without implementing function in LLVMFuzzerTestOneInput, then the fuzz-target should work: Include header in your code, call the function, compile file and link with libraries. Please check the order of include path, file, linked libraries. Be careful with the option of optimization (-O2), sometimes the fuzzer does not give crash with this option.

Calling functions from an external C file that has its own main()

I have two C files, program.c and tests.c, that each contain a main function.
program.c is a standalone program, that compiles and run normally on its own. But I would like to also be able to use some of its functions in tests.c (without using a common header file). Is there a way of doing this?
If I insert the prototype of the function I want from program.c into tests.c and compile with:
gcc -o program.o -c program.c
gcc -o tests.o -c tests.c
gcc -o tests tests.o program.o
I obtain an error duplicate symbol _main, which I understand since there are indeed two `main' functions.
I basically would like to be able to treat program.c both as a standalone program and as a library, similarly to what could be done in Python with if __name__ == '__main__'.
If you need to have two separate distinct executables for which some of the functionality between them is similar you can share the common functionality by placing relevant functions into a third file, and compiling as a portable executable, DLL in Windows. (or shared library in Linux.) Each of these file types contain sharable, executable code, ithout the main() function, designed to be linked during compile time, and dynamically loaded into your executable at runtime.
Here is a step by step set of instructions for shared library using GCC and Linux.
Here is a step by step example for creating DLL using GCC in windows.
So I managed to achieve what I wanted thanks to the comment from #pmg:
I compile program.c into a standalone binary (gcc -o program program.c), but I also compile it into an object file with "main" renamed (gcc -c -Dmain=mainp -o program.o program.c).
I can then use this object file (that does not contain a "main" symbol anymore) to compile tests.c: gcc -o tests tests.c program.o.
Thanks #pmg, I did not know this use of the -D option.

Creating dll in C from source and heading files

How can I create dll from separate source and heading files (written in C).
I have
extrfunc.h
tricclib.c
tricclib.def
tricclibql.c
And I need to create dll (using c not c++) from these components.
These files are just here:
https://drive.google.com/drive/folders/1EyvxHxiOLJqNp7sZwn0YOsOT2eRJLCL1?usp=sharing
Thank you!
That depends on what compiler you're using. Because you are calling it a DLL, I am assuming you are running Windows. When I compile on Windows I use the MinGW port of GCC. Assuming this, do the following:
Make sure you have the correct __declspec on your functions.
Compile each source file to an object file with commands like: gcc -c -o example.o example.c
Link it with something like gcc -shared -o output_dll.dll object1.o object2.o -Wl,--out-implib,libexample_dll.a

GCC compiler multiple files issues

I have a compiled C file, called Hello.o. in Hello.o:
I have a main function
and a function called int myfunc().
I wonder if I were to create a new file, hello2.c that contains a main function as well, and declare myfunc at the top of hello2.c,
will i be able to compile hello2.c and link hello.o to it using a gcc command?
Thanks all in advance.
If you want to just use myfunc() in hello2.c you can try linking the two objects files using gcc.Declare the function in a header file Hello.h and include it in hello2.c and generate Hello.o and hello2.c before linking them together by
$ gcc -o output Hello.o hello2.o
I think this should help you
How do I link object files in C? Fails with "Undefined symbols for architecture x86_64"
Object files are linked completely, or not at all. So this won't work.
GCC adds all the files specified in the command line as .o to the binary. Then the libraries (.a) are used to find needed symbols.
If there are duplicate symbols, an error is reported. (It doesn't know which main).
If a library contains more than one .o file, it can ignore the .O files which are not required. These may have duplicates with the binary.

How to link and compile with .so file in Linux

I am having .c and .so file. I tried by using the following compilation: gcc main.c -ldl. In that .c file i linked to .so file through dlsym(). How to compile using .so file with .c.
Probably you can do this:
when linking do:
g++ -o prog prog.o -ldllname
If libdllname.so is not in the system directory then add its directory to the library path:
g++ -o prog prog.o -L/path/to/my/library/folder -ldllname
This is based on your further comments. First guard the declarations of your header file.
#ifndef HEADER_PROTECT
#define HEADER_PROTECT
---------- Here is the content of header
#endif
Next, check in your code, are you defining multiple definitions. Or are you re-defining the standard functions again? Can you please post your code to guide you better?
Looks like you have re-defined Close_Comm(), can you check it? Error says that the definition is there in main.c also.
The following is the general way to compile shared object and link it.
To compile shared objects.
-g : for debug information
fPIC: for position independent code
$gcc -fPIC -g myfile
The following will create the shared object libmyfile.so
$gcc -shared -o libymyfile.so myfile.o
Now,In order to link it with your main.c.
I assume that the libmyfile.so is in your current path, thus -L./
$gcc main.c -o main.out -L./ -lmyfile
Now, you need to export the LD_LIBRARY_PATH on the bash; in order to execute the binary.
$LD_LIBRARAY_PATH=$LD_LIBRARAY_PATH:./
$./main.out
The dlsym is to load the symbol from the shared object at the run-time. If you want to load the shared object at run time, this can be used. The following is one of the example of dlsym Hack the standard function in library and call the native library function afterwards
dlsym() is used to find a symbol in an open library file.
you first need to use dlopen() in order to open the file, and only then use dlsym()

Resources