the including of elf.h for projects and its significance - c

I often see this file is included in many projects.
Is this mostly for Unix, Linux, MacOS applications?
and which c files would use this elf.h file?

elf.h is used for parsing and processing ELF files. You'll probably never see this on Windows because Windows does not use ELF files (it uses PE - Portable Executable - instead). OS X uses Mach-O, so elf.h isn't that common on OS X either (it doesn't ship as part of the default headers, for example). ELF format is primarily seen on Linux, where it is used for almost all binary executable files, from shared objects to executables.

Related

How to check if a object code is 16/32 bit?

Is there any way by which we can identify that a .obj file and .exe file is 16/32 bit?
Basically I want to create a smart linker, that will automatically identify which linker do the given file names need to be passed to.
Preferred Language: C (it can be different, if needed)
I am looking for some solution that can read the bytes of an .exe/the code of an .obj file and then determine if it's 16/32 bit. Even an algorithm would too do.
Note: I know both object code and a executable are two different entities.
All of this information is encoded in the binary object according to the relevant Application Binary Interface (ABI).
The current Linux ABI is the Executable and Linkable Format (ELF), and you can query a specific binary file using a tool such as readelf or objdump.
The current Windows ABI is the Portable Executable (PE) format. I'm not familiar with the toolset here but a quick google search suggests there are programs that function the same as readelf:
http://www.pe-explorer.com/peexplorer-tour.htm
Here's the Microsoft specification of the PE format:
https://learn.microsoft.com/en-us/windows/win32/debug/pe-format
However, neither of those formats support 16-bit binaries anymore. The older ABI format is called "a.out" for Linux, which can be read and queried with objdump (I'm not sure about readelf). The older Windows/DOS formats are called MZ and NE. Again, I'm not familiar with the tool support for these older Windows formats.
Wikipedia has a pretty comprehensive list of all the popular executable file formats that have been used, with links to more info:
https://en.wikipedia.org/wiki/Comparison_of_executable_file_formats

Can a Static library (.a) compiled in mac OS work in linux?

Can a static library (.a) compiled in Mac OS work in Linux? Do archives in Mac OS and Linux have the same format?
Can a static library (.a) compiled in Mac OS work in Linux?
Yes, but only if you use cross-compiler to compile object files that you'll put into that library.
Do archives in Mac OS and Linux have the same format?
It is very likely that the format of .a archive files is the same between Linux and Mac OSX (I have not verified this, but most UNIX systems use the format referenced above), but that isn't going to help you: the archive library is little more than a concatenation of .o files with some indices, and .o files themselves are different between Linux (ELF object file format) and Mac OSX (Mach-O object file format).
The Linux linker will have no trouble looking inside the .a, but it will ignore any non-ELF files it finds there.
Which Linux? Linux is compiled for many CPU architectures. Macs are currently x86-only.
As others mentioned, Macs use the Mach-O executable format, while Linuxes usually use ELF, and the way syscalls are handled and which libraries are available are completely different.
So in practice, on out-of-the-box systems, there may be similarities, but it's unlikely anything will run.
Question is: What are you trying to do?
There are ways (like http://www.darlinghq.org) to make executables from one platform run on the other, by adding code that performs an on-the-fly translation and implementing the missing libraries.
There may also be a way to create a .a file that contains executables for several platforms, so compilers will pick the right one and ignore the other. If you used a cross-compiler, you could probably build a .a on a Mac that contains code compiled for a Linux.

histogram function in ansi C program: GSL and/or others?

If I just want to use the gsl_histogram.h library from Gnu Scientific Library (GSL), can I copy it from an existing machine (Mac OS Snow Leopard) that has GSL installed to a different machine (Linux CentOS 5.7) that doesn't have GSL installed, and just use an #include <gls_histogram.h> statement in my c program? Would this work?
Or, do I have to go through the full install of GSL on the Linux box, even though I only need this one library?
Just copying a header gsl_histogram.h is not enough. Header states merely the interface that is exposed by this library. You would need to copy also binaries like *.so and *.a files, but it's hard to tell which ones to copy. So I think the you'd better just install it on your machine. It's pretty easy, just use this tutorial to find and install GSL package.
So there are surely a lot of libraries out there. However the particular one is Gnuplot. Using it you even do not need to compile the code, however you do need to read a bit of documentation. But luckily there is already a question about how to draw a histogram with Gnuplot on Stackoverflow: Histogram using gnuplot? It worth noting that Gnuplot is actually very powerful tool, so invested time into reading its documentation will certainly pay off.
You cannot copy libraries from OS and expect them to work unchanged.
OS X uses the Mach-O object file format while modern Linux systems use the ELF object file format. The usual ld.so(8) linker/loader will not know how to load the Mach-O format object files for your executable to execute. So you would need the Apple-provided ld.so(8) -- or whatever they call their loader. (It's been a while.)
Furthermore, the object files from OS X will be linked against the Apple-supplied libc, and require the corresponding symbols from the Apple-supplied library. You would also need to provide the Apple-provided libc on the Linux system. This C library would try to make system calls using the OS X system call numbers and calling conventions. I guarantee the system call numbers have changed and almost certainly calling conventions are different.
While the Linux kernel's binfmt_misc generic object loader can be used to teach the kernel how to load different object file formats, and the kernel's personality(2) system call can be used to select between different calling conventions, system call numbers, and so on, the amount of work required to make this work is nothing short of immense: the WINE Project has been working on exactly this issue (but with the Windows format COFF and supporting libraries) since 1993.
It would be easier to run:
apt-get install libgs0-dev
or whatever the equivalent is on your distribution of choice. If your distribution does not make it easily available, it would still be easier to compile and install the library by hand rather than try to make the OS X version work.

Find a directory in shared library search path

I want dlopen() every shared library in a specific directory. In order to do that,
what is the cleanest way to retrieve linux's library search path. Or Is there a quicker way of find a specific directory in that path ?
posix would be better.
POSIX does not support a mechanism to find out the directories on the shared library search path (it does not mandate LD_LIBRARY_PATH, for example), so any solution is inherently somewhat platform specific.
Linux presents some problems because the values to be used could be based on the contents of /etc/ld.so.conf as well as any runtime value in LD_LIBRARY_PATH environment variable; other systems present comparable problems. The default locations also vary by system - with /lib and /usr/lib being usual for 32-bit Linux machines but /lib64 and /usr/lib64 being used on at least some 64-bit machines. However, other platforms use other locations for 64-bit software. For example, Solaris uses /lib/sparcv9 and /usr/lib/sparcv9, for example (though the docs mention /lib/64 and /usr/lib/64, they're symlinks to the sparcv9 directories). Solaris also has environment variables LD_LIBRARY_PATH_64 and LD_LIBRARY_PATH_32. HP-UX and AIX traditionally use other variables than LD_LIBRARY_PATH -- SHLIB_PATH and LIBPATH, IIRC -- though I believe AIX now uses LD_LIBRARY_PATH too. And, on Solaris, the tool for configuring shared libraries is 'crle' (configure runtime linking environment) and the analog of /etc/ld.so.conf is either /var/ld/ld.config or /var/ld/64/ld.config. Also, of course, the extensions on shared libraries varies (.so, .sl, .dylib, .bundle, etc).
So, your solution will be platform-specific. You will need to decide on the the default locations, the environment variables to read, and the configuration file to read, and the relevant file extension. Given those, then it is mainly a SMOP - Simple Matter Of Programming:
For each directory named by any of the sources:
Open the relevant sub-directory (opendir())
Read each file name (readdir()) in turn
Use dlopen() on the path of the relevant files.
Do whatever analysis is relevant to you.
Use dlclose()
Use closedir()
See also the notes in the comment below...the complete topic is modestly fraught with variations from platform to platform.
I'm not sure it's possible to do that and be portable. Since this question is about Linux, portability may not be of paramount importance. Then I do not understand the POSIX constraint. Could you clarify?
You'll probably have to either implement the search functionality detailed in man 8 ld.so, which includes scanning /etc/ld.so.conf in addition to LD_LIBRARY_PATH, or make /lib/ld.so do what you want for you and parse the output. A not-exactly-pretty command line for that could be:
export LD_PRELOAD=THISLIBRARYSODOESNOTEXIST
strace -s 4096 /bin/true 2>&1 | sed -n 's/^open("\([^"]*\)\/THISLIBRARYSODOESNOTEXIST".*$/\1\/YOURSUBDIRHERE/gp'
unset LD_PRELOAD
You can then enumerate files with the POSIX calls opendir(3) and readdir(3).

Is a C .lib file platform specific?

I'm trying to use an API for a proprietary interface device on an embedded system (Freescale HCS08), and the provided files include headers (.h) and libraries (.lib). The header compiles fine with the rest of my code (standard C), but when trying to link against the library I get memory errors saying the file might be corrupted.
My understanding of libraries in C is somewhat limited as I work almost exclusively on embedded systems where magic things like stdio, files, and dlls don't exist; but would the (or any) library be platform specific? Does it contain fully (if there is any sort of level there) compiled code? Some of the other files provided are VS project files, so if it is the case that the .lib is platform-specific, it wouldn't be unexpected that linking a file meant for x86-Windows to an 8-bit compiler would fail; it could be just me.
Not only is a .lib file CPU specific (there would be no way to link HCS08 code to x86 code), it is toolchain specific (CodeWarrior won't talk to SDCC, GCC/binutils won't talk to Visual Studio).
Yes the .lib contains compiled code so it is platform-specific. If you have the source you should be able to re-compile it to your platform.

Resources