* objcopy.c (main): Give a usage message if there are too many
[deliverable/binutils-gdb.git] / ld / relax.c
1 /* Copyright (C) 1992, 1993 Free Software Foundation, Inc.
2
3 This file is part of GLD, the Gnu Linker.
4
5 This program 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 2 of the License, or
8 (at your option) any later version.
9
10 This program 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 this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18
19 /*
20
21 new age linking
22
23
24 Tie together all the interseting blocks
25
26 */
27
28
29 #include "bfd.h"
30 #include "../bfd/seclet.h"
31 #include "coff/internal.h"
32 #include "sysdep.h"
33
34 #include "ldlang.h"
35 #include "ld.h"
36 #include "ldwrite.h"
37 #include "ldmisc.h"
38 #include "ldsym.h"
39 #include "ldgram.h"
40 #include "relax.h"
41 static void
42 build_it (statement)
43 lang_statement_union_type * statement;
44 {
45 switch (statement->header.type)
46 {
47 #if 0
48 {
49
50 bfd_byte play_area[SHORT_SIZE];
51 unsigned int i;
52 bfd_putshort (output_bfd, statement->fill_statement.fill, play_area);
53 /* Write out all entire shorts */
54 for (i = 0;
55 i < statement->fill_statement.size - SHORT_SIZE + 1;
56 i += SHORT_SIZE)
57 {
58 bfd_set_section_contents (output_bfd,
59 statement->fill_statement.output_section,
60 play_area,
61 statement->data_statement.output_offset + i,
62 SHORT_SIZE);
63
64 }
65
66 /* Now write any remaining byte */
67 if (i < statement->fill_statement.size)
68 {
69 bfd_set_section_contents (output_bfd,
70 statement->fill_statement.output_section,
71 play_area,
72 statement->data_statement.output_offset + i,
73 1);
74
75 }
76
77 abort ();
78 }
79 break;
80 #endif
81 case lang_data_statement_enum:
82
83 {
84
85 bfd_vma value = statement->data_statement.value;
86 bfd_byte play_area[LONG_SIZE];
87 unsigned int size = 0;
88 asection *output_section = statement->data_statement.output_section;
89 switch (statement->data_statement.type)
90 {
91 case LONG:
92 bfd_put_32 (output_section->owner, value, play_area);
93 size = LONG_SIZE;
94 break;
95 case SHORT:
96 bfd_put_16 (output_section->owner, value, play_area);
97 size = SHORT_SIZE;
98 break;
99 case BYTE:
100 bfd_put_8 (output_section->owner, value, play_area);
101 size = BYTE_SIZE;
102 break;
103 }
104
105 bfd_set_section_contents (output_section->owner,
106 statement->data_statement.output_section,
107 play_area,
108 statement->data_statement.output_vma,
109 size);
110
111
112
113 }
114
115 break;
116 case lang_input_section_enum:
117 {
118 /* Create a new seclet in the output section with this
119 attached */
120 if (statement->input_section.ifile->just_syms_flag == false)
121 {
122 asection *i = statement->input_section.section;
123
124 asection *output_section = i->output_section;
125
126 bfd_seclet_type *seclet = bfd_new_seclet (output_section->owner, output_section);
127
128 if (i->flags & SEC_NEVER_LOAD)
129 {
130 /* We've got a never load section inside one which is going
131 to be output, we'll change it into a fill seclet */
132 seclet->type = bfd_fill_seclet;
133 seclet->u.fill.value = 0;
134 }
135 else
136 {
137 seclet->type = bfd_indirect_seclet;
138 seclet->u.indirect.section = i;
139 seclet->u.indirect.symbols
140 = statement->input_section.ifile->asymbols;
141 }
142 seclet->size = i->_cooked_size;
143 seclet->offset = i->output_offset;
144 seclet->next = 0;
145 }
146
147 }
148 break;
149 case lang_padding_statement_enum:
150 /* Make a new seclet with the right filler */
151 {
152 /* Create a new seclet in the output section with this
153 attached */
154
155 bfd_seclet_type *seclet =
156 bfd_new_seclet (statement->padding_statement.output_section->owner,
157 statement->padding_statement.output_section);
158
159 seclet->type = bfd_fill_seclet;
160 seclet->size = statement->padding_statement.size;
161 seclet->offset = statement->padding_statement.output_offset;
162 seclet->u.fill.value = statement->padding_statement.fill;
163 seclet->next = 0;
164 }
165 break;
166
167
168
169 break;
170 default:
171 /* All the other ones fall through */
172 ;
173
174 }
175
176
177
178 }
179
180
181 void
182 write_relax (output_bfd, data, relocateable)
183 bfd * output_bfd;
184 PTR data;
185 boolean relocateable;
186 {
187 /* Tie up all the statements to generate an output bfd structure which
188 bfd can mull over */
189 lang_for_each_statement (build_it);
190
191 if (bfd_seclet_link (output_bfd, data, relocateable) == false)
192 einfo ("%F%P: %B: %E\n", output_bfd);
193 }
194
195 /* See if we can change the size of this section by shrinking the
196 relocations in it. If this happens, then we'll have to renumber the
197 symbols in it, and shift around the data too.
198 */
199 boolean
200 relax_section (this_ptr)
201 lang_statement_union_type ** this_ptr;
202 {
203 extern lang_input_statement_type *script_file;
204 lang_input_section_type *is = &((*this_ptr)->input_section);
205 asection *i = is->section;
206 if (!(i->owner->flags & BFD_IS_RELAXABLE))
207 {
208 if (i->owner != script_file->the_bfd)
209 einfo ("%B: not assembled with -linkrelax\n", i->owner);
210 }
211
212 return bfd_relax_section (i->owner, i, is->ifile->asymbols);
213
214 }
This page took 0.033443 seconds and 4 git commands to generate.