undefined reference to `__kmalloc' - c

While compiling code that uses the SCTP kernel header <sctp/chunk.h>I got a puzzling compiler error(with blue text instead of read) that was trigged by the calling of the kmalloc function whose prototype is defined in <linux/slob-def.h>. Here is the function that caused it:
/* Allocate and initialize datamsg. */
SCTP_STATIC struct sctp_datamsg *sctp_datamsg_new(gfp_t gfp)
{
struct sctp_datamsg *msg;
msg = kmalloc(sizeof(struct sctp_datamsg), gfp);
if (msg) {
sctp_datamsg_init(msg);
SCTP_DBG_OBJCNT_INC(datamsg);
}
return msg;
}
The gcc error message(compiling in native C):
/tmp/ccKDKVjf.o: In function `sctp_datamsg_new':
s.c:(.text+0x2215): undefined reference to `__kmalloc'
collect2: error: ld returned 1 exit status
So what I'm wondering is if the kmalloc function source code properly defined(or not actually implemented at all, or if code that calls this function can only be compiled in kernel mode. I was not actually trying to build an output file(yet), the compile command I issued in Emacs was: gcc s.c (where s.c is the .c file that contains the <sctp/chunk.h> header — just trying to make sure everything compiles properly before building an output file).

That's a linker error, the code compiled fine. Next time, specify -c to avoid linking.

If you are trying to build kernel source without including kernel headers and linking against other kernel modules and the kernel itself, you are going to get errors.
You cannot just use gcc to build kernel source code. There is a way to build them.

Related

get_peer_certificate error when using wolfSSL

I'm new to using wolfSSL. I am trying to compile a set of codes using gcc.
gcc -o main main.c -lwolfssl
I encounter an error of main.c:(.text+0x47b): undefined reference to 'wolfSSL_get_peer_certificate'
collect2: error: ld returned 1 exit status upon entering the statement.
A snippet of the code shows the error location:
fprintf(stderr, "ERROR: failed to connect to wolfSSL\n");
return -1;
}
ret = certverify(CERT_FILE,verifyCert);
WOLFSSL_X509* webCert = wolfSSL_get_peer_certificate(ssl);
I have tried modifying the WOLFSSL_X509* webCert = wolfSSL_get_peer_certificate(ssl); command but it seems to be correct.
I am not too sure why this error is occuring. Can someone please help me with this?
I am using Kali Linux 2019.4 to compile this set of codes.
#wolfSSL_new,
It sounds like the application is failing to link the library so while the right headers are in place to locate the function definitions the final step to link the function is what is failing. Where is libwolfssl.so or libwolfssl.a located on your system? Is it in /usr/local/lib/libwolfssl.so or /usr/local/lib/libwolfssl.a?
(.a is a static library, .so is a shared object library it can be either or)
Once you located where it is try this build command instead (For the sake of an example I am going to assume it is in /usr/local/lib):
gcc main.c -o main -I/usr/local/include -L/usr/local/lib -lwolfssl
Let me know if that resolves the linker error you are seeing.
[UPDATE]
This was resolved by adding the configure setting --enable-opensslextra
[END UPDATE]
Regards,
K

Compiler does not give line number of error undefined reference

Why does the compiler sometimes not give line number of the error? Where is the use case of that "undefined reference". I've already included everything as header files I myself wrote so it needs to give a specific line number. It is not closed source. Have I changed some setting of the compiler by accident or is it another thing whatever that another thing is?
D:\Projects\DanceOfPixels\GLEW>gcc main.c glad.c -IC:\mingw_dev_lib\include\SDL2 -LC:\mingw_dev_lib\lib -lmingw32 -lopengl32 -lSDL2main -lSDL2 -lSDL2_image -o main.exe -ansi -std=c89 -pedantic -w
C:\Users\user\AppData\Local\Temp\ccMooHZm.o:main.c:(.text+0x126ce): undefined reference to `drawImagePartScaledHW'
collect2.exe: error: ld returned 1 exit status
Edit: I have solved the problem. I have included two different versions of the draw.h, one coming from software renderer, other from OpenGL renderer. Since they use same
#ifndef DRAW_H
#define DRAW_H
...
#endif
structure for both files; the compiler didn't include the second. Once I've changed the DRAW_H to DRAW_HW I managed to compile and run the application.
That error comes from the "linker" (ld), not the compiler proper.
Typically, the compiler compiles each source file into its own, individual object file, containing just the code and data from that source file. Then, the linker combines one or more object files together, and also links in any needed library functions.
Crucially, there's no problem if a single source file (a single object file) calls an undefined function -- that's normal, if the definition of the function is in another source file, or a library. So that's why it's the linker (not the compiler) that finally discovers that there's not a definition for a function anywhere, that it's truly undefined.
But since the linker is working with object files, typically it doesn't know which source file line numbers the functions were originally called on.
(Some C compilers work more closely with their linkers, so that these "undefined external" error messages can, more usefully, contain actual source file line numbers, but that's a relatively recent innovation. For this to work it may be important to compile with debugging enabled, e.g. by using the -g flag, so that the compiler includes source line number information in its object files.)

MicroFocus cobol commands cobinit,cobcall and cobtidy are throwing errors in my C program

As per the documentation in Micro-focus support site, to call a cobol program from a C program we just need to follow the given below steps.
main(int argv, char *argv)
{
cobinit(); /* Initialize COBOL environment */
cobcall("cobep", 0, NULL); /* Call a COBOL program */
cobtidy(); /* Close down COBOL environment */
return(0);
}
Based on this I have come up with a simple C program to call an already working Cobol program, but guess I am getting linking error.
C Program
cat call.c
#include<stdio.h>
#include "cobcall.h"
#include "cobmain.h"
int main()
{
int ret=0;
cobinit();
ret=cobcall("cobolprogram.gnt",1,NULL);
cobtidy();
return 0;
}
Error message receiving
gcc -Wall call.c -o call
call.c: In function 'main':
call.c:10: warning: pointer targets in passing argument 1 of 'cobcall' differ in signedness
/usr/ccs/bin/ld: Unsatisfied symbols:
cobtidy (first referenced in /tmp/ccQBPw6r.o) (code)
cobcall (first referenced in /tmp/ccQBPw6r.o) (code)
cobinit (first referenced in /tmp/ccQBPw6r.o) (code)
collect2: ld returned 1 exit status
If you use MF then you likely have access to a paid support. In any case here's what I can tell you from knowing something about gcc and libraries.
The C compiler compiles fine. It only complains about signedness of a char * or const char *, but this shouldn't matter.
To solve this check in the header for the actual defintion of cobcall, I assume changing it to one of these should fix the compiler warning:
ret=cobcall((char *)"cobolprogram.gnt",1,NULL);
ret=cobcall((const char *)"cobolprogram.gnt",1,NULL);
ret=cobcall((unsigned char *)"cobolprogram.gnt",1,NULL);
ret=cobcall((const unsigned char *)"cobolprogram.gnt",1,NULL);
Side note: as far as I know you don't pass the file extension to cobcall, therefore to make it work later you may need to remove the .gnt part.
The errors you get are from the linker as it has no possibility to resolve these mf specific functions. I've skimmed over different MF docs but did not found the library name you need. Maybe it is libcob or libcobmf or libmfcob or ...
Edit: I've found a reference in an old MF manual naming the library libcobol.
As soon as you know the library name use -lname (for example -lcobol/ -lcob/ -lcobmf/-lmfcob) to let the linker know that it can resolve them in this library. Add -L/path/to/library to let the linker know where it can find the library.
If compilation worked any your main program complains about "cannot find libcob.so" (or libcobmf.so or whatever it is named) set LD_LIBRARY_PATH to point to the library name.

undefined symbol: _open_osfhandle, handle to file descriptor, linking error

In a shared library I'm trying to convert a self created handle to a file descriptor so that I can run fsync on that file descriptor. I really have two questions, the first is bellow and the second is if there is some other way to get a file descriptor from a handle.
I include "#include " to my code and then call the code bellow:
int _open_osfhandle(intptr_t oshandle, int flags);
int fd = _open_osfhandle((intptr_t)(handle), 0);
fsync(fd);
This compiles correctly but it does not work when I execute the code I get the following in the logs:
undefined symbol: _open_osfhandle
This usually means there is a linking error when creating the shared library but the correct libraries are linked while compiling the code. io.h is a part of:
rpm -qf /usr/include/sys/io.h
glibc-headers-2.17-105.el7.x86_64
Which should be the standard C library for redhat, which I Included in my ccmake build file:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libgcc -pthread")
But I still get the error that the symbol is undefined.
I've tried to work around this by attempting to create my FD with the bellow command but I believe it did not work.
int fd = (uintptr_t)(handle);
Any ideas as to why this issue is coming up.
Also is there some other way for me to get a file descriptor from my created handle?

Can I modify the dynamic linker and use without recompiling the glibc?

I am trying to modify the dynamic linker provided in the libc6(2.15-0ubuntu20.2) on a 64 bit Ubuntu machine.
So currently my code is using the same version of the glibc library. (I have downloaded the source code for the same and working on it). My question is that is it possible to modify and build only the linker source code which is present in glibc\elf\ directory without building the entire glibc library.
And if it is possible how can I make my test program to switch using the new version of dynamic linker that I have build myself instead of using the default unmodified linker.
Any pointers or suggestions are highly appreciated.
(If any more information is needed please let me know)
EDIT::
#constantius
I followed the steps in the post linked by you to build ld.so.
But I am getting following error on the make and I checked ld.so is not there in the elf.
The error is::
/var/services/homes/abhi/test/ld/eglibc-build/elf/librtld.os: In function `generic_getcwd':
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:356: undefined reference to `__closedir'
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:368: undefined reference to `__fdopendir'
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:384: undefined reference to `__readdir'
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:397: undefined reference to `rewinddir'
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:528: undefined reference to `__closedir'
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:490: undefined reference to `__closedir'
collect2: error: ld returned 1 exit status
make[2]: *** [/var/services/homes/abhi/test/ld/eglibc-build/elf/ld.so] Error 1
make[2]: Leaving directory `/var/services/homes/abhi/test/ld/eglibc-2.15/elf'
make[1]: *** [elf/subdir_lib] Error 2
make[1]: Leaving directory `/var/services/homes/abhi/test/ld/eglibc-2.15'
make: *** [all] Error 2
NOTE With the same infrastructure I can build and install the full GLIBC so I dont think there is an error with the infrastructure.
-- I guess the error is some where related to editing Makeconfig to all-subdirs = csu elf gmon io misc posix setjmp signal stdlib string time.
--Any suggestions on this..
SOLVED
Need to add dirent in the all-subdirs list in addition to what we edited before
Thanks
Citing this page. In case you don't get something, comment please — I'll try to explain.
Building
To compile Glibc (ld.so cannot be compiled independently) download and unpack Glibc source tarball.
1 Make sure the version of Glibc you downloaded is the same as the system's current one.
2 Make sure the environmental variable LD_RUN_PATH is not set.
3 Read the INSTALL and make sure all necessary tool chains (Make, Binutils, etc) are up-to-date.
4 Make sure the file system you are doing the compilation is case sensitive, or you will see weird errors like
/scratch/elf/librtld.os: In function `process_envvars':
/tmp/glibc-2.x.y/elf/rtld.c:2718: undefined reference to `__open'
...
5 ld.so should be compiled with the optimization flag on (-O2 is the default). Failing to do so will end up with weird errors (see Question 1.23 in FAQ)
6 Suppose Glibc is unpacked at
/tmp/glibc-2.x.y/
Then edit /tmp/glibc-2.x.y/Makefile.in: Un-comment the line
# PARALLELMFLAGS = -j 4
and change 4 to an appropriate number.
7 Since we are only interested in ld.so and not the whole Glibc, we only want to build the essential source files needed by ld.so. To do so, edit /tmp/glibc-2.x.y/Makeconfig: Find the line started with
all-subdirs = csu assert ctype locale intl catgets math setjmp signal \
...
and change it to
all-subdirs = csu elf gmon io misc posix setjmp signal stdlib string time
8 Find a scratch directory, say /scratch. Then
$ cd /scratch
$ /tmp/glibc-2.x.y/configure --prefix=/scratch --disable-profile
$ gmake
Since we are not building the entire Glibc, when the gmake stops (probably with some errors), check if /scratch/elf/ld.so exists or not.
ld.so is a static binary, which means it has its own implementation of standard C routines (e.g. memcpy, strcmp, etc) It has its own printf-like routine called _dl_debug_printf.
Testing
You can run the ld-linux.so directly. It will complain that this is probably not what you want (but you want exactly this) and offer you list of options with which you can run it. See also man ld-linux.so for debugging flags, i.e. there's LD_DEBUG environment variable you can define to see ld-linux.so debugging output.
While I'm not clear on whether the build system for glibc makes doing this easy, there's no fundamental reason why you can't build and use the glibc dynamic linker without building libc.so. I would peruse the top-level Makefile for ways to make this work.
As for testing it, there are two methods:
Explicitly invoke the dynamic linker to run a program, as in:
./ld-linux.so.2 a.out args ...
When linking your program, specify an alternate dynamic linker pathname (which will get stored in its PT_INTERP program header) by passing this option to the compiler driver:
-Wl,-dynamic-linker,/path/to/alternate/ld-linux.so.2

Resources