bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug gold/23411] Different behavior when linking common symbol staticall


From: ccoutant at gmail dot com
Subject: [Bug gold/23411] Different behavior when linking common symbol statically or to shared object
Date: Fri, 13 Jul 2018 20:07:56 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=23411

Cary Coutant <ccoutant at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |INVALID

--- Comment #2 from Cary Coutant <ccoutant at gmail dot com> ---
For ANSI/ISO C and C++, gold is doing the right thing here.

Time for a history lesson...

In the old days of K&R C, a declaration like "int globalInt;" was considered a
"tentative definition", and was implemented using the same linker mechanism as
a Fortran common block (hence, the name "common"). Linkers in the K&R era had
the following rules with respect to linking from archive libraries:

- undef in .o, common in archive member: upgrade the undef to a common, but do
not include the archive member (unless it also provides another needed symbol
definition).

- common in .o, common in archive member: don't include the archive member.

- common in .o, regular def in archive member: include the archive member.

By those rules, yes, the linker would have included con.o from the archive, and
you'd see the value 7.

When ANSI C came along, the notion of "tentative definition" was dropped from
the language. A declaration "int globalInt;" was considered the same as "int
globalInt = 0;", with one exception -- in a nod to compatibility with existing
source code, compilers were permitted to allow multiple definitions of the old
tentative form, but were supposed to diagnose multiple definitions that did not
agree, so your static linking example (main.o + con.o) should give an error.

This required a slight change in the rules of linking:

- undef in .o, common in archive member: include the archive member.

- common in .o, common in archive member: don't include the archive member.

- common in .o, regular def in archive member: don't include the archive
member.

Gold implements these rules.

Some compilers chose to implement "int globalInt;" as a regular definition, and
kept the use of common for K&R C only. At HP, we added a new SHN_HP_ANSI_COMMON
so that we could distinguish between the two cases. Others simply continued to
generate common symbols as always (technically in violation of the language
standard).

If you change main.c to say "int globalInt = 0;", ld.bfd and gold will both
give the same results as gold does in your example, except that the static case
(main.o + con.o) will produce a multiple definition error (as it should).
According to the language standard, the results should be the same with or
without the "= 0".

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]