This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos 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: cyg_user_start() in a library


> So the normal use of weak symbols is to allow application code to
> override library code. Remember the traditional module-based linking
> model: the library's cyg_user_start() function might be in the same
> module as several other functions which are also needed directly or
> indirectly by application code. If the application code defined
> cyg_user_start() in a .o file, and then the library module which
> contains cyg_user_start() was pulled in, you would have a duplicate
> definition problem. The use of weak symbols here avoids such problems,
> although in theory section-based linking makes it unnecessary.

... as does careful attention to what modules get placed in what .c (and
hence .o) files.  Although I am sure that there are cases where there is no
solution to this... and I am not trying to pick a religuous war here.

>
> I believe that another use of weak symbols would be to allow one
> package to override another. For example there can be a generic
> implementation of memcpy(), defined weakly, and a more efficient
> architecture-specific implementation in some HAL package.
>
> Things can get confusing when you have multiple libraries, and it
> helps to be aware of how the linking process works. Consider something
> like:
>
>     gcc -o app main.o aux.o -L<path> -Ttarget.ld -lmylib ...
>
> The linker reads in the object files main.o and aux.o and builds a
> list of unresolved symbols. These symbols needs to be resolved from
> the various libraries. Next, -Ttarget.ld causes the linker script to
> be read in and, as a side effect, causes libtarget.a to be read in.
> The linker tries to resolve all unresolved symbols from libtarget.a.
> If there remain unresolved symbols, the linker then moves on to the
> next library libmylib.a, and so on.
>
> So if both libtarget.a and libmylib.a contain definitions for
> cyg_user_start(), the former will get used. It does not matter that
> that definition is weak and the other one is strong, the linker has
> managed to resolve the symbol after processing the first library. If
> the linker tried to replace the first library's cyg_user_start() with
> the second one, things could get very messy: the first implementation
> may have pulled in additional functions which might no longer be
> required, etc.
>
> If instead the command line read:
>
>     gcc -o app main.o aux.o -L<path> -lmylib -Ttarget.ld
>
> then if I understand the ld documentation correctly libmylib.a will
> now get searched before libtarget.a, so you should get the behaviour
> you want.

Thanks for the excellent explanation.  You supplied the missing link in my
puzzle.  I am very familiar with the traditional behavior of linkers pulling
in entire .o files on the basis of a reference to any external symbol
defined in that .o file.  Now I understand that the "weak" attribute allows
finer grain control than "all or nothing".

My problem is that 'cyg_user_start()' is not referenced until libtarget.a
gets pulled in, so placing my library before libtarget.a doesn't solve the
problem.  Neither does placing it after libtarget.a, since the linker finds
the one that it (thinks it) wants in libtarget.a.

The simplest solution is to call out my .o file containing
'cyg_user_start()' directly on the command line, which is what I have done.

Thanks again for the explanation.

--wpd


-- 
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss


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