Tue Oct 20 10:56:06 1992 Ian Lance Taylor (ian@cygnus.com)
[external/binutils.git] / ld / relax.c
1
2
3 /* 
4  
5 new age linking
6
7
8 Tie together all the interseting blocks 
9
10 */
11
12
13 #include "bfd.h"
14 #include "../bfd/seclet.h"
15 #include "coff/internal.h"
16 #include "sysdep.h"
17
18 #include "ldlang.h"
19 #include "ld.h"
20 #include "ldwrite.h"
21 #include "ldmisc.h"
22 #include "ldsym.h"
23 #include "ldgram.h"
24 #include "relax.h"
25 static void
26 DEFUN(build_it,(statement),
27       lang_statement_union_type *statement)
28 {
29   switch (statement->header.type) {
30 #if 0
31     {
32
33       bfd_byte play_area[SHORT_SIZE];
34       unsigned int i;
35       bfd_putshort(output_bfd, statement->fill_statement.fill, play_area);
36       /* Write out all entire shorts */
37       for (i = 0;
38            i < statement->fill_statement.size - SHORT_SIZE + 1;
39            i+= SHORT_SIZE)
40         {
41           bfd_set_section_contents(output_bfd,
42                                    statement->fill_statement.output_section,
43                                    play_area,
44                                    statement->data_statement.output_offset +i,
45                                    SHORT_SIZE);
46
47         }
48
49       /* Now write any remaining byte */
50       if (i < statement->fill_statement.size) 
51         {
52           bfd_set_section_contents(output_bfd,
53                                    statement->fill_statement.output_section,
54                                    play_area,
55                                    statement->data_statement.output_offset +i,
56                                    1);
57
58         }
59
60       abort();
61     }
62     break;
63 #endif
64   case lang_data_statement_enum:
65 #if 0
66     {
67
68       bfd_vma value = statement->data_statement.value;
69       bfd_byte play_area[LONG_SIZE];
70       unsigned int size = 0;
71       switch (statement->data_statement.type) {
72       case LONG:
73         bfd_put_32(output_bfd, value,  play_area);
74         size = LONG_SIZE;
75         break;
76       case SHORT:
77         bfd_put_16(output_bfd, value,  play_area);
78         size = SHORT_SIZE;
79         break;
80       case BYTE:
81         bfd_put_8(output_bfd, value,  play_area);
82         size = BYTE_SIZE;
83         break;
84       }
85       
86       bfd_set_section_contents(output_bfd,
87                                statement->data_statement.output_section,
88                                play_area,
89                                statement->data_statement.output_vma,
90                                size);
91                                
92                                
93
94     }
95 #endif
96     break;
97   case lang_input_section_enum:
98     {
99       /* Create a new seclet in the output section with this
100          attached */
101       if (statement->input_section.ifile->just_syms_flag == false) 
102       {
103         asection *i  = statement->input_section.section;
104
105         asection *output_section = i->output_section;
106         
107         bfd_seclet_type *seclet  = bfd_new_seclet(output_section->owner,output_section);
108         
109         seclet->type = bfd_indirect_seclet;
110         seclet->u.indirect.section = i;
111         seclet->u.indirect.symbols = statement->input_section.ifile->asymbols;
112         seclet->size = i->_cooked_size;
113         seclet->offset = i->output_offset;
114         seclet->next = 0;
115       }
116         
117     }
118     break;
119   case lang_padding_statement_enum:
120     /* Make a new seclet with the right filler */
121     {
122       /* Create a new seclet in the output section with this
123          attached */
124
125       bfd_seclet_type *seclet  =
126         bfd_new_seclet(statement->padding_statement.output_section->owner,
127                        statement->padding_statement.output_section);
128         
129       seclet->type = bfd_fill_seclet;
130       seclet->size = statement->padding_statement.size;
131       seclet->offset = statement->padding_statement.output_offset;
132       seclet->u.fill.value = statement->padding_statement.fill;
133       seclet->next = 0;
134     }
135     break;
136
137
138
139     break;
140   default:
141     /* All the other ones fall through */
142     ;
143
144   }
145
146
147
148 }
149
150
151 void 
152 DEFUN(write_relaxnorel,(output_bfd, data),
153       bfd *output_bfd AND
154       PTR data)
155 {
156 /* Tie up all the statements to generate an output bfd structure which
157    bfd can mull over */
158
159
160   lang_for_each_statement(build_it);
161
162   seclet_dump(output_bfd, data);
163
164 }
165
166
167     
168
169
170 /* See if we can change the size of this section by shrinking the
171    relocations in it. If this happens, then we'll have to renumber the
172    symbols in it, and shift around the data too.
173  */
174 boolean
175 DEFUN(relax_section,(this_ptr),
176       lang_statement_union_type **this_ptr)
177 {
178
179   lang_input_section_type *is = &((*this_ptr)->input_section);
180   asection *i = is->section;
181   if (!(i->owner->flags & BFD_IS_RELAXABLE)) 
182   {
183     einfo("%B: not assembled with -linkrelax\n", i->owner);    
184   }
185
186   return bfd_relax_section(i->owner, i, is->ifile->asymbols);
187   
188 }
189