Let's say I want to call a C function: printf, getpid, socketpair or any other standard C function from my code in Assembly language. I know how to do that in terms of implementation. However, I'll also have to know where one of those functions defined -- in what Linux file, so that I can pass the name of that of that file to the linker. I think it should be a "so" file. How would I find out in what file it's defined?
Note that my question is general and the functions I've mentioned above are just an example. How would I know in what Linux library any arbitrary C function defined?
These (printf, getpid, socketpair) are all part of the standard C library. That's the library that gets automatically linked to every C program.
I think the easiest way to solve your problem would be to link it with gcc, which will call the linker and link the appropriate version of the standard C library in.
If you want to proceed your way:
echo 'int main(){ }' |gcc -x c - && ldd ./a.out |grep libc
should give you the so file. In my case it's:
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc3a2b46000)
There's no generic solution for function x as far as I know.
You'd have to google to map a function to a library. If the library uses a library specific prefix instead of bare names (like the standard C library unfortunately does in most cases), googling it should be fairly unambiguous. (After that, you'd need to find where the library's SO file is on your system.)
If it's a standard C library function, libc.so is probably correct.
If it's another library, that library's documentation should tell you. Eg. the manpage for pthread_create says
Compile and link with -pthread
and you then need to look at the GCC documentation to see what it does with that option (eg, -lpthread plus some other stuff, so you want libpthread.so).
With third-party libraries, the onus is entirely on the library developer/distributor to tell you where to find the symbols listed in their API.
Worst case you can just find all .so files under /usr, /lib, /opt or wherever else you have libraries installed, and run nm -D on them. You're looking for entries of type t or T.
Note we're assuming that you only want shared objects (dynamic libraries) - if you're talking about arbitrary third-party libraries, they could equally ship static (.a) archives.
Related
I need to add headers to an already existing program by transforming it with LLVM and Clang.
I have used clang's rewriter to accomplish a similar thing in the changing function names and arguments, etc.
But the header files aren't present in clang's AST. I already know we need to use PPCallbacks (https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html) but I am in dire need of some examples on how to make it work with the rewriter if at all possible.
Alternatively, adding a #include statement just before the first
using namespace <namespace>;
Also works. I would like to know an example of this as well.
Any help would be appreciated.
There is a bit of confusion in your question. You need to understand in details how the preprocessor works. Be aware that most of C++ compilation happens after the preprocessing phase (so most C++ static analyzers work after that phase).
In other words, the C++ specification (and also the C specification) defines first what is preprocessing, and then what is the syntax and the semantics of the preprocessed form.
In other words, when compiling foo.cc your compiler see the preprocessed form foo.ii that you could obtain with clang++ -C -E foo.cc > foo.ii
In the 1980s the preprocessor /lib/cpp was a separate program forked by the compiler (and some temporary foo.ii was sitting on the disk and removed at end of compilation). Today, it is -for performance reasons- some initial processing done inside the compiler. But you could reason as if it was still separate.
Either you want to alter the Clang compiler, and it deals (like every other C++ compiler or C++ static analyzer) mostly with the preprocessed form. Then you don't want to add new #include-s, but you want to alter the flow of AST given to the compiler (after preprocessing), and that is a different question: you then want to add some AST between existing AST elements (independently of any preprocessor directives).
Or you want to automatically change the C++ source code. The hard part is determining what you want to change and at what place. I suppose that you have used complex stuff to determine that a #include <vector> has to be inserted after line 34 of file foo.cc. Once you've got that information (and getting it is the hard thing), doing the insertion is pretty trivial. For example, you could read every C++ source line, and insert your line when you have read enough lines.
We try to build tests in java from a fortran library and we would like to check COMMON variables. Is there a way to do it ?
If the symbol for it shows up in your shared library (use nm or objdump to look for it), then you can likely request its address using NativeLibrary.getGlobalVariableAddress(), then extract its value using the appropriate Pointer.getXXX() method.
I have a static library, where one of the objects defines a symbol:
nm mylib.a
...
00007340 t _a_local_symbol
...
I need to access the function from my C code. Obviously, I don't have the source code for the library, so I can work only with the archive file that I have at hand.
This is further restricted by iOS linker.
A bit more context. The library is Objective-C++, the function in question is pure C. I don't have original headers, but I've got the function signature restored.
objcopy has a flag to do what you want:
--globalize-symbol <name> Force symbol <name> to be marked as a global
Not sure whether objcopy works on iOS object files though.
I'm working on a parser that parses json string and I want to make it a library.
The problem is that when I use ld to link the library I wrote,
there's a error message:
main.o: In function `main':
main.c:(.text+0x0): multiple definition of `main'
json-parser.o:/build/buildd/flex-2.5.35/libmain.c:29: first defined here
how can I fix this..? thanks.
using gcc -o charcount charcount.o -lfl instead of gcc -o charcount -lfl charcount.o may be help.
It's strange that the order of object file and shared library make crucial sense here, but the reversion really works.
Since neither flex nor bison creates the main function for you, it must be your own main() in the code that is getting in the way of the library. Basically, do not put main() into a library.
However, it is only fair to note that both the Flex library (-lfl, /usr/lib/libfl.*) and the Yacc library (-ly, /usr/lib/liby.*) do in fact contain a rudimentary main() program. If you use either or both of those libraries, then, you must make sure your own object file with main() is linked before the libraries are scanned.
There is only one public library for binding Lua to Ada I have found (http://coreland.ath.cx/code/lua-ada), but how can it be used on a Windows platform? What do I need to use in my ada-project to get lua.ads.adb libraries defined in project-files working properly?
I tried to put lua sources in my ada-project directory befory compiling but that does nothing - GNAT raises an error like undefined reference to <c++ function>.
.
Windows doesn't seem to be on Lua-Ada's list of supported platforms. Still, the bindings ought to be somewhat portable to other Gnat platforms. You would need to get hold of a Windows Lua library (most likely a DLL) and graft the two together somehow though.
It's doable - I did something similar with Clips once. However, anyone doing this is going to need to be (or become) quite conversant with the C/C++ linker, Mingwin's support for Windows libraries (typically through DLLs), and how Ada interfaces to C linkages work.
Only by testing and testing once more I found how to bind safely Lua.
First of all is to unpack lua-ext.c from Ada-Lua package and all Lua-sources to main Ada-project directory. Then renaming lua.c to lual.c (or something equal) to eliminate error with same object-file name ('lua.ads->lua.o | lua.c->lua.o'). The last one is to turn on C-compiler in GNAT. It could be done via "Project - Edit project properties - Languages".
That's all I made to have my lua-files work with Ada-program.
P.S. To turn on all available Lua-libraries in Ada-program should be called those two procedures:
Lua.Lib.Open_Base(Lua.State_t); -- this will append to _G all main functions
Lua.Lib.Open_Libs(Lua.State_t); -- this will append math, string, package, etc. libraries