(enum bfd_reloc_code_real): Put simple power-to-two relocs together, and add
[deliverable/binutils-gdb.git] / ld / relax.c
CommitLineData
ac496d4f 1/* Copyright (C) 1992, 1993 Free Software Foundation, Inc.
2e2bf962 2
ac496d4f
ILT
3This file is part of GLD, the Gnu Linker.
4
5This program 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 2 of the License, or
8(at your option) any later version.
9
10This program 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 this program; if not, write to the Free Software
17Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
2e2bf962 18
29f33467
SC
19/*
20
2e2bf962
SC
21new age linking
22
23
29f33467 24Tie together all the interseting blocks
2e2bf962
SC
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"
9aa97a39 40#include "relax.h"
2e2bf962 41static void
8ddef552
DM
42build_it (statement)
43 lang_statement_union_type * statement;
2e2bf962 44{
29f33467
SC
45 switch (statement->header.type)
46 {
2e2bf962 47#if 0
29f33467
SC
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;
cd1d8c6d 80#endif
29f33467
SC
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
85c838d6 119 attached */
29f33467
SC
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
85c838d6 153 attached */
2e2bf962 154
29f33467
SC
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;
0d3e45ea
SC
166
167
168
29f33467
SC
169 break;
170 default:
171 /* All the other ones fall through */
172 ;
2e2bf962 173
29f33467 174 }
2e2bf962
SC
175
176
177
178}
179
180
29f33467 181void
8ddef552
DM
182write_relax (output_bfd, data, relocateable)
183 bfd * output_bfd;
184 PTR data;
185 boolean relocateable;
2e2bf962 186{
29f33467 187 /* Tie up all the statements to generate an output bfd structure which
2e2bf962
SC
188 bfd can mull over */
189
190
29f33467 191 lang_for_each_statement (build_it);
2e2bf962 192
29f33467 193 bfd_seclet_link (output_bfd, data, relocateable);
2e2bf962
SC
194
195}
196
197
29f33467 198
2e2bf962
SC
199
200
201/* See if we can change the size of this section by shrinking the
202 relocations in it. If this happens, then we'll have to renumber the
203 symbols in it, and shift around the data too.
204 */
205boolean
8ddef552
DM
206relax_section (this_ptr)
207 lang_statement_union_type ** this_ptr;
2e2bf962 208{
25de6a20 209 extern lang_input_statement_type *script_file;
2e2bf962
SC
210 lang_input_section_type *is = &((*this_ptr)->input_section);
211 asection *i = is->section;
29f33467
SC
212 if (!(i->owner->flags & BFD_IS_RELAXABLE))
213 {
214 if (i->owner != script_file->the_bfd)
215 einfo ("%B: not assembled with -linkrelax\n", i->owner);
216 }
217
218 return bfd_relax_section (i->owner, i, is->ifile->asymbols);
2e2bf962 219
29f33467 220}
This page took 0.066524 seconds and 4 git commands to generate.