[En-Nut-Discussion] Strange newlib syscall dependencies / linker problems when using 64bit integers

5 views
Skip to first unread message

Ole Reinhardt

unread,
Feb 6, 2012, 5:19:26 PM2/6/12
to en-nut-d...@egnite.de
Hi all,

in one special situation I need to use a 64bit devision on a Cortex M3.
Compiling works fine, but the linker trows the following problems:

arm-eCross-eabi-gcc test.o -mcpu=cortex-m3 -mthumb -mlittle-endian
-D__CORTEX__ -nostartfiles
-L/home/ole/work/Streamit/NutOS_M3N/nut/arch/cm3/ldscripts
-Tlpc1778_flash.ld -Wl,-Map=uart.map,--cref,--gc-sections
-L/home/ole/work/Streamit/nut-build-lpc177x_8x/lib
-Wl,--start-group /home/ole/work/Streamit/nut-build-lpc177x_8x/lib/nutinit.o -lnutcrt -lnutarch -lnutdev -lnutos -lnutdev -lnutarch -Wl,--end-group -o uart.elf
/opt/arm-eCross-eabi/bin/../lib/gcc/arm-eCross-eabi/4.5.2/../../../../arm-eCross-eabi/lib/thumb/v7m/libc.a(lib_a-abort.o): In function `abort':
/home/ole/work/eCross/newlib-build/arm-eCross-eabi/thumb/v7m/newlib/libc/stdlib/../../../../../../../src/newlib-1.19.0/newlib/libc/stdlib/abort.c:63: undefined reference to `_exit'
/opt/arm-eCross-eabi/bin/../lib/gcc/arm-eCross-eabi/4.5.2/../../../../arm-eCross-eabi/lib/thumb/v7m/libc.a(lib_a-signalr.o): In function `_kill_r':
/home/ole/work/eCross/newlib-build/arm-eCross-eabi/thumb/v7m/newlib/libc/reent/../../../../../../../src/newlib-1.19.0/newlib/libc/reent/signalr.c:61: undefined reference to `_kill'
/opt/arm-eCross-eabi/bin/../lib/gcc/arm-eCross-eabi/4.5.2/../../../../arm-eCross-eabi/lib/thumb/v7m/libc.a(lib_a-signalr.o): In function `_getpid_r':
/home/ole/work/eCross/newlib-build/arm-eCross-eabi/thumb/v7m/newlib/libc/reent/../../../../../../../src/newlib-1.19.0/newlib/libc/reent/signalr.c:96: undefined reference to `_getpid'
/opt/arm-eCross-eabi/bin/../lib/gcc/arm-eCross-eabi/4.5.2/../../../../arm-eCross-eabi/lib/thumb/v7m/libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
/home/ole/work/eCross/newlib-build/arm-eCross-eabi/thumb/v7m/newlib/libc/reent/../../../../../../../src/newlib-1.19.0/newlib/libc/reent/sbrkr.c:60: undefined reference to `_sbrk'
collect2: ld returned 1 exit status


The program itself looks like this:

#include <inttypes.h>
int main()
{
uint64_t *a,b;
volatile uint64_t c;
a = 0xaa000aa00;

b= 0xaa00aa0000550055;

c = b/(*a);

if (c < 100) return 1;

while(1);
return 0;
}

Btw: defining a as pointer is just a trick to trick the optimizer (which
eliminates constant calculations)


Beside the above problem the linker complained about overlapping
sections .data with (implicit?) segments ARM.extab ad ARN.exidx

I fixed this by adding the requested segments (see part of the
lpc17xx_flash.ld linker script below):

.text :
{
. = ALIGN(4);
_svect = .;
KEEP(*(.isr_vector))
_evect = .;
*(.text .text.* .gnu.linkonce.t.*)
*(.rodata .rodata* .gnu.linkonce.r.*)
*(.glue_7t)
*(.glue_7)
*(.gcc_except_table)
. = ALIGN(4);
/* _etext = .;*/
} > FLASH0

/* for exception handling/unwind - some Newlib functions (in common
with C++ and STDC++) use this. */

.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH0

__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH0
__exidx_end = .;

_etext = .;

.vtable (NOLOAD):
{
. = ALIGN(4);
_vtable = .;
*(.vtable*)
. = ALIGN(4);
_evtable = .;
} > SRAM0


Does anybody has an idea of what is going wrong here?

Best regards,

Ole Reinhardt

--

Thermotemp GmbH, Embedded-IT

Embedded Hard-/ Software and Open Source Development,
Integration and Consulting

http://www.embedded-it.de

Geschäftsstelle Siegen - Steinstraße 67 - D-57072 Siegen -
tel +49 (0)271 5513597, +49 (0)271-73681 - fax +49 (0)271 736 97

Hauptsitz - Hademarscher Weg 7 - 13503 Berlin
Tel +49 (0)30 4315205 - Fax +49 (0)30 43665002
Geschäftsführer: Jörg Friedrichs, Ole Reinhardt
Handelsregister Berlin Charlottenburg HRB 45978 UstID DE 156329280

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Ulrich Prinz

unread,
Feb 7, 2012, 10:41:48 AM2/7/12
to Ethernut User Chat (English)
Hi Ole,

I never had this kind of problem, but I never used 64 bit variables...

But... I compared the local nut/os version for cortexM3 with the
sourceforge one and the only bigger difference is the double -L
parameter for the linker.
You remember the problem I have that building a simple uart example
results in 14k code instead of 6k or less in older versions?
I guess (but didn't test, cause lack of time) that this might be the problem.

Can you test again with
LDFLAGS = ...-T'path/to/linker/ldscript.ld' ... -L'path_to_libs'
instead of
LDFLAGS = ... -L'path/to/linker/' -T'ldscript.ld' ... -L'path_to_libs'

It's just a feeling...
Linker might test the first search path only and include stdlibs on
failing result even the nutos libs exist in the second one.

If it is still needed to have the linker scripts in search path, we
could reorder the parameters and test again:
LDFLAGS = ... -L'path_to_libs' ... -L'path/to/linker/' -T'ldscript.ld'

Ulrich

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Uwe Bonnes

unread,
Feb 7, 2012, 11:40:19 AM2/7/12
to Ethernut User Chat (English)
>>>>> "Ulrich" == Ulrich Prinz <ulrich...@googlemail.com> writes:

Ulrich> Hi Ole, I never had this kind of problem, but I never used 64
Ulrich> bit variables...

Ulrich> But... I compared the local nut/os version for cortexM3 with the
Ulrich> sourceforge one and the only bigger difference is the double -L
Ulrich> parameter for the linker. You remember the problem I have that
Ulrich> building a simple uart example results in 14k code instead of 6k
Ulrich> or less in older versions? I guess (but didn't test, cause lack
Ulrich> of time) that this might be the problem.

Ulrich> Can you test again with LDFLAGS =
Ulrich> ...-T'path/to/linker/ldscript.ld' ... -L'path_to_libs' instead
Ulrich> of LDFLAGS = ... -L'path/to/linker/' -T'ldscript.ld'
Ulrich> ... -L'path_to_libs'

Ulrich> It's just a feeling... Linker might test the first search path
Ulrich> only and include stdlibs on failing result even the nutos libs
Ulrich> exist in the second one.

The order doesn't seem to make a difference:
* Order as produced by our tree:

arm-none-eabi-gcc owi_test.o owi_timer.o -mcpu=cortex-m3 -mthumb -mlittle-endian -D__CORTEX__ -nostartfiles -L../../../devnut_m3n_git/nut/arch/cm3/ldscripts -Tstm32f107xC_flash.ld -Wl,-Map=owi_test.map,--cref,--gc-sections -L../.././lib -Wl,--start-group ../.././lib/nutinit.o -lnutcrt -lnutarch -lnutdev -lnutos -lnutdev -lnutarch -Wl,--end-group -o owi_test.elf
> arm-none-eabi-size owi_test.elf
text data bss dec hex filename
24296 320 1380 25996 658c owi_test.elf

* All linker specific files at the end:
> arm-none-eabi-gcc owi_test.o owi_timer.o -mcpu=cortex-m3 -mthumb -mlittle-endian -D__CORTEX__ -nostartfiles -L../.././lib ../.././lib/nutinit.o -lnutcrt -lnutarch -lnutdev -lnutos -lnutdev -lnutarch -nostartfiles -L../../../devnut_m3n_git/nut/arch/cm3/ldscripts -Tstm32f107xC_flash.ld -Wl,-Map=owi_test.map,--cref,--gc-sections -Wl,--start-group -Wl,--end-group -o owi_test.elf

> arm-none-eabi-size owi_test.elf
text data bss dec hex filename
24296 320 1380 25996 658c owi_test.elf

--
Uwe Bonnes b...@elektron.ikp.physik.tu-darmstadt.de

Institut fuer Kernphysik Schlossgartenstrasse 9 64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Ole Reinhardt

unread,
Feb 8, 2012, 7:15:10 AM2/8/12
to en-nut-d...@egnite.de
Hi!

> The order doesn't seem to make a difference:

Right. And the described problem does not depend on the linked libs (i
tried several combinations). The simple divide test program even did not
need any lib linked at all, does it?

What I found out so far is that gcc implements the division by using a
function "idiv" or similar, which itself depends on these syscalls to be
implemented.

In fact this does not rely to your problem at all. So I think we have
two disjunct problems here.

I just found another thread on microcontroller.net describing the same
problem (but on a different platform) but their solition (to implement
the newlib syscall stubs) is not really satisfying in the Nut/OS
environment...

What do you think? Where would you implement these syscall stubs (most
of these functions just return 0, only sbrk_r has to be correctly
implemented)

Bye,

Ole

Uwe Bonnes

unread,
Feb 8, 2012, 7:20:55 AM2/8/12
to Ethernut User Chat (English)
>>>>> "Ole" == Ole Reinhardt <ole.re...@embedded-it.de> writes:

...
Ole> I just found another thread on microcontroller.net describing the
Ole> same problem (but on a different platform) but their solition (to
Ole> implement the newlib syscall stubs) is not really satisfying in the
Ole> Nut/OS environment...

Can you give a link to that thread?

Thanks

Ulrich Prinz

unread,
Feb 8, 2012, 7:46:32 AM2/8/12
to Ethernut User Chat (English)
Got a part of it:

in app/Makevars.cm3-gcc the linker lines where disabled. If you add
back the line
LDFLAGS = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT)
-Wl,-Map=$(PROJ).map,--cref,--gc-sections -L$(LIBDIR)
it works without the overhead.

For latest version it must be modified to LDPATH and LDNAME.

Might be that you have to run 'Create Sampledirectory' from qnutconf
again to apply the modification to the nutconf.mk files.

Creating a local project without this modification results in a binary
image of 90k, with patch applied it is 85k.
Bootloader without patch is 14850 bytes, with patch applied it is 8252 bytes.

Ulrich

Am 7. Februar 2012 17:40 schrieb Uwe Bonnes
<b...@elektron.ikp.physik.tu-darmstadt.de>:

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Uwe Bonnes

unread,
Feb 8, 2012, 8:49:19 AM2/8/12
to Ethernut User Chat (English)
>>>>> "Ulrich" == Ulrich Prinz <ulrich...@googlemail.com> writes:

Ulrich> Got a part of it: in app/Makevars.cm3-gcc the linker lines where
Ulrich> disabled. If you add back the line LDFLAGS = $(MCFLAGS)
Ulrich> -nostartfiles -T$(LDSCRIPT)
Ulrich> -Wl,-Map=$(PROJ).map,--cref,--gc-sections -L$(LIBDIR) it works
Ulrich> without the overhead.

Ulrich> For latest version it must be modified to LDPATH and LDNAME.

Ulrich> Might be that you have to run 'Create Sampledirectory' from
Ulrich> qnutconf again to apply the modification to the nutconf.mk
Ulrich> files.

Ulrich> Creating a local project without this modification results in a
Ulrich> binary image of 90k, with patch applied it is 85k. Bootloader
Ulrich> without patch is 14850 bytes, with patch applied it is 8252
Ulrich> bytes.

Ulrich,

what exactly is missing from the command
arm-none-eabi-gcc owi_test.o owi_timer.o -mcpu=cortex-m4 -mthumb
-mlittle-endian -D__CORTEX__ -nostartfiles
-L../../../devnut_m3n_git/nut/arch/cm3/ldscripts -Tstm32f405xG_ram.ld


-Wl,-Map=owi_test.map,--cref,--gc-sections -L../.././lib -Wl,--start-group
../.././lib/nutinit.o -lnutcrt -lnutarch -lnutdev -lnutos -lnutdev -lnutarch
-Wl,--end-group -o owi_test.elf

as produced by devnut_m3n-SVN?

Bye

Ole Reinhardt

unread,
Feb 8, 2012, 9:22:32 AM2/8/12
to en-nut-d...@egnite.de
Hi Uwe,

> Can you give a link to that thread?

here it is:

http://embdev.net/topic/129607

It's the english version of microcontroller.net

Btw: It's no problem of cortex but also shows on other platforms as you
read in the thread (they use a ARM7)

bye,

Klaus Kloos

unread,
Feb 16, 2012, 1:58:59 AM2/16/12
to Ethernut User Chat (English)
Hello

Some days ago there have been problems with linking using 64bit integers and im not shure if a solution was found. I stumbled over the same problem and found the following solution for me (Ethernut 4.10, yagarto).
the following:
---
/* .ARM.exidx is sorted, so has to go in its own output section. kl for using long long*/
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} >rom
---
was added to my .ld file right after the .text segment

Somewhere i had to create the empty functions:
---
void _sbrk(void){
}

void _getpid(void){
}

void _kill(void){
}

void _exit(int status){
while(1){;}
}
---
But dont ask me why .....

This was all. It wasnt necessary for me to remove the -fno-exceptions -fno-rtti flags like some other descriptions are telling.
Now the int64 are working, i have only little doubts in what situations the _exit functions is called and freezes my prg.

Greetings Klaus


_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Ole Reinhardt

unread,
Feb 20, 2012, 3:28:57 PM2/20/12
to Ethernut User Chat (English)
Hi all,

I've been on a business trip for the last week, so sorry for the late
answer.

> Some days ago there have been problems with linking using 64bit integers and im not shure if a solution was found. I stumbled over the same problem and found the following solution for me (Ethernut 4.10, yagarto).
> the following:
> ---
> /* .ARM.exidx is sorted, so has to go in its own output section. kl for using long long*/
> .ARM.exidx : {
> __exidx_start = .;
> *(.ARM.exidx* .gnu.linkonce.armexidx.*)
> __exidx_end = .;
> } >rom
> ---
> was added to my .ld file right after the .text segment
>
> Somewhere i had to create the empty functions:
> ---
> void _sbrk(void){
> }
>
> void _getpid(void){
> }
>
> void _kill(void){
> }
>
> void _exit(int status){
> while(1){;}
> }

Yes this is the solution. I decided to go another way and to use only
32bit integers after a redesign of my algorithm.

The mentioned function stubs are the needed "syscall" stubs for Newlib.
In fact they hopefully won't ever be used. The _exit() function will
only be called in case of a "software exeption" like a division by zero.

Reply all
Reply to author
Forward
0 new messages