Tue Jan 25 19:54:19 1994 Stan Shebs (shebs@andros.cygnus.com)
[deliverable/binutils-gdb.git] / ld / ldctor.c
CommitLineData
fcf276c4
ILT
1/* Copyright (C) 1991 Free Software Foundation, Inc.
2
3This file is part of GLD, the Gnu Linker.
4
5GLD is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation; either version 1, or (at your option)
8any later version.
9
10GLD is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with GLD; see the file COPYING. If not, write to
17the 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 */
34lang_statement_list_type constructor_list;
35
36
37
38typedef struct constructor_list
39{
40 CONST char *name;
41 struct constructor_list *next;
42} constructor_list_type;
43
44static constructor_list_type *constructor_name_list;
45
46static void
47add_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
63void
64ldlang_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
77void
78ldlang_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
109void
110find_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.032136 seconds and 4 git commands to generate.