EmbDev.net

Forum: ARM programming with GCC/GNU tools Super weird link behaviour


von Dan Q. (danq)


Rate this post
useful
not useful
I have run into a particulary funny problem that perhaps someone else
has observed  and can comment/solve.

Given the following code segment:

----------
  test :
    {
      for (;;)
        {
          GPIO1_IOSET = 0x00010000 ;
          GPIO1_IOCLR = 0x00010000 ;
        }
    }
----------

The entire application compiles and executes correctly, generating a
square wave on the output pin.

When I comment out the 'for (;;)' statement, effectively reducing the
code to a single compound statement, the linker complains like hell that
it can't find a bunch of functions.  I am at a total loss as to why all
of a sudden these functions are needed.

Here is the edited code:

----------
  test :
    {
//    for (;;)
        {
          GPIO1_IOSET = 0x00010000 ;
          GPIO1_IOCLR = 0x00010000 ;
        }
    }
----------

Anyone got any idea of what is going on? Up until now, all my compiles
have been fine and no linker errors.  How is it possible a simple 'for
(;;)' statement omission can cause such linker behaviour?

Cheers!

Dan

Linker messages:

c:/winarm.20070505/bin/../lib/gcc/arm-elf/4.1.2/../../../../arm-elf/lib\ 
libc.a(lib_a-makebuf.o):
In function `__smakebuf_r':
makebuf.c:(.text+0x104): undefined reference to `isatty'
c:/winarm.20070505/bin/../lib/gcc/arm-elf/4.1.2/../../../../arm-elf/lib\ 
libnewlib-lpc.a(_close_r.o):
In function `_close_r':
C:\WinARM\utils\newlib_lpc_rel5a_src/_close_r.c:71: undefined reference
to `device_table'
c:/winarm.20070505/bin/../lib/gcc/arm-elf/4.1.2/../../../../arm-elf/lib\ 
libnewlib-lpc.a(_read_r.o):
In function `_read_r':
C:\WinARM\utils\newlib_lpc_rel5a_src/_read_r.c:84: undefined reference
to `device_table'
c:/winarm.20070505/bin/../lib/gcc/arm-elf/4.1.2/../../../../arm-elf/lib\ 
libnewlib-lpc.a(_write_r.o):
In function `_write_r':
C:\WinARM\utils\newlib_lpc_rel5a_src/_write_r.c:103: undefined reference
to `device_table'
c:/winarm.20070505/bin/../lib/gcc/arm-elf/4.1.2/../../../../arm-elf/lib\ 
libnewlib-lpc.a(_ioctl_r.o):
In function `_ioctl_r':
C:\WinARM\utils\newlib_lpc_rel5a_src/_ioctl_r.c:75: undefined reference
to `device_table'
collect2: ld returned 1 exit status

von Dan Q. (danq)


Rate this post
useful
not useful
Some additional info:

Examining a listing of the build shows that not only is the stdio code
being included in the binary, but string functions (strcpy,etc.) and
memset.

It is as if changing the code slightly causes either the compiler or
linker to somehow include or not-include references to these functions.

When the additional code is not linked (when it works), the binary is
only +2k.  When it links the extra code, the binary goes to +47K.
Frustrating!

Since I do not make any references to any of these functions
(strcpy,memset,fopen,etc.), I cannot figure out why these are being
linked in.

Anybody got some clues as to what is going on?

Cheers!

Dan

von Dan Q. (danq)


Rate this post
useful
not useful
Hi All,

I finally figured out what is happening with the code segment and the
external references:

When I was testing my code, I inserted this 'for (;;)' loop to do a
quick test.  The compiler recognized this as an infinite loop and
optimized out the following code.  Good compiler, good optimization.

As it turns out, the following code was some exception handling test
code "try/throw/catch", so by adding or removing the 'for (;;)' in the
test code, I was effectively removing/adding the exception handling test
code.

Finally, using exception handling requires the presence of a default
exception handler that is called when an unexpected exception is thrown.
The behavior of this function is defined and simple prints to 'stderr'
and terminates.  Hence the sudden external references.

When I remove all exception handling code and add the '-fno-exceptions'
option to the C++ compile, all external references to 'stdlib' code
disappear and the final test binary is a nice +2k in size instead of the
+47K I have be experiencing.

Now, if I remember correctly, there should be a way to override the
default unexpected exception handler so that I can point it to something
that does not use any IO. This would let me use exceptions without
incurring the huge code/ram penalty.

If anyone knows how to do that, please let me know.

Cheers!

Dan

PS: This also solves my earlier question(s) regarding a minimal compile.

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.