]> Git Repo - binutils.git/blob - ld/ldindr.c
Initial revision
[binutils.git] / ld / ldindr.c
1 /* ldindr.c
2    Handle indirect symbols.
3
4    BFD supplies symbols to be indirected with the BFD_INDIRECT bit
5    set. Whenever the linker gets one of these, it calls add_indirect
6    with the symbol. We look up the symbol which this one dereferneces,
7    and stop if they are the same. If they are not the same, copy all
8    the information from the current to the dereffed symbol. Set the
9    indirect bit in the flag. From now on the ldsym_get stuff will
10    perform the indirection for us, at no charge.
11 */
12
13
14
15 #include "bfd.h"
16 #include "sysdep.h"
17 #include "ld.h"
18 #include "ldsym.h"
19 #include "ldmisc.h"
20
21
22
23 static asymbol **
24 DEFUN(move_it,(a_list, b_list),
25 asymbol **a_list AND
26 asymbol **b_list)
27 {
28   asymbol **head = a_list;
29   asymbol **cursor = head;
30
31   if (a_list == 0) return b_list;
32   if (b_list == 0) return a_list;
33
34   while (1) {
35     asymbol *ptr = cursor[0];
36     asymbol **next = (asymbol **)(ptr->udata);
37     if (next == 0) {
38       ptr->udata = (PTR) b_list;
39       return head;
40     }
41     cursor = next;
42   }
43 }
44
45 void 
46 DEFUN(add_indirect,(ptr),
47 asymbol **ptr)
48 {
49   ldsym_type *lgs = ldsym_get((*ptr)->name);
50   ldsym_type *new = ldsym_get(((asymbol *)((*ptr)->value))->name);
51
52   /* If the mapping has already been done, stop now */
53   if (lgs == new) return;
54   lgs->flags |= SYM_INDIRECT;
55
56   new->scoms_chain = move_it(new->scoms_chain, lgs->scoms_chain);
57   lgs->scoms_chain = 0;
58   new->srefs_chain = move_it(new->srefs_chain, lgs->srefs_chain);
59   lgs->srefs_chain = 0;
60   new->sdefs_chain = move_it(new->sdefs_chain, lgs->sdefs_chain);
61   lgs->sdefs_chain = 0;
62
63   lgs->sdefs_chain = (asymbol **)new;
64 }
65
66
67
This page took 0.026626 seconds and 4 git commands to generate.