summaryrefslogtreecommitdiff
path: root/bfd/linker.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/linker.c')
-rw-r--r--bfd/linker.c41
1 files changed, 32 insertions, 9 deletions
diff --git a/bfd/linker.c b/bfd/linker.c
index 76bc70af09..fc52b51f00 100644
--- a/bfd/linker.c
+++ b/bfd/linker.c
@@ -223,7 +223,10 @@ SUBSUBSECTION
archive and decide which elements of the archive should be
included in the link. For each such element it must call the
<<add_archive_element>> linker callback, and it must add the
- symbols from the object file to the linker hash table.
+ symbols from the object file to the linker hash table. (The
+ callback may in fact indicate that a replacement BFD should be
+ used, in which case the symbols from that BFD should be added
+ to the linker hash table instead.)
@findex _bfd_generic_link_add_archive_symbols
In most cases the work of looking through the symbols in the
@@ -243,9 +246,13 @@ SUBSUBSECTION
element should be included in the link. If the element is to
be included, the <<add_archive_element>> linker callback
routine must be called with the element as an argument, and
- the elements symbols must be added to the linker hash table
+ the element's symbols must be added to the linker hash table
just as though the element had itself been passed to the
- <<_bfd_link_add_symbols>> function.
+ <<_bfd_link_add_symbols>> function. The <<add_archive_element>>
+ callback has the option to indicate that it would like to
+ replace the element archive with a substitute BFD, in which
+ case it is the symbols of that substitute BFD that must be
+ added to the linker hash table instead.
When the a.out <<_bfd_link_add_symbols>> function receives an
archive, it calls <<_bfd_generic_link_add_archive_symbols>>
@@ -257,7 +264,8 @@ SUBSUBSECTION
symbol) it calls the <<add_archive_element>> callback and then
<<aout_link_check_archive_element>> calls
<<aout_link_add_symbols>> to actually add the symbols to the
- linker hash table.
+ linker hash table - possibly those of a substitute BFD, if the
+ <<add_archive_element>> callback avails itself of that option.
The ECOFF back end is unusual in that it does not normally
call <<_bfd_generic_link_add_archive_symbols>>, because ECOFF
@@ -957,8 +965,10 @@ archive_hash_table_init
included. CHECKFN should set *PNEEDED to TRUE if the object file
should be included, and must also call the bfd_link_info
add_archive_element callback function and handle adding the symbols
- to the global hash table. CHECKFN should only return FALSE if some
- sort of error occurs.
+ to the global hash table. CHECKFN must notice if the callback
+ indicates a substitute BFD, and arrange to add those symbols instead
+ if it does so. CHECKFN should only return FALSE if some sort of
+ error occurs.
For some formats, such as a.out, it is possible to look through an
object file but not actually include it in the link. The
@@ -1213,11 +1223,20 @@ generic_link_check_archive_element (bfd *abfd,
{
bfd_size_type symcount;
asymbol **symbols;
+ bfd *subsbfd = NULL;
/* This object file defines this symbol, so pull it in. */
- if (! (*info->callbacks->add_archive_element) (info, abfd,
- bfd_asymbol_name (p)))
+ if (! (*info->callbacks->add_archive_element)
+ (info, abfd, bfd_asymbol_name (p), &subsbfd))
return FALSE;
+ /* Potentially, the add_archive_element hook may have set a
+ substitute BFD for us. */
+ if (subsbfd)
+ {
+ abfd = subsbfd;
+ if (!bfd_generic_link_read_symbols (abfd))
+ return FALSE;
+ }
symcount = _bfd_generic_link_get_symcount (abfd);
symbols = _bfd_generic_link_get_symbols (abfd);
if (! generic_link_add_symbol_list (abfd, info, symcount,
@@ -1238,12 +1257,16 @@ generic_link_check_archive_element (bfd *abfd,
symbfd = h->u.undef.abfd;
if (symbfd == NULL)
{
+ bfd *subsbfd = NULL;
/* This symbol was created as undefined from outside
BFD. We assume that we should link in the object
file. This is for the -u option in the linker. */
if (! (*info->callbacks->add_archive_element)
- (info, abfd, bfd_asymbol_name (p)))
+ (info, abfd, bfd_asymbol_name (p), &subsbfd))
return FALSE;
+ /* Potentially, the add_archive_element hook may have set a
+ substitute BFD for us. But no symbols are going to get
+ registered by anything we're returning to from here. */
*pneeded = TRUE;
return TRUE;
}