GCC -nostdlib fails with undefined reference to `__libc_csu_fini' - c

I provide the linker with my files: ld-2.7.so, libc-2.7.so and crt1.o but it fails to compile successfully. Is it possible to link to a different glibc from the default one ?
(Static compilation or installing a separate glibc is not an option.)
gcc -Wl,-dynamic-linker,ld-2.7.so,libc-2.7.so,crt1.o -nostdlib program.c
crt1.o: In function `_start':
(.text+0x12): undefined reference to `__libc_csu_fini'
crt1.o: In function `_start':
(.text+0x19): undefined reference to `__libc_csu_init'
/tmp/user/1000/ccauFlwt.o: In function `findsize':
program.c:(.text+0x21): undefined reference to `stat'
/tmp/user/1000/ccauFlwt.o: In function `findtime':
program.c:(.text+0x4c): undefined reference to `stat'
collect2: ld returned 1 exit status

I found out how to do it:
rpath specifies where the provided libraries are located. This folder should contain: libc.so.6, libdl.so.2, libgcc_s.so.1 and maybe more. Check with strace to find out which libraries your binary file uses.
ld.so is the provided linker
gcc -Xlinker -rpath=/default/path/to/libraries -Xlinker -I/default/path/to/libraries/ld.so program.c

As #onemasse said, you also need header files compatible with that version of libc. Between glibc versions things still work anyway though, but this can not relied upon.
Otherwise, I would suggest you use export LD_PRELOAD_PATH to wherever your other libc is before starting the new library.
But what you really is after, is to cross-compile in linux, for linux, but with another libc.
Have a look at crosstool.

If you want to link to another libc than the one provided by the system you also need to compile your program with header files compatible with that version of libc.
Also, I'm not familiar with the option "-dynamic-linker". It's not in the man page for gcc. I really can't work out what you're trying to do.
Maybe you should try this instead and work from there:
gcc -ldl program.c -o program
You normally don't have to explicitly link with "libc" or "crt1.o".

Related

MinGW GCC - undefined reference to `atexit'

I am trying to link a large project with GCC 4.8.1 from MinGW for a x86 target.
I am calling the linker like this
D:\MyGCCPath\gcc -L [LIBPATHS] -nostdlib -Wl,-Map,D:\PathToMapFile.map,--emit-relocs [OBJECTFILES AND LIBS] -lmsvcrt -lgcc -o D:\PathToMyOutputFile
With this call I get this linker rror:
libgcc.a(__main.o):(.text+0x5a): undefined reference to `atexit'
I tried different msvcr versions (100 and 90), but this was more a desperate attempt, since I am not very familiar with this problem. I am using the correct libraries provided by MinGW.
Is there any way I can fix this error?
You are linking with -nostdlib, and atexit() is a function from stdlib.h.
According to GCC Link Options:
-nostdlib
Do not use the standard system startup files or libraries when linking. No startup files and only the libraries you specify are passed to the linker, and options specifying linkage of the system libraries, such as -static-libgcc or -shared-libgcc, are ignored.
Libraries are checked in the order used on the command line so use -lgcc -lmsvcrt.

Which library shall I add to get fcntl64, stat64, ... resolved?

I'm trying to build a project for ARM uClibc environment, but I've some functions missing. Can not find which library shall I include to resolve dependancies. nm do not help me to search, since it says on most of libs coming with toolchain:
nm: ./host/usr/arm-unknown-linux-uclibcgnueabi/sysroot/lib/libuClibc-0.9.32.1.so: no symbols
Here is the output from GCC:
./host/usr/bin/arm-unknown-linux-uclibcgnueabi-gcc
-Wl,-rpath,./host/usr/lib/
-Wl,-rpath,./host/usr/../lib/
-Wl,-rpath,./host/usr/arm-unknown-linux-uclibcgnueabi/sysroot/lib/
-Llibzway -o test_so main.o -lzway
-L./host/usr/lib/
-L./host/usr/../lib/
-L./host/usr/arm-unknown-linux-uclibcgnueabi/sysroot/lib/ -lpthread
-lxml2 -lz -lm
./host/usr/lib/libxml2.so: warning: gethostbyname is obsolescent, use getnameinfo() instead.
./host/usr/lib/libxml2.so: undefined reference to `fcntl64'
./host/usr/lib/libxml2.so: undefined reference to `fopen64'
./host/usr/../lib/libz.so: undefined reference to `lseek64'
./host/usr/lib/libxml2.so: undefined reference to `stat64'
./host/usr/lib/libiconv.so.2: undefined reference to `mbrtowc'
./host/usr/lib/libiconv.so.2: undefined reference to `_stdlib_mb_cur_max'
./host/usr/lib/libiconv.so.2: undefined reference to `wcrtomb'
./host/usr/lib/libxml2.so: undefined reference to `open64'
collect2: ld returned 1 exit status
make: *** [test_so] Error 1
UPD:
I've copied uClibc from the target host and explicitely defined asked to link with it:
./host/usr/bin/arm-unknown-linux-uclibcgnueabi-gcc
-Wl,-rpath,./host/usr/lib/
-Wl,-rpath,./host/usr/../lib/
-Wl,-rpath,./host/usr/arm-unknown-linux-uclibcgnueabi/sysroot/lib/
-Llibzway -o test_so main.o -lzway
-L./host/usr/lib/
-L./host/usr/../lib/
-L./host/usr/arm-unknown-linux-uclibcgnueabi/sysroot/lib/
-luClibc-0.9.31
-lpthread -lxml2 -lz -lm
./host/usr/bin/../lib/gcc/arm-unknown-linux-uclibcgnueabi/4.5.3/../../../../arm-unknown-linux-uclibcgnueabi/bin/ld:
errno: TLS reference in ./host/usr/bin/../arm-unknown-linux-uclibcgnueabi/sysroot/lib/libpthread.so.0 mismatches non-TLS definition in ./host/usr/lib/libuClibc-0.9.31.so section .bss
./host/usr/bin/../arm-unknown-linux-uclibcgnueabi/sysroot/lib/libpthread.so.0: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [test_so] Error 1
This is much bayond my knowledge of cross-compilation. Any idea?
It sounds like you have several issues going on:
You seem to be trying to use the host's copy of libxml2.so. This is not going to work. You need one built for your target system and its libc.
Your uClibc was compiled without large file support. Go back and fix the build options or uClibc. It's not strictly necessary (a correctly built libxml2.so linked against uClibc will work without doing this), but using the pre-large-file interfaces is really backwards and will unnecessarily limit your programs.

How are newlibc stubs supposed to be included/linked into one's code

During my project's linking process the linker fails with the following errors unless I make an explicit call in my code to one of of the stub functions (i.e. _sbrk):
c:/toolchains/yagarto/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libg.a(lib_a-abort.o): In function `abort':
C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\newlib\libc\stdlib/../../../../../newlib-1.19.0/newlib/libc/stdlib/abort.c:63: undefined reference to `_exit'
c:/toolchains/yagarto/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libg.a(lib_a-signalr.o): In function `_kill_r':
C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\newlib\libc\reent/../../../../../newlib-1.19.0/newlib/libc/reent/signalr.c:61: undefined reference to `_kill'
c:/toolchains/yagarto/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libg.a(lib_a-signalr.o): In function `_getpid_r':
C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\newlib\libc\reent/../../../../../newlib-1.19.0/newlib/libc/reent/signalr.c:96: undefined reference to `_getpid'
c:/toolchains/yagarto/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libg.a(lib_a-sbrkr.o): In function `_sbrk_r':
C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\newlib\libc\reent/../../../../../newlib-1.19.0/newlib/libc/reent/sbrkr.c:60: undefined reference to `_sbrk'
collect2: ld returned 1 exit status
I am aware that I need some stubs functions that newlibc requires and I have a "C" file that contains all of the ones mentioned above as missing and I am also positive that the file is being compiled and added to an archive file (*.a) that is later linked.
I am calling the linker using the following commands
arm-none-eabi-gcc -L -T linkerscript.ld -nostartfiles -Wl,-Map,$(TARGET).map -lc archive.a
My question is simple (I hope) How can I make sure that the linker links my stub functions into the elf file without having to make an explicit function call from one of my project files?
I think those errors you're getting refer to the linker not being able to find the appropriate library. My first suspicion is in how you're using your arguments, specifically your specification of archive directory (-L) and the archive.a file. I'm thinking it should go like this:
arm-none-eabi-gcc -L. -T linkerscript.ld -nostartfiles -Wl,-Map,$(TARGET).map -lc -larchive
where the changes I'd make are:
-L. means use the current directory to look for library files to link.
-lc specifies to use the archive file libc.a.
-larchive specifies to use the archive file libarchive.a.
For more info I'd suggest checking out theGNU GCC reference.
Pass --verbose to gcc to see exactly where archive.a is showing up in the list of libraries and objects passed to the linker.
You need to arrange things so that archive.a is searched after libg.a since that's the archive that contains the objects that end up with undefined references.
You might be able to fix this by adding -lg before archive.a on the gcc command line.
-lg should in libg.a earlier than where it's getting pulled in now by default and more importantly pull it in before archive.a.

MinGW undefined reference to malloc, free, sprintf, _beginthreadex

I'm using MinGW. I have some code which calls malloc and a few other general purpose functions. When I type:
gcc TestCode.c
I get an a.exe file, it works perfect, and I don't get any warnings.
If I type this:
gcc -c TestCode.c -o TestCode.o
ld *.o
I get a whole bunch of warnings such as:
TestCode.o:TestCode.c:(.text+0xa): undefined reference to `__main'
TestCode.o:TestCode:(.text+0x2e): undefined reference to `printf'
TestCode.o:TestCode:(.text+0x42): undefined reference to `_strerror'
TestCode.o:TestCode:(.text+0x69): undefined reference to `snprintf'
TestCode.o:TestCode:(.text+0x7e): undefined reference to `malloc'
TestCode.o:TestCode:(.text+0x93): undefined reference to `_strerror'
TestCode.o:TestCode:(.text+0xb1): undefined reference to `sprintf'
TestCode.o:TestCode:(.text+0xcf): undefined reference to `free'
I'm assuming this is an issue with how I'm calling the linker. As such, I'll only post the code if it isn't clear what the problem is. I'm hoping this is an easy fix and that I simply forgot to include some super obvious library when linking.
It appears that your ld doesn't link any libraries by default. From your error messages, it looks like you need at least the C runtime and libc. Use gcc to link to get some handy defaults linked in for you:
gcc -c TestCode.c -o TestCode.o
gcc *.o
If you really want to use ld directly, you're going to need to figure out the names of your C runtime library and libc. For example (assuming libraries named libcrt and libc):
ld *.o -lcrt -lc
As Carl Norum said, you can pass object files to gcc and it'll know it doesn't need to compile them - it just passes them on to the linker (whether or not you're compiling other source files in the same invocation).
And you should probably do that because there's a fair amount of detail that goes into linking in the CRT and windows support libraries (unless you have a very specific need to not use the default runtime). My current MinGW setup links in the following items along with my object files:
crt2.o
crtbegin.o
-ladvapi32
-lshell32
-luser32
-lkernel32
-lmingw32
-lgcc
-lmoldname
-lmingwex
-lmsvcrt
crtend.o
Use the --verbose option to see how gcc links for you.

Problem in compiling C function with threading on Fedora

When I try to compile a C-program with multithreading in Fedora, I get the following error.
The file name is abc.c
abc.c:(.text+0x39): undefined reference to `pthread_create'
abc.c:(.text+0x61): undefined reference to `pthread_create'
abc.c:(.text+0x79): undefined reference to `pthread_join'
abc.c:(.text+0x8d): undefined reference to `pthread_join'
I checked in /usr/include and I found that pthread.h is present. Also I tried copying pthread.h to the same directory as abc.c
How do I resolve these linking errors?
As pointed out by George you must link with the thread library
gcc -o abc abc.c -pthread
The reason you are getting those errors is because during the linking stage the compiler tries to fill in all the slots where it had placed placeholders for method calls that it knew were defined but currently did not know their locations because the appropriate library had not been linked yet. As pointed out by caf using the -pthread flag in both compiling and linking stages allows for the compiler to make smarter choices about what it needs to use to be thread-safe in certain conditions.

Resources