Made many changes to eliminate gcc warnings. Made various
[platform/upstream/binutils.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