Linker bug: unauthorized linking (fwd)

From:

Mark Whitis

Subject:

Linker bug: unauthorized linking (fwd)

Date:

Wed, 5 Jan 2005 21:23:08 -0500 (EST)

This bug was originally found in m6811-elf-ld but has been verified to
exist in plain old (linux x86) GNU ld version 2.13.90.0.18 20030206.
gcc -Tscript.x hello.c
/usr/bin/ld: cannot open foobarbaz.o: No such file or directory
script.x:
SECTIONS
{
. = 0x10000;
.text : { foobarbaz.o(.text) *(.text) }
.data : { *(.data) }
.bss : { *(.bss) }
}
hello.c:
#include <stdlib.h>
#include <stdio.h>
main()
{
printf("hello, world\n");
}
---------- Forwarded message ----------
Date: Mon, 3 Jan 2005 23:57:17 -0500 (EST)
From: Mark Whitis <address@hidden>
Reply-To: address@hidden
To: address@hidden
Subject: Linker bug: unauthorized linking
In the linker.x linker script, I put (small excpert):
bank3C : {
emstdio.elf(.text)
foobarbaz.elf(.text)
*(bank3C.text)
*(bank3C.rodata)
} >bank3C
this causes the emstdio.elf and foobarbaz.elf files to be linked even if
they were not specfied on the command line. This is incorrect and
has serious consequences.
Nowhere (and for good reason) does the ld documentation say that
mentioning a file in the SECTIONS area will force that file to be
linked in. If you want to cause a file to be linked
in the linker script, you use the "INPUT()" directive. The foobarbaz.elf
line was added because the file does not exist and is not mentioned
anywhere else (i.e. in the makefile) and elicited the following
smoking gun:
attempt to open foobarbaz.elf failed
This bug seriously interferes with using the same linker.x file to link
different programs or different versions of the same program.
For example, I had a package emstdio that in one program was compiled
with the -Dtest option and in another without so there were two elf
files: emstdio.elf and emstdio_test.elf. Everything was fine until
I tried to move emstdio to a specfic bank instead of the default .text
bank. Then, the above lines cuased emstdio.elf to be loaded and placed
in bank3C and emstdio_test.elf to be loaded and placed in bank3E {
*(.text) }. This resulted in two copies of the same code and lots of
symbol conflicts.
Specifying a file name within the SECTIONS area means to match that file
IF AND ONLY IF it has been explicitly linked in by specifying it on
the command line or in an INPUT(directive). It is just a wildcard
pattern to match against files which have already been loaded NOT an
instruction to load a file.
Here is a contrived (for simplicity) but very real example, in shorthand
notation, of using
a single linker.x to support multiple applications:
bank30 : ( motor.elf(.text) }
bank31 : ( stdio.elf(.text) }
bank32 : ( serial.elf(.text) }
bank33 : ( lcd.elf(.text) }
bank34 : ( ethernet.elf(.text) }
bank35 : (
bread_machine.elf(.text)
dishwasher.elf(.text)
washer.elf(.text)
dryer.elf(.text)
}
bank3F : {
*(.text)
etc.
}
Here, only one of bread_machine, dishwasher, washer, or dryer would be
linked into the smart appliance application at one time. Requirint
a separate linker command file (with all the non-application specific
stuff) for every variation of a program is a maintainability nightmare.
While the example given is contrived for simplicity, in the real world
it is not uncommon to have a dozen different versions of essentially
the same program to support different products as well as various
different versions for testing. Different programs linked with
the same file should prefereably be closely related. Another example
would be similar but onlye one of ethernet.elf, canbus.elf, cebus.elf, or
rs422.elf would be linked in at a given time (or perhaps combinations).
The number of permutations of a particular program can multiply very
quickly. In the following example: only one of the two files listed
in each section would be linked in at the same time (indeed, there may
not be space for both):
bank30: {
dc_motor.elf(*.text)
ac_motor,elf(*.text)
}
bank31: {
ethernet.elf(*.text)
canbus,elf(*.text)
}
bank32: {
analog_controls.elf(*.text)
switches,elf(*.text)
}
bank33: {
battery.elf(*.text)
acline,elf(*.text)
}
bank33: {
encoder.elf(*.text)
tachometer,elf(*.text)
}
With 5 variables with 2 values each, that is 32 combinations. Having 32
linker files would be absurd. Now imagine that you had several different
rebranded products and you had to link in different company names, logos
(for LCD), etc.
The standard linker files that ship with the compiler are useless for
banked programs and can not be used, so the users linker.x file needs
to have all that functionality, making linker.x rather complex.
--
Mark Whitis http://www.freelabs.com/~whitis/ NO SPAM
Author of many open source software packages.
Coauthor: Linux Programming Unleashed (1st Edition)
To Post a message, send it to: address@hidden
To Unsubscribe, send a blank message to: address@hidden
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/gnu-m68hc11/
<*> To unsubscribe from this group, send an email to:
address@hidden
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/