Correct syntax errors which only appeared when relocating.
[deliverable/binutils-gdb.git] / ld / ldindr.c
1 /* ldindr.c
2 Handle indirect symbols.
3
4 An indirect symbol is where a global symbol in one file say's that
5 all refs like it should be turned into refs of the symbol pointed
6 at by the value of the indirect symbol.
7
8 BFD supplies symbols to be indirected with the BFD_INDIRECT bit
9 set. Whenever the linker gets one of these, it calls add_indirect
10 with the symbol. We look up the symbol which this one dereferneces,
11 and stop if they are the same. If they are not the same, copy all
12 the information from the current to the dereffed symbol. Set the
13 indirect bit in the flag. From now on the ldsym_get stuff will
14 perform the indirection for us, at no charge.
15 */
16
17
18
19 #include "bfd.h"
20 #include "sysdep.h"
21 #include "ld.h"
22 #include "ldsym.h"
23 #include "ldmisc.h"
24
25
26
27 static asymbol **
28 DEFUN(move_it,(a_list, b_list),
29 asymbol **a_list AND
30 asymbol **b_list)
31 {
32 asymbol **head = a_list;
33 asymbol **cursor = head;
34
35 if (a_list == 0) return b_list;
36 if (b_list == 0) return a_list;
37
38 while (1) {
39 asymbol *ptr = cursor[0];
40 asymbol **next = (asymbol **)(ptr->udata);
41 if (next == 0) {
42 ptr->udata = (PTR) b_list;
43 return head;
44 }
45 cursor = next;
46 }
47 }
48
49 #if 0
50 void
51 DEFUN(copy_over,(ldsym, bfdsym),
52 ldsym_type *ldsym AND
53 asymbol **bfdsym)
54 {
55 while (list && *list)
56 {
57 refize(Q_enter_global_ref(list, name);
58 list = (asymbol **)((*list)->udata);
59 }
60 }
61 #endif
62
63 /* This call allows us to change the symbol table so that all future
64 refs to the symbol are patched to know the alias - but we still
65 have to fix all the old ones */
66 void
67 DEFUN(add_indirect,(ptr),
68 asymbol **ptr)
69 {
70 asymbol **p;
71 ldsym_type *lgs = ldsym_get((*ptr)->name);
72 ldsym_type *new = ldsym_get(((asymbol *)((*ptr)->value))->name);
73
74 /* If the mapping has already been done, stop now */
75 if (lgs == new) return;
76
77 lgs->flags |= SYM_INDIRECT;
78
79 if (lgs->sdefs_chain && lgs->sdefs_chain[0])
80 {
81 einfo("indirect symbol already has definition %s", lgs->sdefs_chain[0]);
82 }
83 new->scoms_chain = move_it(new->scoms_chain, lgs->scoms_chain);
84 lgs->scoms_chain = 0;
85 new->srefs_chain = move_it(new->srefs_chain, lgs->srefs_chain);
86 lgs->srefs_chain = 0;
87 new->sdefs_chain = move_it(new->sdefs_chain, lgs->sdefs_chain);
88 lgs->sdefs_chain = 0;
89
90 /* If the result has any commons they should be turned into refs */
91
92 if (new->sdefs_chain && new->scoms_chain)
93 {
94 refize(new, new->scoms_chain);
95 }
96 lgs->sdefs_chain = (asymbol **)new;
97
98 }
99
100
101
This page took 0.033405 seconds and 4 git commands to generate.