diff --git a/ld/ChangeLog b/ld/ChangeLog index dc721c88e4..b951cc3c3f 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,16 @@ +Wed May 6 13:26:19 1992 Steve Chamberlain (sac@thepub.cygnus.com) + + changed calling convention for Q_enter_global_ref + * ldexp.c, ldlang.c, ldmain.c: reflect this + * ldver.c: bump version to 1.97.1 + * ldindr.c (add_indirect): when an edict declaring an indirect + symbol is found, make sure that any ideas about the symbol being + common are changed if it now known to be defined. + * ldmain.c (linear_library): complain once if archive isn't + ranlibbed. + * ldlang.h, ldlang.c: make room for and initialize the complain + once field. + Wed May 6 11:07:35 1992 K. Richard Pixley (rich@rtl.cygnus.com) * Makefile.in: use flex & bison from ../ if they exist. diff --git a/ld/ldindr.c b/ld/ldindr.c index 834c6275ac..82efe33a65 100644 --- a/ld/ldindr.c +++ b/ld/ldindr.c @@ -1,6 +1,10 @@ /* ldindr.c Handle indirect symbols. + An indirect symbol is where a global symbol in one file say's that + all refs like it should be turned into refs of the symbol pointed + at by the value of the indirect symbol. + BFD supplies symbols to be indirected with the BFD_INDIRECT bit set. Whenever the linker gets one of these, it calls add_indirect with the symbol. We look up the symbol which this one dereferneces, @@ -42,17 +46,40 @@ asymbol **b_list) } } +#if 0 +void +DEFUN(copy_over,(ldsym, bfdsym), + ldsym_type *ldsym AND + asymbol **bfdsym) +{ + while (list && *list) + { + refize(Q_enter_global_ref(list, name); + list = (asymbol **)((*list)->udata); + } +} +#endif + +/* This call allows us to change the symbol table so that all future + refs to the symbol are patched to know the alias - but we still + have to fix all the old ones */ void DEFUN(add_indirect,(ptr), asymbol **ptr) { + asymbol **p; ldsym_type *lgs = ldsym_get((*ptr)->name); ldsym_type *new = ldsym_get(((asymbol *)((*ptr)->value))->name); /* If the mapping has already been done, stop now */ if (lgs == new) return; + lgs->flags |= SYM_INDIRECT; + if (lgs->sdefs_chain && lgs->sdefs_chain[0]) + { + einfo("indirect symbol already has definition %s", lgs->sdefs_chain[0]); + } new->scoms_chain = move_it(new->scoms_chain, lgs->scoms_chain); lgs->scoms_chain = 0; new->srefs_chain = move_it(new->srefs_chain, lgs->srefs_chain); @@ -60,7 +87,12 @@ asymbol **ptr) new->sdefs_chain = move_it(new->sdefs_chain, lgs->sdefs_chain); lgs->sdefs_chain = 0; - lgs->sdefs_chain = (asymbol **)new; + /* If the result has any commons they should be turned into refs */ + + if (new->sdefs_chain && new->scoms_chain) + { + refize(new, new->scoms_chain); + } } diff --git a/ld/ldsym.c b/ld/ldsym.c index a2c8449b0a..02faf351a3 100644 --- a/ld/ldsym.c +++ b/ld/ldsym.c @@ -18,17 +18,13 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* - * $Id$ - */ - /* We keep a hash table of global symbols. Each entry in a hash table is called an ldsym_type. Each has three chains; a pointer to a chain of definitions for the symbol (hopefully one long), a pointer to a chain of references to the symbol, and a pointer to a chain of common symbols. Each pointer points into the canonical symbol table - provided by bfd, each one of which points to an asymbol. Duringing + provided by bfd, each one of which points to an asymbol. During linkage, the linker uses the udata field to point to the next entry in a canonical table....