* bfd.c (bfd_get_error, bfd_set_error): New functions.
[external/binutils.git] / bfd / ctor.c
1 /* BFD library support routines for constructors
2    Copyright (C) 1990-1991 Free Software Foundation, Inc.
3
4    Hacked by Steve Chamberlain of Cygnus Support. With some help from
5    Judy Chamberlain too.
6
7
8 This file is part of BFD, the Binary File Descriptor library.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
23
24 /*
25 SECTION
26         Constructors
27
28         Classes in C++ have @dfn{constructors} and @dfn{destructors}.  These
29         are functions which are called automatically by the language
30         whenever data of a class is created or destroyed.  Class data
31         which is static may also be have a type which requires
32         `construction'; the contructor must be called before the data
33         can be referenced, so the contructor must be called before the
34         program begins. 
35
36         The common solution to this problem is for the compiler to
37         call a magic function as the first statement before <<main>>.
38         This magic function (often called <<__main>>) runs around
39         calling the constructors for all the things needing it.
40
41         With COFF, the compiler has a bargain with the linker et al.
42         All constructors are given strange names; for example,
43         <<__GLOBAL__$I$foo>> might be the label of a contructor for
44         the class @var{foo}.  The solution on unfortunate systems
45         (most System V machines) is to perform a partial link on all
46         the <<.o>> files, do an <<nm>> on the result, run <<awk>> or some
47         such over the result looking for strange <<__GLOBAL__$>>
48         symbols, generate a C program from this, compile it, and link
49         with the partially linked input. This process is usually
50         called <<collect>>. 
51
52         Some versions of <<a.out>> use something called the
53         <<set_vector>> mechanism.  The constructor symbols are output
54         from the compiler with a special stab code saying that they
55         are constructors, and the linker can deal with them directly. 
56
57         BFD allows applications (i.e., the linker) to deal with
58         constructor information independently of their external
59         implementation by providing a set of entry points for the
60         indiviual object back ends to call to maintain a database
61         of the contructor information.  The application can
62         interrogate the database to find out what it wants.  The
63         construction data essential for the linker to be able to
64         perform its job are: 
65
66         o asymbol -
67         The asymbol of the contructor entry point contains all the
68         information necessary to call the function. 
69
70         o table id -
71         The type of symbol, i.e., is it a constructor, a destructor or
72         something else someone dreamed up to make our lives difficult.
73
74         The constructor module takes this information and builds extra
75         sections attached to the BFDs which own the entry points.  It
76         creates these sections as if they were tables of pointers to
77         the entry points, and builds relocation entries to go with
78         them so that the tables can be relocated along with the data
79         they reference. 
80
81         These sections are marked with a special bit
82         (<<SEC_CONSTRUCTOR>>), which the linker notices and does with
83         what it wants.
84
85 */
86
87 #include <bfd.h>
88 #include <sysdep.h>
89 #include <libbfd.h>
90
91
92
93 /*
94 INTERNAL_FUNCTION
95         bfd_constructor_entry 
96
97 SYNOPSIS
98         boolean bfd_constructor_entry(bfd *abfd, 
99                 asymbol **symbol_ptr_ptr,
100                 CONST char*type);
101
102
103 DESCRIPTION
104         @var{symbol_ptr_ptr} describes the
105         function to be called; @var{type} descibes the xtor type,
106         e.g., something like "CTOR" or "DTOR" would be fine.  @var{abfd}
107         is the BFD which owns the function.  Create a section
108         called "CTOR" or "DTOR" or whatever if the BFD doesn't already
109         have one, and grow a relocation table for the entry points as
110         they accumulate.
111
112         Return <<true>> if successful, <<false>> if out of memory.
113
114 */
115
116  
117 boolean
118 DEFUN(bfd_constructor_entry,(abfd, symbol_ptr_ptr, type),
119            bfd *abfd AND
120            asymbol **symbol_ptr_ptr AND
121            CONST char *type)
122 {
123     /* Look up the section we're using to store the table in */
124     asection *rel_section = bfd_get_section_by_name (abfd, type);
125     if (rel_section == (asection *)NULL) {
126         rel_section = bfd_make_section (abfd, type);
127         rel_section->flags = SEC_CONSTRUCTOR;
128         rel_section->alignment_power = 2;
129     }
130
131     /* Create a relocation into the section which references the entry
132        point */
133    {
134        arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd,
135                                                          sizeof(arelent_chain));
136        if (!reloc)
137          {
138            bfd_set_error (bfd_error_no_memory);
139            return false;
140          }
141
142 /*       reloc->relent.section = (asection *)NULL;*/
143        reloc->relent.addend = 0;
144
145        reloc->relent.sym_ptr_ptr = symbol_ptr_ptr;
146        reloc->next = rel_section->constructor_chain;
147        rel_section->constructor_chain = reloc;
148        reloc->relent.address = rel_section->_cooked_size;
149        /* ask the cpu which howto to use */
150        reloc->relent.howto = bfd_reloc_type_lookup(abfd, BFD_RELOC_CTOR);
151        rel_section->_cooked_size += sizeof(int *);
152        rel_section->reloc_count++;
153    }
154     return true;
155 }