Made many changes to eliminate gcc warnings. Made various
[deliverable/binutils-gdb.git] / ld / ldctor.c
1 /* Copyright (C) 1991 Free Software Foundation, Inc.
2
3 This file is part of GLD, the Gnu Linker.
4
5 GLD is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 1, or (at your option)
8 any later version.
9
10 GLD is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GLD; see the file COPYING. If not, write to
17 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
18
19 /*
20 * By steve chamberlain
21 * steve@cygnus.com
22 */
23
24 #include "bfd.h"
25 #include "sysdep.h"
26 #include "ld.h"
27 #include "ldexp.h"
28 #include "ldlang.h"
29 #include "ldsym.h"
30 #include "ldmisc.h"
31 #include "ldgram.h"
32
33 /* exported list of statements needed to handle constructors */
34 lang_statement_list_type constructor_list;
35
36
37
38 typedef struct constructor_list
39 {
40 CONST char *name;
41 struct constructor_list *next;
42 } constructor_list_type;
43
44 static constructor_list_type *constructor_name_list;
45
46 static void
47 add_constructor_name (name)
48 CONST char *name;
49 {
50 register constructor_list_type *ptr = constructor_name_list;
51 for (; ptr != (constructor_list_type *)NULL; ptr = ptr->next) {
52 if (strcmp (ptr->name, name) == 0)
53 return;
54 }
55
56 /* There isn't an entry, so add one */
57 ptr = (constructor_list_type *) ldmalloc (sizeof(constructor_list_type));
58 ptr->next = constructor_name_list;
59 ptr->name = name;
60 constructor_name_list = ptr;
61 }
62
63 void
64 ldlang_add_constructor (name)
65 ldsym_type *name;
66 {
67 if (name->flags & SYM_CONSTRUCTOR) return;
68 add_constructor_name (name->name);
69 name->flags |= SYM_CONSTRUCTOR;
70 }
71
72
73 /* this function looks through the sections attached to the supplied
74 bfd to see if any of them are magical constructor sections. If so
75 their names are remembered and added to the list of constructors */
76
77 void
78 ldlang_check_for_constructors (entry)
79 struct lang_input_statement_struct *entry;
80 {
81 asection *section;
82
83 for (section = entry->the_bfd->sections;
84 section != (asection *)NULL;
85 section = section->next)
86 {
87 if (section->flags & SEC_CONSTRUCTOR)
88 add_constructor_name (section->name);
89 }
90 }
91
92
93 /* run through the symbol table, find all the symbols which are
94 constructors and for each one, create statements to do something
95 like..
96
97 for something like "__CTOR_LIST__, foo" in the assembler
98
99 __CTOR_LIST__ = . ;
100 LONG(__CTOR_LIST_END - . / 4 - 2)
101 *(foo)
102 __CTOR_LIST_END= .
103
104 Put these statements onto a special list.
105
106 */
107
108
109 void
110 find_constructors ()
111 {
112 lang_statement_list_type *old = stat_ptr;
113 constructor_list_type *p = constructor_name_list;
114 stat_ptr = & constructor_list;
115 lang_list_init(stat_ptr);
116 while (p != (constructor_list_type *)NULL)
117 {
118 /* Have we already done this one ? */
119 CONST char *name = p->name;
120 ldsym_type *lookup = ldsym_get_soft(name);
121
122 /* If ld is invoked from collect, then the constructor list
123 will already have been defined, so don't do it again. */
124
125 if (lookup->sdefs_chain == (asymbol **)NULL)
126 {
127 size_t len = strlen(name);
128 char *end = ldmalloc(len+3);
129 strcpy(end, name);
130 strcat(end,"$e");
131
132 lang_add_assignment
133 ( exp_assop('=',name, exp_nameop(NAME,".")));
134
135 lang_add_data
136 (LONG, exp_binop('-',
137 exp_binop ( '/',
138 exp_binop ( '-',
139 exp_nameop(NAME, end),
140 exp_nameop(NAME,".")),
141 exp_intop(4)),
142
143 exp_intop(2)));
144
145
146 lang_add_wild(name, (char *)NULL);
147 lang_add_data(LONG, exp_intop(0));
148 lang_add_assignment
149 (exp_assop('=', end, exp_nameop(NAME,".")));
150 }
151 p = p->next;
152 }
153 stat_ptr = old;
154 }
155
This page took 0.032098 seconds and 4 git commands to generate.