(1) describe -relax
[deliverable/binutils-gdb.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.030666 seconds and 4 git commands to generate.