In which header file are EINVAL, ENOMEM, etc. defined in Linux? - c

It’s said that the error numbers like EINVAL, ENOMEM, etc. are defined in errno.h, but I can’t find them in errno.h, I also searched some directories under /usr/include, still can’t find them. I can use these macros without any issue in my C code. Anyone can tell me where are them?

It is defined either directly in errno.h or in a file included (directly or indirectly) by errno.h.
I searched for it using the following command:
find /usr/include | xargs grep ENOMEM | grep '#define'
and I found a match in /usr/include/asm-generic/errno-base.h in my linux (RHEL 6).

It's up to the implementation of the standard C library.
All that is certain is that <errno.h> is the top-level header that application code should use.
One way of figuring out is to trace an invocation of the compiler.

You can run locate errno.h | xargs grep EINVAL to find the location
On my Ubuntu 12.04 machine, its in /usr/lib/syslinux/com32/include/errno.h

Related

Get an exhaustive list of all the functions (other than the functions used in the .c file) in a statically GCC compiled C program

I am working on a binary analysis. For that, I need to rule out all the functions which are added to our statically compiled C program. I want only the functions which are present in the static C file. But the analysis tool reports apart from the functions present in the .c file, all other functions that are added by the compiler. Few examples are:
__open64
__pthread_enable_asynccancel
__pthread_disable_asynccancel
__stack_chk_fail
__fortify_fail
__libc_message
abort
sigprocmask
pthread_sigmask
...
These are a few functions from the huge list of function-trace from main() in the binary analysis (using the control flow graph).
I am unaware of which headers these functions belong to. Are they part of libc? I tried to open up an executable in gdb and tried to find some function names in the address range where libc is loaded. (For that I used dynamic linking and not static to explicitly check in the libc package) I could not find many of them. Is there any man-page containing an exhaustive list of all these kinds of functions? Something like the linux man page containing the list of syscalls.
Thanks in advance.
You asked about an exhaustive list. Maybe you can use glibc and gcc source code itself to discover what you need?
github is another good resource, search all of github for __pthread_enable_asynccancel and __fortify_fail, github is a very exhaustive list of identifiers.
wget http://ftp.gnu.org/gnu/glibc/glibc-2.36.tar.gz
tar xzf glibc-2.36.tar.gz
grep -r libc_hidden
. . . a very long list . . .
./glibc-2.36/nptl/cancellation.c:libc_hidden_def (__pthread_enable_asynccancel)
wget https://ftp.gnu.org/gnu/gcc/gcc-12.2.0/gcc-12.2.0.tar.xz
tar xJf gcc-12.2.0.tar.xz
grep -r __fortify_fail
. . . a lot of results . . .

What is the difference between /usr/include/linux and /usr/include/x86_64-linux-gnu/

I'm very new to native C programming and now I'm trying to configure my IDE to set up include paths correctly. Since I would like to navigate by sys/xxx.h files I added
/usr/include/x86_64-linux-gnu/
to my include path. But there is also /usr/include/linux which seems contains the same headers also. So what is the difference between them? And which one should I use actually?
I can tell you immediately that the directories /usr/include/linux and /usr/include/asm should never be included in a list of system header directories. The headers in those directories are meant to be used as #include <linux/whatever.h> or #include <asm/whatever.h>, not as #include <whatever.h>.
The rest of the answer to this question depends on exactly which "distribution" of Linux you are using, so I can't just say it. Fortunately, there is a way to get the compiler to tell you. Run this command (exactly as shown) in a terminal window:
LC_ALL=C gcc -v -xc -E /dev/null 2>&1 |
sed -ne '/search starts here/,/End of search list/p'
You will get output that looks something like this, but the details may be slightly different:
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/8/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/8/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
The directories listed are the directories you should configure your IDE to look for system headers in, for purpose of looking up declarations and whatnot. However, you should not configure your IDE to pass any of these directories to the compiler as -I directories. It already knows to use them, it doesn't need to be told again, and telling it again can mess things up (for instance, the order of the above directories matters).
As an application programmer you don't need to worry about which headers "belong" in which directories. That's entirely the compiler and C library developers and Linux distribution maintainers' task.

undefined reference to `sctp_get_no_strms'

I have a link error when trying to use sctp_get_no_strms function. I am running Slackware 14.1 and have lksctp-tools installed.
# ls /var/log/packages | grep sctp
lksctp-tools-1.0.16-x86_64-1_SBo
However libsctp symbol list does not include this function.
# nm -D /usr/lib64/libsctp.so | grep sctp_get
0000000000001100 T sctp_getaddrlen
00000000000010e0 T sctp_getladdrs
00000000000010c0 T sctp_getpaddrs
Is sctp_get_no_strms not supported by lksctp-tools?
The compilation command is as follows:
gcc -o srv sctpserv01.o sctp_wrapper.o -L../lib -lsock -lsctp
When using functions from a library, the appropriate header file needs to be #include'd — for example #include "unp.h" since the function sctp_get_no_strms() is described in Stevens Unix Network Programming, Volume 1: The Sockets API, 3rd Edn and is specific to that book.
Note that unp.h is not a standard system header, which is why I used "unp.h" rather than <unp.h> (with angle brackets around the header file name).
It turns out that function is defined in the source code available for the book. Confusingly it is not declared in the header file unp.h. It is defined in sctp/sctp_getnostrms.c.

How to check if openssl or cryptopp is installed and use the library that actually exists in the system (is installed)?

I wrote function that encrypts/decrypts a buffer (2 versions of the same function - first, with cryptopp, second - with openssl).
I would like to make something like this:
#if defined OPENSSL
run_aes_openssl(...);
#elif defined CRYPTOPP
run_aes_crytopp(...);
#else
error(...);
#end
Is it possible?
It's not quite that simple. In order to find that a macro is defined, you have to include the header that defines that macro. And C doesn't have anything like "include foo.h iff it exists"; it has to exist otherwise there is a compilation error.
Normally this would be sorted out by a script that you run before compilation. Your script checks locations like /usr/include, /usr/local/include, etc., to see if the OpenSSL headers are there; and then it outputs a Makefile which contains in the CFLAGS -DHAVE_OPENSSL. Then your code can check for that macro.
This is quite a bit of hullabaloo, to keep things simple you could require the user to manually edit a file , e.g. distribute your project with something called user_config.h that the user is supposed to edit before compiling, to specify where they put OpenSSL and so on.
There is a preset system called GNU Autoconf which contains a script that checks your system for everything under the sun. This has its advantages and disadvantages; it makes things easier for plebs downloading your source code, but it is bloaty and can be hard work for yourself.
How to check if openssl or cryptopp is installed and use the library that actually exists in the system (is installed)?
If your application was built on the system it is running, then the code you have shown is OK. Presumably, the build system will detect both OpenSSL and Crypto++. In the case both are available, it looks like your code will favor OpenSSL.
If you application is built elsewhere and needs to check at runtime, then you will need dlopen, dlsym, dlclose and friends.
In the case of runtime checking, its probably best to build a dispatch table and call through it. For example, you might have a table with function pointers to your internal run_aes_openssl, run_aes_crytopp, etc.
Upon startup, you populate the table based on the results of dlopen. If you find OpenSSL, then you populate your table with the OpenSSL gear. If you find Crypto++, then you populate your table with the Crypto++ gear.
C++ can be painful to use with dlopen and friends because of name mangling. Worse, the mangling differs between distributions and runtime library versions. For example, here's a function to generate a private RSA key:
RSA::PrivateKey key;
key.GenerateRandomWithKeySize(prng, 1024);
And here's the corresponding function names on Mac OS X. Debian and Red Hat will likely be different.
$ nm cryptopp-test.exe | grep -i GenerateRandom | grep -i RSA
00000001000c7d80 T __ZN8CryptoPP21InvertibleRSAFunction14GenerateRandomERNS_21RandomNumberGeneratorERKNS_14NameValuePairsE
00000001000c8eb0 T __ZThn120_N8CryptoPP21InvertibleRSAFunction14GenerateRandomERNS_21RandomNumberGeneratorERKNS_14NameValuePairsE

Using List.h in C files, Ubuntu10.10

I am running Ubuntu 10.10 on an IBM R51 machine. When I access list.h to read it(manually/humanly) I open /usr/src/linux-headers-2.6.35-22/include/linux .
But when coding a C program in terminal, I cant invoke any #include because it is not in the default /usr/include folders.
When I change the statement to reflect the path by typing #include "/usr/src/linux-headers-2.6.35-22/include/linux/list.h" it returns errors as list.h in turn calls other header files which are mentioned as located in "linux" folder
The header files are as you must be aware:
"linux/poison.h", "linux/prefetch.h" and "asm/system.h"
So if I have to copy each, I can but prefetch in turn calls other dependencies, which are not present in /usr/include directory. I hope you understand.
How can I solve this problem?
Are you sure these headers are really what you need ? The standard C headers should be under /usr/include
Anyhow you need to pass the header search path to the compiler via the '-I' flag.
Pass the path via -I
-I/usr/src/linux-headers-2.6.35-22/include/linux
Then in your C code
#include "list.h"
Link to GCC manual & preprocessor directives
The header files you are using are designed for internal use of the Linux kernel. They were not designed to be used by a userland program.
If you MUST use these headers (the Linux kernel list implementation is brilliant), copy the headers into your program source directory. Copy each file that is referenced, edit each one to remove whatever assumptions exist about being used in-kernel, and recurse until you're finished. I might suggest to make your own prefetch() macro that simply does nothing, rather than try to untangle <linux/prefetch.h>. Do the same for <linux/poison.h>, and untangle <linux/types> and <linux/stddef.h> (not too hard here :) as best you can.
And also be sure you license your project GPLv2 (and specifically GPLv2, the Linux kernel's COPYING file is quite strict that GPLv2 is the only license that applies; there is debate whether the GPL allows specifying only one version, but that is the license Linus chose ages ago, and the license that is valid on all files unless specified otherwise).
adding -I/usr/src/linux is a no-go, since unsanitized header files are not meant to be used from user programs
you could manually copy list.h to your own project and sanitize
or use a library that is specifically for userspace and provides the same functionality (since you already used libHX elsewhere, you might want to continue reading into the linked list chapter)

Resources