undefined reference to `sctp_get_no_strms' - c

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.

Related

Where are avr-gcc libraries stored?

I'm trying to locate the .c files that are related to the #include header files in avr.
I want to have a look at some of the standard libraries that are defined in the avr-gcc library, particularly the PORT definitions contained in <avr/io.h>. I searched through the library in /usr/lib/avr/include/avr and found the header file, however what I am looking for is the .c file. Does this file exist? If so, where can I find it? If not, what is the header file referencing?
The compiler provided libraries are precompiled object code stored in static libraries. In gcc, libraries conventionally the extension .a (for "archive" for largely historic reasons), and the prefix "lib".
At build time, the linker will search the library archives to find the object-code modules necessary to resolve referenced to library symbols. It extracts the required modules and links them to the binary image being built.
In gcc a library libXXX.a is typically linked using the command line switch -lXXX - so the libXXX.a naming convention is important in that case. So for example the standard C library libc.a is looking linked by the switch -lc.
So to answer your question, there are normally no .c files for the compiler provided libraries provided with the toolchain. The library need not even have been written by in C.
That said, being open source, the source files (.c or otherwise) will be available from the repositories of the various libraries. For example, for the standard C library: https://www.nongnu.org/avr-libc/.
For other AVR architecture and I/O support libraries, you might inspect the associated header files or documentation. The header files will typically have a boiler-plate comment with a project URL for example.
PORTB and other special function registers are usually defined as macros in headers provided by avr-libc. Find your include/avr directory (the one that contains io.h). In that directory, there should be many other header files. As an example, iom328p.h contains the following line that defines PORTB on the ATmega328P:
#define PORTB _SFR_IO8(0x05)
If you are also looking for the libraries that are distributed as .a files, you should run avr-gcc -print-search-dirs.
There are several ways to find out where the system headers are located and which are included:
avr-gcc -v -mmcu=atmega8 foo.c ...
With option -v, GCC will print (amongst other stuff) whch include paths it is using. Check the output on a shell / console, where GCC will print the search paths:
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/avr/5.4.0/include
/usr/lib/gcc/avr/5.4.0/include-fixed
/usr/lib/gcc/avr/5.4.0/../../../avr/include
The last location is for AVR-LibC, which provides avr/io.h. Resolving the ..s, that path is just /usr/lib/avr/include. These paths depend on how avr-gcc was configured and installed, hence you have to run that command with your installation of avr-gcc.
avr-gcc -H -mmcu=atmega8 foo.c ...
Suppose the C-file foo.c reads:
#include <avr/io.h>
int main (void)
{
PORTD = 0;
}
for an easy example. With -H, GCC will print out which files it is actually including:
. /usr/lib/avr/include/avr/io.h
.. /usr/lib/avr/include/avr/sfr_defs.h
... /usr/lib/avr/include/inttypes.h
.... /usr/lib/gcc/avr/5.4.0/include/stdint.h
..... /usr/lib/avr/include/stdint.h
.. /usr/lib/avr/include/avr/iom8.h
.. /usr/lib/avr/include/avr/portpins.h
.. /usr/lib/avr/include/avr/common.h
.. /usr/lib/avr/include/avr/version.h
.. /usr/lib/avr/include/avr/fuse.h
.. /usr/lib/avr/include/avr/lock.h
avr-gcc -save-temps -g3 -mmcu=atmega8 foo.c ...
With DWARF-3 debugging info, the macro definitions will be recorded in the debug info and are visible in the pre-processed file (*.i for C code, *.ii for C++, *.s for pre-processed assembly). Hence, in foo.i we can find the definition of PORTD as
#define PORTD _SFR_IO8(0x12)
Starting from the line which contains that definition, scroll up until you find the annotation that tells in which file the macro definition happened. For example
# 45 "/usr/lib/avr/include/avr/iom8.h" 3
in the case of my toolchain installation. This means that the lines following that annotation follow line 45 of /usr/lib/avr/include/avr/iom8.h.
If you want to see the resolution of PORTD, scroll down to the end of foo.i which contains the pre-processed source:
# 3 "foo.c"
int main (void)
{
(*(volatile uint8_t *)((0x12) + 0x20)) = 0;
}
0x12 is the I/O address of PORTD, and 0x20 is the offset between I/O addresses and RAM addresses for ATmega8. This means the compiler may implement PORTD = 0 by means of out 0x12, __zero_reg__.
avr-gcc -print-file-name=libc.a -mmcu=...
Finally, this command will print the location (absolue path) of libraries like libc.a, libm.a, libgcc.a or lib<mcu>.a. The location of the library depends on how the compiler was configureed and installed, but also on command line options like -mmcu=.
avr-gcc -Wl,-Map,foo.map -mmcu=atmega8 foo.c -o foo.elf
This directs the linker to dump a "map" file foo.map where it reports which symbol will drag which module from which library. This is a text file that contains lines like:
LOAD /usr/lib/gcc/avr/5.4.0/../../../avr/lib/avr4/crtatmega8.o
...
LOAD /usr/lib/gcc/avr/5.4.0/avr4/libgcc.a
LOAD /usr/lib/gcc/avr/5.4.0/../../../avr/lib/avr4/libm.a
LOAD /usr/lib/gcc/avr/5.4.0/../../../avr/lib/avr4/libc.a
LOAD /usr/lib/gcc/avr/5.4.0/../../../avr/lib/avr4/libatmega8.a
libgcc.a is from the compiler's C runtime, and all the others are provided by AVR-LibC. Resolving the ..s, the AVR-LibC files for ATmega8 are located in /usr/lib/avr/lib/avr4/.

gcc object file linking

I'm learning C by rehashing some Project Euler problems, as I did for Python. In Python, I created a file of general mathematical utilities such as prime number checking, which I pulled functions out of as and when I needed them. I was wondering if there was a way to simply do a similar thing with C, other than compiling alongside the utilities file each time?
I'm running Linux and using gcc as my compiler, if that helps.
It looks like you need some basic knowledge about separate compilation and libraries(archives and shared libraries). You can read about it in chapter "2.3 Writing and Using Libraries" of
Advanced Linux Programming, 1st Edition by CodeSourcery LLC, Mark L. Mitchell, Alex Samuel, Jeffrey Oldham.
This book is also available as a PDF from http://www.advancedlinuxprogramming.com/ (although the site is down at the moment). Perhaps you can search for other places to legally download the PDF.
A crash course:
You create a number of object (*.o) files via
gcc name.c -o name.o
Each file has a header that declares the functions in the source file. You might have several source files using a single header if the functions are related. The source files such as name.c include that header. Your code that uses those functions also includes that header.
You create a static library (archive) with ar
ar ruv libXYZ.a name1.o name2.o ... nameN.o
The prefix lib is important.
You link to the library with
gcc prog.o -lXYZ -o prog
This command will create an executable named prog from the object file prog.o and from object files, extracted from libXYZ.a, which are required to satisfy symbol references from prog.o.

Distribution and Linking of C Header Files and Libraries

I am brand new to C programming (but not programming) and am trying to understand how libraries and header files work together, particularly with respect to packaging and distribution.
After reading this excellent question and its answer, I understand that the header file(s) act as the API to a library, exposing capabilities to the outside world; and that the library itself is the implementation of those capabilities.
However one thing that I cannot seem to find a good explanation of is: how are header files packaged into or distributed with the libraries?
Are the libs and their headers packaged into an archive (zip, tarball, etc.)?
Are headers compiled into libs and distributed alongside them?
When I do a #include "mylib.h", how does the linker know where to find:
the header file itself, mylib.h
the library implementing the functions declared in mylib.h.
how does the linker know where to find: (1) the header file itself, mylib.h
With a notation like #include <mylib.h>, it searches the header file in the system defined include PATH.
With a notation like #include "mylib.h", it searches the header file in the system defined include PATH and in the current directory.
if the header file is present in some other hierarchy, you can provide the path to get the header file with -I option with gcc.
(2) the library implementing mylib.h?
You need to provide the path to the library using -L (in case of non-standard path to the library) and link the library using -l option.
As per the convention, if the (shared) library is named libmylib.so, you can use -lmylib to link to that directory.
For example , consider the pow() function.
It is prototyped in math.h, so in your source file, you need to add #include <math.h> to get the function declaration.
Then, at compile (rather, linking) time, you need to link it with the "math" library using -lm to get the function definition.

Unable to compile a c application that reads smartcard

I am trying to compile an example c application that is using pkcs#11 to finds all
the private keys on the token, and print their label and id, but getting following errors
/tmp/ccAqQ7UI.o: In function initialize':
pkcs11_example1.c:(.text+0x8e5): undefined reference to C_Initialize'
/tmp/ccAqQ7UI.o: In function `get_slot':
The example is taken from here
compilling by using following command;
`gcc pkcs11_example1.c -o slots -L /usr/lib/opensc-pkcs11.so`
I am not sure which library i should link after -L.
Can anyone guide how to compile this and are there some libraries required to link.
C_Initialize and other 60+ functions with "C_" prefix are cryptoki functions defined in PKCS#11 specification. They are usually implemented in standalone library provided by HSM vendor. Looking at your code samples I would say that you need to directly link also PKCS#11 library or you can modify the code to dynamically load PKCS#11 library in runtime with LoadLibrary or dlopen and then acquire pointers to all cryptoki functions via the C_GetFunctionList call. You can also take a look at pkcs11-logger the source code for an example on how to do that.
The link command you give, gcc pkcs11_example1.c -o slots -L /usr/lib/opensc-pkcs11.so, is wrong.
-L takes just path, which is added to paths where libs are searched from, but /usr/lib is default so you don't need this switch at all.
You are missing -l, which takes the library name without lib prefix or .so suffix, so looks like you need -lopensc-pkcs11.
So, first make sure your library file really is /usr/lib/libopensc-pkcs11.so (note lib prefix!) possibly with verion numbers following. Then change build options so link command becomes
gcc pkcs11_example1.c -o slots -lopensc-pkcs11

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

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

Resources