public inbox for ecos-discuss@sourceware.org
 help / color / mirror / Atom feed
* [ECOS] cyg_user_start() in a library
@ 2002-07-11 13:05 Patrick Doyle
  2002-07-29 16:22 ` Bart Veer
  0 siblings, 1 reply; 4+ messages in thread
From: Patrick Doyle @ 2002-07-11 13:05 UTC (permalink / raw)
  To: eCos

I would like to place my version of 'cyg_user_start()' in a library.  My
version calls yet another 'main()' replacement, 'mymain()' which is supplied
by the application.  The problem is, the linker finds the version of
'cyg_user_start()' in the eCos library before it finds my version of
'cyg_user_start()'.  Does anybody have any suggestions as to how I can
override the version of 'cyg_user_start()' in the eCos library with a
version in a second library?  (For the moment, I am working around this
problem by explicitly listing the filename containing my version of
'cyg_user_start()' on the linker command line, but that is a little
cumbersome).

Not knowing anything at all about the "weak" attribute supported by GCC, I
guess I would have assumed that, since the version of 'cyg_user_start()'
declared in the eCos library was given a "weak" attribute, I could override
it in another library.  Obviously, if I create my own version of
'cyg_user_start()' and specify the file containing it on the command line
for the linker, it will always override a version listed in a library,
regardless of whether the library version has a "weak" attribute or not.
So, what does the "weak" attribute do?

--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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [ECOS] cyg_user_start() in a library
  2002-07-11 13:05 [ECOS] cyg_user_start() in a library Patrick Doyle
@ 2002-07-29 16:22 ` Bart Veer
  2002-07-30  0:05   ` Andrew Lunn
  2002-07-30  8:23   ` Patrick Doyle
  0 siblings, 2 replies; 4+ messages in thread
From: Bart Veer @ 2002-07-29 16:22 UTC (permalink / raw)
  To: wpd; +Cc: ecos-discuss

>>>>> "Patrick" == Patrick Doyle <wpd@delcomsys.com> writes:

    Patrick> I would like to place my version of 'cyg_user_start()' in
    Patrick> a library. My version calls yet another 'main()'
    Patrick> replacement, 'mymain()' which is supplied by the
    Patrick> application. The problem is, the linker finds the version
    Patrick> of 'cyg_user_start()' in the eCos library before it finds
    Patrick> my version of 'cyg_user_start()'. Does anybody have any
    Patrick> suggestions as to how I can override the version of
    Patrick> 'cyg_user_start()' in the eCos library with a version in
    Patrick> a second library? (For the moment, I am working around
    Patrick> this problem by explicitly listing the filename
    Patrick> containing my version of 'cyg_user_start()' on the linker
    Patrick> command line, but that is a little cumbersome).

    Patrick> Not knowing anything at all about the "weak" attribute
    Patrick> supported by GCC, I guess I would have assumed that,
    Patrick> since the version of 'cyg_user_start()' declared in the
    Patrick> eCos library was given a "weak" attribute, I could
    Patrick> override it in another library. Obviously, if I create my
    Patrick> own version of 'cyg_user_start()' and specify the file
    Patrick> containing it on the command line for the linker, it will
    Patrick> always override a version listed in a library, regardless
    Patrick> of whether the library version has a "weak" attribute or
    Patrick> not. So, what does the "weak" attribute do?

I am not an expert on this, but from the gcc documentation:

  `weak'
     The `weak' attribute causes the declaration to be emitted as a weak
     symbol rather than a global.  This is primarily useful in defining
     library functions which can be overridden in user code, though it
     can also be used with non-function declarations.  Weak symbols are
     supported for ELF targets, and also for a.out targets when using
     the GNU assembler and linker.

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.

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.

Bart

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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [ECOS] cyg_user_start() in a library
  2002-07-29 16:22 ` Bart Veer
@ 2002-07-30  0:05   ` Andrew Lunn
  2002-07-30  8:23   ` Patrick Doyle
  1 sibling, 0 replies; 4+ messages in thread
From: Andrew Lunn @ 2002-07-30  0:05 UTC (permalink / raw)
  To: Bart Veer; +Cc: wpd, ecos-discuss

> 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.

One word of warning. gcc is allowed, and actually does sometimes,
rearrange the order of parameters passed to ld. This has caused me
problems before. To see what is actually happening, add -v to the gcc
command line so you get to see the invocation of ld.

        Andrew

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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: [ECOS] cyg_user_start() in a library
  2002-07-29 16:22 ` Bart Veer
  2002-07-30  0:05   ` Andrew Lunn
@ 2002-07-30  8:23   ` Patrick Doyle
  1 sibling, 0 replies; 4+ messages in thread
From: Patrick Doyle @ 2002-07-30  8:23 UTC (permalink / raw)
  To: bartv; +Cc: ecos-discuss

> 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

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2002-07-30 15:23 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-07-11 13:05 [ECOS] cyg_user_start() in a library Patrick Doyle
2002-07-29 16:22 ` Bart Veer
2002-07-30  0:05   ` Andrew Lunn
2002-07-30  8:23   ` Patrick Doyle

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).