I have a strange linker problem.
My application uses the phat filesystem and therefor needs the _open,
_close and similar functions.
Everything works fine until I use the strdup() function in my sources.
If I use strdup() anywhere in my code I get the following linker errors:
arm-elf-gcc ../../xxxxxx/logout.o ../../xxxxxx/version.o ....
-mcpu=arm7tdmi -nostartfiles
-T/home/ole/work/xxxxxx/xxxxxx/ethernut-4.4.0/arch/arm/ldscripts/at91_ram.ld -Wl,-Map=xxxxxx.map,--cref,--no-warn-mismatch -L/home/ole/work/xxxxxx/xxxxxx/arm/nut-build/lib -Wl,--start-group /home/ole/work/xxxxxx/xxxxxx/arm/nut-build/lib/nutinit.o -lnutpro -lnutos -lnutarch -lnutdev -lnutnet -lnutfs -lnutcrt -lm -Wl,--end-group -o xxxxxx.elf
/opt/arm-elf/lib/gcc/arm-elf/4.1.2/../../../../arm-elf/lib/libc.a(lib_a-syscalls.o): In function `_open':
../../../../../../src/newlib-1.15.0/newlib/libc/sys/arm/syscalls.c:412:
multiple definition of `_open'
/home/ole/work/xxxxxx/xxxxxx/arm/nut-build/lib/libnutcrt.a(open.o):open.c:(.text+0x0): first defined here
/opt/arm-elf/lib/gcc/arm-elf/4.1.2/../../../../arm-elf/bin/ld: Warning:
size of symbol `_open' changed from 172
in /home/ole/work/xxxxxx/xxxxxx/arm/nut-build/lib/libnutcrt.a(open.o) to
32
in /opt/arm-elf/lib/gcc/arm-elf/4.1.2/../../../../arm-elf/lib/libc.a(lib_a-syscalls.o)
/opt/arm-elf/lib/gcc/arm-elf/4.1.2/../../../../arm-elf/lib/libc.a(lib_a-syscalls.o): In function `_close':
../../../../../../src/newlib-1.15.0/newlib/libc/sys/arm/syscalls.c:434:
multiple definition of `_close'
/home/ole/work/xxxxxx/xxxxxx/arm/nut-build/lib/libnutcrt.a(close.o):close.c:(.text+0x0): first defined here
(Sorry for obfuscating file names, but this is a project under NDA)
What in hell triggers this symbol mixup? Does NutOS uses its own strdup
function or the one from newlib? And what could be the reason to link
the lib_a-syscalls.o?
Has anybody experienced similar problems? Again: Without using strdup
everything works fine!
Btw: I'm using a self build arm-elf-gcc (GCC) 4.1.2 toolchain with
newlib-1.15.0 on my Debian/Sid Linux box.
Bye,
Ole Reinhardt
--
_____________________________________________________________
| |
| Embedded-IT Hard- und Softwarelösungen |
| |
| Ole Reinhardt Tel. / Fax: +49 (0)271 7420433 |
| Luisenstraße 29 Mobil: +49 (0)177 7420433 |
| 57076 Siegen eMail: ole.re...@embedded-it.de |
| Germany Web: http://www.embedded-it.de |
| UstID / VAT: DE198944716 |
|_____________________________________________________________|
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion
> Everything works fine until I use the strdup() function in my sources.
strdup() is not supplied by Nut/OS. Thus, it will collect the missing
routine from the newlib, which is part of your ARM toolchain. However,
more dependencies are created and finally you end up with lots of linker
errors and duplicates.
Specific solution: Add an strdup() implementation to your application code.
General solution: Always check your map file for functions supplied by
libraries which are not part of any Nut/OS library.
Harald
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion
> > Everything works fine until I use the strdup() function in my sources.
>
> strdup() is not supplied by Nut/OS. Thus, it will collect the missing
> routine from the newlib, which is part of your ARM toolchain. However,
> more dependencies are created and finally you end up with lots of linker
> errors and duplicates.
Ok. I did not dig into what is linked and what not. Strdup is supplied
in nut/c/string/strdup.c. After looking a bit deeper, it seems only to
be compiled for platforms not providing these libs.
Strange is, that all other funcions provided in nut/c/string/ are not
linked either and seem to be provided by newlib. Using them does not
trigger this problem.
> Specific solution: Add an strdup() implementation to your application code.
That's what I've done.
Thanks,
Ole
nut/c/ provides all required function in case the toolchain comes
without any runtime library. This had been the case in early times when
Nut/OS was ported to the GameBoy Advance.
Today the ARM runtime library is provided by newlib and the AVR runtime
by avrlibc. nut/c/ is not used in these cases.
Those runtime functions, which need special OS support, are located in
nut/crt, like stdio functions as well as malloc() and friends.
Unfortunately strdup() is not just a simple string function, but
requires malloc(). However, libraries like newlib do not simply
reference malloc() within strdup() but do more complex things, which in
turn create additional system specific references like syscall().
Actually strdup() should be in nut/crt, although the header string.h
refers to functions in nut/c/string. Actually the strdup() prototype
should be in memory.h, but that would break well established standards.
Harald
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion