This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH: Check symbol type for symbol alias


"H.J. Lu" <hjl@lucon.org> writes:
> On Fri, Jul 20, 2007 at 02:06:31PM +0100, Richard Sandiford wrote:
>> "H.J. Lu" <hjl@lucon.org> writes:
>> > On Fri, Jul 20, 2007 at 10:12:42AM +0100, Richard Sandiford wrote:
>> >> "H.J. Lu" <hjl@lucon.org> writes:
>> >> > Here is a patch to add a testcase and check symbol type for symbol
>> >> > alias.
>> >> 
>> >> In case anyone's in any doubt, this really doesn't fix my original
>> >> problem.  Although the strong symbol in the test's shared library was
>> >> defined by the linker script, that was mostly for test convenience.
>> >> We can still have a situation in which an object symbol "bar" in a
>> >> shared library is overridden by an assignment "PROVIDE (bar = .);" in
>> >> the linker script of an object being linked against the shared library.
>> >> (And as I said in the covering note, we do handle that situation
>> >> correctly; we use relocations against the original weak symbol instead.)
>> >> I can adjust the testcase in the obvious way if this patch goes in.
>> >
>> > The problem is linker creates a wrong symbol alias for a dynamic
>> > object. We don't have a reliable way to tell if a symbol is an aliase
>> > in a shared library. It can lead to many problems. Can we use
>> > STT_SECTION for linker created symbols? Gabi says
>> >
>> > STT_SECTION
>> >     The symbol is associated with a section. Symbol table entries of
>> > this type exist primarily for relocation and normally have STB_LOCAL
>> > binding.
>> >
>> > It doesn't forbid STB_GLOBAL binding. At least, we won't make a weak
>> > symbol an alias of linker created symbols.
>> 
>> I think you're missing my point.  Please read what I said again.  You seem
>> to be talking about cases where the alias should not be considered valid
>> in isolation (i.e. by looking at the shared library and nothing else).
>> The bug I'm fixing happens _regardless of whether the alias would
>> normally be considered valid in isolation_.  Hence my comment about
>> changing my testcase.  Although the original testcase did use a linker
>> script to establish the alias, the test would still fail if that alias
>> were established in the normal environ/__environ way.
>> 
>> In my example -- where the shared library is involved in a second link
>> that redefines the strong symbol using a PROVIDE statement -- we _already_
>> correctly determine that the alias is _not_ valid, because the PROVIDEd
>> symbol overrides the shared library's symbol.  The problem is simply
>> that we have a bogus assert along the way.  (Recall that this is a
>> non-fatal assert.)  The code did not realise that a strongly-defined
>> PROVIDE symbol would actually have type bfd_link_hash_undefined
>> (rather than bfd_link_hash_defined or bfd_link_hash_defweak).
>> 
>> The bug I'm fixing is a corner case, and is simply an artifact of the
>> way PROVIDE symbols are handled.
>> 
>
> We have 2 problems:
>
> 1. Linker may create wrong symbol alias.
> 2. Linker needs to handle the case where symbol alias in a shared
> library is changed by linker created symbol.
>
> For #2, I think linker should rediret symbol alias to the linker
> created symbol. Does the linker do it correctly?

No, that's not the intended behaviour.  If a regular object (or linker
script) overrides the strong symbol, relocations against the weak symbol
are not redirected.  Quoting from elflink.c:

  /* If this is a weak definition, and we know a real definition, and
     the real symbol is not itself defined by a regular object file,
     then get a good value for the real definition.  We handle the
     real symbol first, for the convenience of the backend routine.

     Note that there is a confusing case here.  If the real definition
     is defined by a regular object file, we don't get the real symbol
     from the dynamic object, but we do get the weak symbol.  If the
     processor backend uses a COPY reloc, then if some routine in the
     dynamic object changes the real symbol, we will not see that
     change in the corresponding weak symbol.  This is the way other
     ELF linkers work as well, and seems to be a result of the shared
     library model.

     I will clarify this issue.  Most SVR4 shared libraries define the
     variable _timezone and define timezone as a weak synonym.  The
     tzset call changes _timezone.  If you write
       extern int timezone;
       int _timezone = 5;
       int main () { tzset (); printf ("%d %d\n", timezone, _timezone); }
     you might expect that, since timezone is a synonym for _timezone,
     the same number will print both times.  However, if the processor
     backend uses a COPY reloc, then actually timezone will be copied
     into your process image, and, since you define _timezone
     yourself, _timezone will not.  Thus timezone and _timezone will
     wind up at different memory locations.  The tzset call will set
     _timezone, leaving timezone unchanged.  */

This is the case I'm talking about, except that in my example,
"_timezone" is defined by a PROVIDE assignment.

Richard


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]