This is the mail archive of the
mailing list for the binutils project.
- From: Ian Lance Taylor <ian at airs dot com>
- To: binutils at sources dot redhat dot com
- Date: 21 Jul 2002 08:44:13 -0700
- Subject: Re: None
- References: <firstname.lastname@example.org><email@example.com>
Ian Dall <firstname.lastname@example.org> writes:
> It turns out that this is specific to a.out. I know a.out is no longer
> widely used, but still it would be good if this were fixed. In aoutx.h
> (aout_link_check_ar_symbols) there is a comment
> /* [...] If this object
> file defines a common symbol, then we may adjust the size of the
> known symbol but we do not include the object file in the link
> (unless there is some other reason to include it). */
> and yet this is later contradicted:
> /* This object file defines this symbol. We must link it
> in. This is true regardless of whether the current
> definition of the symbol is undefined or common. [...]
> FIXME: The SunOS 4.1.3 linker will pull in the archive
> element if the symbol is defined in the .data section,
> but not if it is defined in the .text section. That
> seems a bit crazy to me, and I haven't implemented it.
> However, it might be correct. */
I don't see any contradiction there, although the terminology is
ambiguous. One case refers to an object file in an archive which
defines a common symbol. The other refers to an object file in an
archive which defines a .text or .data symbol.
> I think current code is clearly wrong. It pollutes the name space for
> user programs. It causes the gcc test suite to fail in a number of
> places, but specifically gcc.c-torture/execute/960218-1.c.
I believe the current code correctly reflects the traditional
behaviour of a.out linkers.
> There are two possible strategies:
> a) never pull in archive modules to satisfy common symbols
That would be wrong, and would certainly break otherwise working
links. In particular, many traditional a.out header files define the
array of standard FILE structures, which stdin, stdout, and stderr
refer to, as a common symbol. Programs will only work correctly if
the corresponding .data definition is pulled in from an archive.
> b) never consider archive *text* symbols to satisfy common symbols.
That would match the SunOS linker, but not other traditional a.out
> Both alternatives cause a problem if anyone expects the following to
> cause an archive member to be included:
> const int a = 5; /* Assume compiler uses .text segment for this */
> this object file:
> const int a;
This case, which never arises with the SunOS compiler but does arise
with gcc, is in fact why the GNU linker behaves as it does. Changing
the linker behaviour in this manner will silently break currently
> ! Avoid including this object file to match common symbols with
> ! symbols defined in the .text segment. */
> ! if (h->type == bfd_link_hash_common && type != (N_DATA | N_EXT))
> ! continue;
If this patch is accepted, I think it would be safer to explicitly
I do understand that the current code means that you can not use a
common symbol which is defined as a text symbol in an archive.
However, if you are only using standard libraries, and if the symbol
should not be defined by the standard library, then this actually a
library bug, not a linker bug.
The GNU a.out linker does support weak symbols as an extension, so if
you have the library sources you can correct this bug by making the
symbols which not be globally visible into weak symbols. If you don't
have the library sources, then I think this is simply a platform bug.
I don't think it's appropriate to silently break working programs in
order to avoid a platform bug.