home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / gnu / djgpp / src / binutils.2 / ld / ldindr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-30  |  3.3 KB  |  125 lines

  1.  
  2. /* ldindr.c
  3.    Handle indirect symbols.
  4.  
  5.    Copyright (C) 1991 Free Software Foundation, Inc.
  6.    Written by Steve Chamberlain steve@cygnus.com
  7.  
  8.    This file is part of GLD, the Gnu Linker.
  9.  
  10.    GLD is free software; you can redistribute it and/or modify
  11.    it under the terms of the GNU General Public License as published by
  12.    the Free Software Foundation; either version 2, or (at your option)
  13.    any later version.
  14.  
  15.    GLD is distributed in the hope that it will be useful,
  16.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.    GNU General Public License for more details.
  19.  
  20.    You should have received a copy of the GNU General Public License
  21.    along with GLD; see the file COPYING.  If not, write to
  22.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  
  23.  
  24. */
  25.  
  26. /*
  27.    An indirect symbol is where a global symbol in one file say's that
  28.    all refs like it should be turned into refs of the symbol pointed
  29.    at by the value of the indirect symbol.
  30.  
  31.    BFD supplies symbols to be indirected with the BFD_INDIRECT bit
  32.    set. Whenever the linker gets one of these, it calls add_indirect
  33.    with the symbol. We look up the symbol which this one dereferneces,
  34.    and stop if they are the same. If they are not the same, copy all
  35.    the information from the current to the dereffed symbol. Set the
  36.    indirect bit in the flag. From now on the ldsym_get stuff will
  37.    perform the indirection for us, at no charge.
  38. */
  39.  
  40.  
  41.  
  42. #include "bfd.h"
  43. #include "sysdep.h"
  44. #include "ld.h"
  45. #include "ldsym.h"
  46. #include "ldmisc.h"
  47.  
  48.  
  49.  
  50. static asymbol **
  51. DEFUN(move_it,(a_list, b_list),
  52. asymbol **a_list AND
  53. asymbol **b_list)
  54. {
  55.   asymbol **head = a_list;
  56.   asymbol **cursor = head;
  57.  
  58.   if (a_list == 0) return b_list;
  59.   if (b_list == 0) return a_list;
  60.  
  61.   while (1) {
  62.     asymbol *ptr = cursor[0];
  63.     asymbol **next = (asymbol **)(ptr->udata);
  64.     if (next == 0) {
  65.       ptr->udata = (PTR) b_list;
  66.       return head;
  67.     }
  68.     cursor = next;
  69.   }
  70. }
  71.  
  72. #if 0
  73. void 
  74. DEFUN(copy_over,(ldsym, bfdsym),
  75.    ldsym_type *ldsym AND
  76.    asymbol **bfdsym)
  77. {
  78.   while (list && *list)
  79.   {
  80.     refize(Q_enter_global_ref(list, name);
  81.     list = (asymbol **)((*list)->udata);
  82.   }
  83. }
  84. #endif
  85.  
  86. /* This call allows us to change the symbol table so that all future
  87.    refs to the symbol are patched to know the alias - but we still
  88.    have to fix all the old ones */
  89. void 
  90. DEFUN(add_indirect,(ptr),
  91. asymbol **ptr)
  92. {
  93.   asymbol **p;
  94.   ldsym_type *lgs = ldsym_get((*ptr)->name);
  95.   ldsym_type *new = ldsym_get(((asymbol *)((*ptr)->value))->name);
  96.  
  97.   /* If the mapping has already been done, stop now */
  98.   if (lgs == new) return;
  99.  
  100.   lgs->flags |= SYM_INDIRECT;
  101.  
  102.   if (lgs->sdefs_chain && lgs->sdefs_chain[0]) 
  103.   {
  104.     einfo("indirect symbol already has definition %s",   lgs->sdefs_chain[0]);
  105.   }
  106.   new->scoms_chain = move_it(new->scoms_chain, lgs->scoms_chain);
  107.   lgs->scoms_chain = 0;
  108.   new->srefs_chain = move_it(new->srefs_chain, lgs->srefs_chain);
  109.   lgs->srefs_chain = 0;
  110.   new->sdefs_chain = move_it(new->sdefs_chain, lgs->sdefs_chain);
  111.   lgs->sdefs_chain = 0;
  112.  
  113.   /* If the result has any commons they should be turned into refs */
  114.  
  115.   if (new->sdefs_chain && new->scoms_chain) 
  116.   {
  117.     refize(new, new->scoms_chain);
  118.   }    
  119.   lgs->sdefs_chain = (asymbol **)new;
  120.   lgs->srefs_chain = ptr;
  121. }
  122.  
  123.  
  124.  
  125.